That violates "don't pay for what you don't need" rule of C++. Users of std::atomic<T>::wait will often have some bit in their atomic indicate whether the value is contended or not, so we don't need libstdc++ to do double book-keeping for us. --- libstdc++-v3/include/bits/atomic_wait.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h index 1c6bda2e2b6..4d240f44faf 100644 --- a/libstdc++-v3/include/bits/atomic_wait.h +++ b/libstdc++-v3/include/bits/atomic_wait.h @@ -258,14 +258,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (std::__atomic_spin(__pred)) return; - __waiter __w(__addr); - while (!__pred()) + if constexpr (__platform_wait_uses_type<_Tp>) { - if constexpr (__platform_wait_uses_type<_Tp>) - { - __platform_wait(__addr, __old); - } - else + __platform_wait(__addr, __old); + } + else + { + __waiter __w(__addr); + while (!__pred()) { // TODO support timed backoff when this can be moved into the lib __w._M_do_wait(); @@ -274,13 +274,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _Tp> - void + inline void __atomic_notify(const _Tp* __addr, bool __all) noexcept { using namespace __detail; - auto& __w = __waiters::_S_for((void*)__addr); - if (!__w._M_waiting()) - return; #ifdef _GLIBCXX_HAVE_LINUX_FUTEX if constexpr (__platform_wait_uses_type<_Tp>) @@ -290,6 +287,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION else #endif { + auto& __w = __waiters::_S_for((void*)__addr); + if (!__w._M_waiting()) + return; __w._M_notify(__all); } } -- 2.30.1