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
and
atomic_wait .
atomic_wait_explicit
and
atomic_flag_wait .
atomic_flag_wait_explicit .
atomic_ref < T >:: wait - end note ]
[ Note: The following functions are atomic notifying operations:
and
atomic < T >:: notify_one .
atomic < T >:: notify_all
and
atomic_flag :: notify_one .
atomic_flag :: notify_all
and
atomic_notify_one .
atomic_notify_all
and
atomic_flag_notify_one .
atomic_flag_notify_all and
atomic_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 on
M if there exist side effects
M and
X on
Y such that:
M
the atomic waiting operation has blocked after observing the result of
,
X
precedes
X in the modification order of
Y , and
M
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 neither
order nor
memory_order :: release .
memory_order :: acq_rel Effects: Repeatedly performs the following steps, in order:
Evaluates
and compares its value representation for equality against that of
load ( 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 ; // ...