[gcc r16-1248] libstdc++: Add assertions to atomic waiting functions that need platform wait
Jonathan Wakely
redi@gcc.gnu.org
Fri Jun 6 08:52:44 GMT 2025
https://gcc.gnu.org/g:ba1ad0ec6fe6b8ee3e6682f266f7a336a15f7965
commit r16-1248-gba1ad0ec6fe6b8ee3e6682f266f7a336a15f7965
Author: Jonathan Wakely <jwakely@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);
More information about the Libstdc++-cvs
mailing list