Skip to content

threads_done_semaphore_ probably shouldn't be std::binary_semaphore #10

@wolfpld

Description

@wolfpld

After updating libstdc++ from 15.2.1 to 16.1.1 I started getting the following assertion:

/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../include/c++/16.1.1/semaphore:74: void std::counting_semaphore<1>::release(ptrdiff_t) [__least_max_value = 1]: Assertion '__update >= 0 && __update <= max() - __old' failed.

No sensible call stack or anything.

Running AI against the issue resulted in:

In thread_pool.h:126, multiple workers can race to call release() on a binary_semaphore after total_tasks_ hits 0:

while (get_next_task(id));
if (total_tasks_.load(std::memory_order_acquire) == 0)
   threads_done_semaphore_.release();   // multiple workers can hit this

std::binary_semaphore is counting_semaphore<1> with max=1. If two workers race here, the second release() would push the count to 2, triggering libstdc++ 16's new assertion __update <= max() - __old. Older libstdc++ either lacked or had a looser assertion.

Switching binary_semaphore to counting_semaphore makes the issue no longer reproducible for me.

https://github.com/wolfpld/tracy/blob/5bbafeabd7c38bcf7c264769a48e973173fd0430/cmake/ppqsort-semaphore.patch

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions