https://gcc.gnu.org/g:59bc37debfbf315a7cd0c8bbbfcecdf87b6ea91a
commit r16-6711-g59bc37debfbf315a7cd0c8bbbfcecdf87b6ea91a Author: Jonathan Wakely <[email protected]> Date: Sat Jan 10 13:44:49 2026 +0000 libstdc++: Improve comments on __wait_args::_M_setup_proxy_wait 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. Reviewed-by: Tomasz KamiĆski <[email protected]> Diff: --- 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) {
