Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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