https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101761

--- Comment #5 from Thomas Rodgers <rodgertq at gcc dot gnu.org> ---
(In reply to Florian Weimer from comment #4)
> I think it's a test bug:
> 
>       std::atomic_ref<S> a{ aa };
> 
>       std::thread t([&]
>         {
>         a.store(bb);
>         a.notify_one();
>         });
>       a.wait(aa);
> 
> Due to the use of std::atomic_ref, store() overwrites aa with the value of
> bb. If the notify_one() call completes before the wait() call, wait() blocks
> because aa == bb (due to the previous store()), and the wakeup never happens
> because wakes are not queued.

This was my initial suspicion. It applies to all of the
29_atomics/**/wait_notify.cc tests. The libc++ tests for wait/notify have the
same problem (see
https://github.com/llvm/llvm-project/blob/main/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp)

I have, as part of this investigation, extensively re-reviewed the
implementation detail in bits/atomic_wait.h and I think there is a race
condition lurking in the implementation which also needs to be address.
Specifically tracking waiters to try to void making the syscall for
FUTEX_WAKE_PRIVATE if there are no current waiters. In order for this to work
the increment of the waiter count would have to be atomic with syscall. I
believe that libc++ also has this same issue.

Reply via email to