libstdc++-v3/ChangeLog:
* include/bits/atomic_wait.h (__wait_args): Improve comments.
* src/c++20/atomic.cc (__wait_args::_M_setup_proxy_wait):
Improve comment.
---
v2: Improve comment in atomic.cc instead of duplicating it in the
header. Also add comments to __wait_args data members.
libstdc++-v3/include/bits/atomic_wait.h | 11 +++++------
libstdc++-v3/src/c++20/atomic.cc | 24 ++++++++++++++++--------
2 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/libstdc++-v3/include/bits/atomic_wait.h
b/libstdc++-v3/include/bits/atomic_wait.h
index 8511e003abca..fb4457566395 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -162,9 +162,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __wait_args_base
{
__wait_flags _M_flags;
- int _M_order = __ATOMIC_ACQUIRE;
- __wait_value_type _M_old = 0;
- void* _M_wait_state = nullptr;
+ int _M_order = __ATOMIC_ACQUIRE; // Memory order for loads from _M_obj.
+ __wait_value_type _M_old = 0; // Previous value of *_M_obj.
+ void* _M_wait_state = nullptr; // For proxy wait and tracking contention.
const void* _M_obj = nullptr; // The address of the object to wait on.
unsigned char _M_obj_size = 0; // The size of that object.
@@ -286,9 +286,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __val;
}
- // Returns true if a proxy wait will be used for __addr, false otherwise.
- // If true, _M_wait_state, _M_obj, _M_obj_size, and _M_old are set.
- // If false, data members are unchanged.
+ // Prepare `*this` for a call to `__wait_impl` or `__wait_until_impl`.
+ // See comments in src/c++20/atomic.cc for more details.
bool
_M_setup_proxy_wait(const void* __addr);
diff --git a/libstdc++-v3/src/c++20/atomic.cc b/libstdc++-v3/src/c++20/atomic.cc
index 80558a1ad9e0..2b66793ede7e 100644
--- a/libstdc++-v3/src/c++20/atomic.cc
+++ b/libstdc++-v3/src/c++20/atomic.cc
@@ -308,14 +308,22 @@ namespace
} // namespace
-// Return false (and don't change any data members) if we can do a non-proxy
-// wait for the object of size `_M_obj_size` at address `addr`.
-// Otherwise, we will use a proxy wait. If addr == _M_obj this is the initial
-// setup of the proxy wait, so set _M_wait_state to the proxy state for addr,
-// and set _M_obj and _M_obj_size to refer to the _M_wait_state->_M_ver proxy.
-// For both the initial setup of a proxy wait and for subsequent calls to this
-// function for proxy waits, we load the current value from _M_obj (the proxy)
-// and store it in _M_old, then return true.
+// Returns true if a proxy wait will be used for addr, false otherwise.
+//
+// For the first call (from `_M_setup_wait`) `_M_obj` will equal `addr`,
+// and this function will decide whether to use a proxy wait.
+//
+// If it returns false, there are no effects (all data members are unchanged),
+// and this function should not be called again on `*this` (because calling it
+// again will just return false again, so is a waste of cycles).
+//
+// The first call that returns true does the initial setup of the proxy wait,
+// setting `_M_wait_state` to the waitable state for `addr` and setting
+// `_M_obj` and `_M_obj_size` to refer to the `_M_wait_state->_M_ver` proxy.
+// For subsequent calls (from `_M_on_wake`) the argument can be null,
+// because any value not equal to `_M_obj` has the same effect.
+// All calls that return true will load a value from `_M_obj` (i.e. the proxy)
+// and store it in `_M_old`.
bool
__wait_args::_M_setup_proxy_wait(const void* addr)
{
--
2.52.0