https://gcc.gnu.org/g:ba1ad0ec6fe6b8ee3e6682f266f7a336a15f7965
commit r16-1248-gba1ad0ec6fe6b8ee3e6682f266f7a336a15f7965 Author: Jonathan Wakely <jwak...@redhat.com> Date: Wed Jun 4 16:58:45 2025 +0100 libstdc++: Add assertions to atomic waiting functions that need platform wait These overloads should never be used for proxy waits, so add assertions to ensure that they aren't used accidentally. The reason they can't be used is that they don't call __args._M_setup_wait to obtain a __wait_state pointer. Even if that was changed, they would wait on a proxy wait which is potentially used by many other threads waiting on other addresses, meaning spurious wake ups are likely. In order to make the functions correct they would need to perform additional loads and comparisons of the atomic variable before calling __wait_impl or __wait_until_impl, which would make these functions no faster than the general purpose overloads that take an accessor function and predicate. That would be possible, and I think they would then work for proxy waits, but doesn't seem necessary at this time. In order to preseve the property that these functions are more lightweight and efficient than the general ones, they should not be used for proxy waits. libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h (__atomic_wait_address_until_v): Add assertion to prevent use with proxy waits. (__atomic_wait_address_for_v): Likewise. * include/bits/atomic_wait.h (__atomic_wait_address_v): Likewise. Diff: --- libstdc++-v3/include/bits/atomic_timed_wait.h | 6 ++++++ libstdc++-v3/include/bits/atomic_wait.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h b/libstdc++-v3/include/bits/atomic_timed_wait.h index bd2e6bf61ecf..30f7ff616840 100644 --- a/libstdc++-v3/include/bits/atomic_timed_wait.h +++ b/libstdc++-v3/include/bits/atomic_timed_wait.h @@ -156,6 +156,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const chrono::time_point<_Clock, _Dur>& __atime, bool __bare_wait = false) noexcept { +#ifndef _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT + __glibcxx_assert(false); // This function can't be used for proxy wait. +#endif __detail::__wait_args __args{ __addr, __old, __order, __bare_wait }; auto __res = __detail::__wait_until(__addr, __args, __atime); return !__res._M_timeout; // C++26 will also return last observed __val @@ -205,6 +208,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const chrono::duration<_Rep, _Period>& __rtime, bool __bare_wait = false) noexcept { +#ifndef _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT + __glibcxx_assert(false); // This function can't be used for proxy wait. +#endif __detail::__wait_args __args{ __addr, __old, __order, __bare_wait }; auto __res = __detail::__wait_for(__addr, __args, __rtime); return !__res._M_timeout; // C++26 will also return last observed __val diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h index 9ae11191d9ab..95151479c120 100644 --- a/libstdc++-v3/include/bits/atomic_wait.h +++ b/libstdc++-v3/include/bits/atomic_wait.h @@ -255,6 +255,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __detail::__platform_wait_t __old, int __order, bool __bare_wait = false) { +#ifndef _GLIBCXX_HAVE_PLATFORM_WAIT + __glibcxx_assert(false); // This function can't be used for proxy wait. +#endif __detail::__wait_args __args{ __addr, __old, __order, __bare_wait }; // C++26 will not ignore the return value here __detail::__wait_impl(__addr, __args);