This represents a major refactoring of the previous atomic::wait
and atomic::notify implementation detail. The aim of this change
is to simplify the implementation details and position the resulting
implementation so that much of the current header-only detail
can be moved into the shared library, while also accounting for
anticipated changes to wait/notify functionality for C++26.
The previous implementation implemented spin logic in terms of
the types __default_spin_policy, __timed_backoff_spin_policy, and
the free function __atomic_spin. These are replaced in favor of
two new free functions; __spin_impl and __spin_until_impl. These
currently inline free functions are expected to be moved into the
libstdc++ shared library in a future commit.
The previous implementation derived untimed and timed wait
implementation detail from __detail::__waiter_pool_base. This
is-a relationship is removed in the new version and the previous
implementation detail is renamed to reflect this change. The
static _S_for member has been renamed as well to indicate that it
returns the __waiter_pool_impl entry in the static 'side table'
for a given awaited address.
This new implementation replaces all of the non-templated waiting
detail of __waiter_base, __waiter_pool, __waiter, __enters_wait, and
__bare_wait with the __wait_impl free function, and the supporting
__wait_flags enum and __wait_args struct. This currenly inline free
function is expected to be moved into the libstdc++ shared library
in a future commit.
This new implementation replaces all of the non-templated notifying
detail of __waiter_base, __waiter_pool, and __waiter with the
__notify_impl free function. This currently inline free function
is expected to be moved into the libstdc++ shared library in a
future commit.
The __atomic_wait_address template function is updated to account
for the above changes and to support the expected C++26 change to
pass the most recent observed value to the caller supplied predicate.
A new non-templated __atomic_wait_address_v free function is added
that only works for atomic types that operate only on __platform_wait_t
and requires the caller to supply a memory order. This is intended
to be the simplest code path for such types.
The __atomic_wait_address_v template function is now implemented in
terms of new __atomic_wait_address template and continues to accept
a user supplied "value function" to retrieve the current value of
the atomic.
The __atomic_notify_address template function is updated to account
for the above changes.
The template __platform_wait_until_impl is renamed to
__wait_clock_t. The previous __platform_wait_until template is deleted
and the functionality previously provided is moved t the new tempalate
function __wait_until. A similar change is made to the
__cond_wait_until_impl/__cond_wait_until implementation.
This new implementation similarly replaces all of the non-templated
waiting detail of __timed_waiter_pool, __timed_waiter, etc. with
the new __wait_until_impl free function. This currently inline free
function is expected to be moved into the libstdc++ shared library
in a future commit.
This implementation replaces all templated waiting functions that
manage clock conversion as well as relative waiting (wait_for) with
the new template functions __wait_until and __wait_for.
Similarly the previous implementation detail for the various
__atomic_wait_address_Xxx templates is adjusted to account for the
implementation changes outlined above.
All of the "bare wait" versions of __atomic_wait_Xxx have been removed
and replaced with a defaulted boolean __bare_wait parameter on the
new version of these templates.
libstdc++-v3/ChangeLog:
* include/bits/atomic_timed_wait.h:
(__detail::__platform_wait_until_impl): Rename to
__platform_wait_until.
(__detail::__platform_wait_until): Remove previous
definition.
(__detail::__cond_wait_until_impl): Rename to
__cond_wait_until.
(__detail::__cond_wait_until): Remove previous
definition.
(__detail::__spin_until_impl): New function.
(__detail::__wait_until_impl): New function.
(__detail::__wait_until): New function.
(__detail::__wait_for): New function.
(__detail::__timed_waiter_pool): Remove type.
(__detail::__timed_backoff_spin_policy): Remove type.
(__detail::__timed_waiter): Remove type.
(__detail::__enters_timed_wait): Remove type alias.
(__detail::__bare_timed_wait): Remove type alias.
(__atomic_wait_address_until): Adjust to new implementation
detail.
(__atomic_wait_address_until_v): Likewise.
(__atomic_wait_address_bare): Remove.
(__atomic_wait_address_for): Adjust to new implementation
detail.
(__atomic_wait_address_for_v): Likewise.
(__atomic_wait_address_for_bare): Remove.
* include/bits/atomic_wait.h: Include bits/stl_pair.h.
(__detail::__default_spin_policy): Remove type.
(__detail::__atomic_spin): Remove function.
(__detail::__waiter_pool_base): Rename to __waiter_pool_impl.
Remove _M_notify. Rename _S_for to _S_impl_for.
(__detail::__waiter_base): Remove type.
(__detail::__waiter_pool): Remove type.
(__detail::__waiter): Remove type.
(__detail::__enters_wait): Remove type alias.
(__detail::__bare_wait): Remove type alias.
(__detail::__wait_flags): New enum.
(__detail::__wait_args): New struct.
(__detail::__wait_result_type): New type alias.
(__detail::__spin_impl): New function.
(__detail::__wait_impl): New function.
(__atomic_wait_address): Adjust to new implementation detail.
(__atomic_wait_address_v): Likewise.
(__atomic_notify_address): Likewise.
(__atomic_wait_address_bare): Delete.
(__atomic_notify_address_bare): Likewise.
* include/bits/semaphore_base.h: Adjust implementation to
use new __atomic_wait_address_v contract.
* include/std/barrier: Adjust implementation to use new
__atomic_wait contract.
* include/std/latch: Adjust implementation to use new
__atomic_wait contract.
* testsuite/29_atomics/atomic/wait_notify/100334.cc (main):
Adjust to for __detail::__waiter_pool_base renaming.