[05/10] libstdc++: Fix race condition in new atomic notify code
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
fail
|
Test failed
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
fail
|
Test failed
|
Commit Message
When using a proxy object for atomic waiting and notifying operations,
we need to ensure that the _M_ver value is always incremented by a
notifying operation, even if we return early without doing the futex
wake syscall. Otherwise we get missed wake-ups because the notifying
thread doesn't modify the value that other threads are doing a futex
wait on.
libstdc++-v3/ChangeLog:
* include/bits/atomic_wait.h (__notify_impl): Increment the
proxy value before returning early for the uncontended case.
---
libstdc++-v3/include/bits/atomic_wait.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
@@ -392,13 +392,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__wait_args __args{ *__a };
__waiter_pool_impl* __pool = nullptr;
- if (__args & __wait_flags::__track_contention)
- {
- __pool = &__waiter_pool_impl::_S_impl_for(__addr);
- if (!__pool->_M_waiting())
- return;
- }
-
const __platform_wait_t* __wait_addr;
if (__args & __wait_flags::__proxy_wait)
{
@@ -416,6 +409,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else // Use the atomic variable's own address.
__wait_addr = __addr;
+ if (__args & __wait_flags::__track_contention)
+ {
+ __pool = &__waiter_pool_impl::_S_impl_for(__addr);
+ if (!__pool->_M_waiting())
+ return;
+ }
+
#ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
__platform_notify(__wait_addr, __all);
#else