1. Introduction
[P1135] added the member functions , , and to , but did not add those same member
functions to due in part to scheduling concerns. This
paper takes care of that, bringing the interface of back in line with that of .
2. Changelog
Revision 0: Initial version.
3. Wording
Note: The following changes are relative to the post Kona 2019 working draft of ISO/IEC 14882, ([N4810]), with the changes from [P1135R5] merged in.
Modify the section about atomic waiting and notifying operations, [atomics.wait], which comes from P1135 not from N4810, as follows:
31.� Waiting and notifying [atomics.wait]Atomic waiting operations and atomic notifying operations provide a mechanism to wait for the value of an atomic object to change more efficiently than can be achieved with polling. Atomic waiting operations may block until they are unblocked by atomic notifying operations, according to each function’s effects. [ Note: Programs are not guaranteed to observe transient atomic values, an issue known as the A-B-A problem, resulting in continued blocking if a condition is only temporarily met. – end note ][ Note: The following functions are atomic waiting operations:
.atomic < T >:: wait
.atomic_flag :: wait
andatomic_wait .atomic_wait_explicit
andatomic_flag_wait .atomic_flag_wait_explicit .atomic_ref < T >:: wait - end note ]
[ Note: The following functions are atomic notifying operations:
andatomic < T >:: notify_one .atomic < T >:: notify_all
andatomic_flag :: notify_one .atomic_flag :: notify_all
andatomic_notify_one .atomic_notify_all
andatomic_flag_notify_one .atomic_flag_notify_all andatomic_ref < T >:: notify_one .atomic_ref < T >:: notify_all - end note ]
A call to an atomic waiting operation on an atomic objectis eligible to be unblocked by a call to an atomic notifying operation onM if there exist side effectsM andX onY such that:M
the atomic waiting operation has blocked after observing the result of
,X
precedesX in the modification order ofY , andM
happens before the call to the atomic notifying operation.Y
Modify the class synopsis for in [atomics.ref.generic] as follows:
31.6 Class template[atomics.ref.generic]atomic_ref namespace std { template < class T > struct atomic_ref { // ... bool compare_exchange_strong ( T & , T , memory_order = memory_order_seq_cst ) const noexcept ; void wait ( T , memory_order = memory_order :: seq_cst ) const noexcept ; void notify_one () noexcept ; void notify_all () noexcept ; }; }
Add the following to the end of [atomics.ref.operations]:
void wait ( T old , memory_order order = memory_order :: seq_cst ) const noexcept ; Expects:is neitherorder normemory_order :: release .memory_order :: acq_rel Effects: Repeatedly performs the following steps, in order:
Evaluates
and compares its value representation for equality against that ofload ( order ) .old If they compare unequal, returns.
Blocks until it is unblocked by an atomic notifying operation or is unblocked spuriously.
Remarks: This function is an atomic waiting operation ([atomics.wait]) on atomic object.* ptr void notify_one () noexcept ; Effects: Unblocks the execution of at least one atomic waiting operation onthat is eligible to be unblocked ([atomics.wait]) by this call, if any such atomic waiting operations exist.* ptr Remarks: This function is an atomic notifying operation ([atomics.wait]).void notify_all () noexcept ; Effects: Unblocks the execution of all atomic waiting operations onthat are eligible to be unblocked ([atomics.wait]) by this call.* ptr Remarks: This function is an atomic notifying operation ([atomics.wait]).
Modify the class synopsis for the specialization for integral types in [atomics.ref.int] as follows:
namespace std { template <> struct atomic_ref < integral > { // ... bool compare_exchange_strong ( integral & , integral , memory_order = memory_order_seq_cst ) const noexcept ; void wait ( integral , memory_orger = memory_order :: seq_cst ) const noexcept ; void notify_one () noexcept ; void notify_all () noexcept ; integral fetch_add ( integral , memory_order = memory_order_seq_cst ) const noexcept ; // ...
Modify the class synopsis for the specialization for floating-point types in [atomics.ref.float] as follows:
namespace std { template <> struct atomic_ref < floating - point > { // ... bool compare_exchange_strong ( floating - point & , floating - point , memory_order = memory_order_seq_cst ) const noexcept ; void wait ( floating - point , memory_orger = memory_order :: seq_cst ) const noexcept ; void notify_one () noexcept ; void notify_all () noexcept ; floating - point fetch_add ( floating - point , memory_order = memory_order_seq_cst ) const noexcept ; // ...
Modify the class synopsis for the partial specialization for pointer types in [atomics.ref.pointer] as follows:
namespace std { template < class T > struct atomic_ref < T *> { // ... bool compare_exchange_strong ( T *& , T * , memory_order = memory_order_seq_cst ) const noexcept ; void wait ( T * , memory_orger = memory_order :: seq_cst ) const noexcept ; void notify_one () noexcept ; void notify_all () noexcept ; T * fetch_add ( difference_type , memory_order = memory_order_seq_cst ) const noexcept ; // ...