On Mon, Jan 12, 2026 at 11:28 AM Jonathan Wakely <[email protected]> wrote:
> 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.
>
LGTM.
>
> 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
>
>