https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106183
Anthony Williams <anthony.ajw at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |anthony.ajw at gmail dot com --- Comment #3 from Anthony Williams <anthony.ajw at gmail dot com> --- This is one of the common mistakes I mention when teaching people about condition variables. Just because the data being waited for is atomic, doesn't guarantee that the condition variable state is updated: you need the mutex to synchronize that. In current libstdc++ trunk libstdc++-v3/include/bits/atomic_wait.h insert a line in _M_notify at line 235: https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/include/bits/atomic_wait.h;h=125b1cad88682384737c048ac236af9c4deab957;hb=refs/heads/trunk void _M_notify(const __platform_wait_t* __addr, bool __all, bool __bare) noexcept { if (!(__bare || _M_waiting())) return; #ifdef _GLIBCXX_HAVE_PLATFORM_WAIT __platform_notify(__addr, __all); #else /// INSERT HERE { std::lock_guard<mutex> __lock(_M_mtx); } /// END INSERT if (__all) _M_cv.notify_all(); else _M_cv.notify_one(); #endif } The lock/unlock here ensures that the notify is correctly synchronized with the wait.