<atomic>
[added with C++11]
atomic
· atomic<integral>
· atomic<Ty *>
· atomic_flag
· atomic_integral
· memory_order
atomic_int8_t
· atomic_uint8_t
· atomic_int16_t
· atomic_uint16_t
· atomic_int32_t
· atomic_uint32_t
· atomic_int64_t
· atomic_uint64_t
· atomic_int_least8_t
· atomic_uint_least8_t
· atomic_int_least16_t
· atomic_uint_least16_t
· atomic_int_least32_t
· atomic_uint_least32_t
· atomic_int_least64_t
· atomic_uint_least64_t
· atomic_int_fast8_t
· atomic_uint_fast8_t
· atomic_int_fast16_t
· atomic_uint_fast16_t
· atomic_int_fast32_t
· atomic_uint_fast32_t
· atomic_int_fast64_t
· atomic_uint_fast64_t
· atomic_intptr_t
· atomic_uintptr_t
· atomic_size_t
· atomic_ptrdiff_t
· atomic_intmax_t
· atomic_uintmax_t
atomic_compare_exchange_strong
· atomic_compare_exchange_strong_explicit
· atomic_compare_exchange_weak
· atomic_compare_exchange_weak_explicit
· atomic_exchange
· atomic_exchange_explicit
· atomic_fetch_add
· atomic_fetch_add_explicit
· atomic_fetch_and
· atomic_fetch_and_explicit
· atomic_fetch_or
· atomic_fetch_or_explicit
· atomic_fetch_sub
· atomic_fetch_sub_explicit
· atomic_fetch_xor
· atomic_fetch_xor_explicit
· atomic_flag_clear
· atomic_flag_clear_explicit
· atomic_flag_test_and_set
· atomic_flag_test_and_set_explicit
· atomic_init
· atomic_is_lock_free
· atomic_load
· atomic_load_explicit
· atomic_signal_fence
· atomic_store
· atomic_store_explicit
· atomic_thread_fence
· kill_dependency
ATOMIC_BOOL_LOCK_FREE
· ATOMIC_CHAR_LOCK_FREE
· ATOMIC_CHAR16_T_LOCK_FREE
· ATOMIC_CHAR32_T_LOCK_FREE
· ATOMIC_FLAG_INIT
· ATOMIC_INT_LOCK_FREE
· ATOMIC_LLONG_LOCK_FREE
· ATOMIC_LONG_LOCK_FREE
· ATOMIC_POINTER_LOCK_FREE
· ATOMIC_SHORT_LOCK_FREE
· ATOMIC_VAR_INIT
· ATOMIC_WCHAR_T_LOCK_FREE
Include the standard header <atomic>
to define several classes and template classes for defining types that
support atomic operations.
An atomic operation has two key
properties:
memory_order
argument
(and, as a corollary, it inhibits compiler optimizations that would
violate the ordering requirements).These two properties, in conjunction with the inter-thread happens before relationship in the language definition, allow expert programmers to write algorithms that correctly manipulate an object from multiple threads without mutex locks.
This documentation uses, but does not define, the terms consume operation, acquire operation, release operation, acquire fence, release fence, sequentially consistent, and read-modify-write operation. These terms are formally defined in the C++ standard in [intro.multithread] and [atomics.fences] which also formalize their interaction with the C++ memory model.
On some platforms it might not be possible to efficiently implement atomic operations for some types without mutex locks. An atomic type is lock free if no atomic operations on that type use locks.
The class atomic_flag
provides a minimal
atomic type that holds a boolean flag. Its operations are always
lock free.
The template class atomic<Ty>
stores an
object of its argument type Ty
and provides atomic access to that stored value. It
can be instantiated with any type that can be copied with memcpy
and tested for
equality with memcmp
. In particular, it can be used with user-defined types that
meet these requirements and, in many cases, floating-point types. The template also has a set
of specializations for integral types and a partial specialization for pointers. These
specializations provide additional operations that are not available through the general
template:
bool
. It provides a rich set of member
functions for atomic arithmetic and logical operations.Each atomic<integral>
type has a corresponding macro
that can be used in an
if directive
to determine at compile time whether operations on that type are
lock free. If the
value
of the macro is zero, operations
on the type are not lock free. If the value is 1, operations may be
lock free, and a runtime check is needed. If the value is 2, operations
are lock free. The function
atomic_is_lock_free
can be used to determine at runtime whether operations on the type are
lock free.
For each of the integral types except bool
there is a corresponding named
atomic type that manages an object of that integral type. The
managed type
for each
atomic_integral
type is:
atomic_char
-- char
atomic_schar
-- signed char
atomic_uchar
-- unsigned char
atomic_char16_t
-- char16_t
atomic_char32_t
-- char32_t
atomic_wchar_t
-- wchar_t
atomic_short
-- short
atomic_ushort
-- unsigned short
atomic_int
-- int
atomic_uint
-- unsigned int
atomic_long
-- long
atomic_ulong
-- unsigned long
atomic_llong
-- long long
atomic_ullong
-- unsigned long long
Each atomic_integral
type has the same set of member functions as the corresponding
instantiation of atomic<Ty>
and can be passed to any of the
non-member atomic functions.
There are typedef
names for specializations of the atomic
template for some of the types defined in the header <inttypes.h>
:
atomic_int8_t
-- atomic<int8_t>
atomic_uint8_t
-- atomic<uint8_t>
atomic_int16_t
-- atomic<int16_t>
atomic_uint16_t
-- atomic<uint16_t>
atomic_int32_t
-- atomic<int32_t>
atomic_uint32_t
-- atomic<uint32_t>
atomic_int64_t
-- atomic<int64_t>
atomic_uint64_t
-- atomic<uint64_t>
atomic_int_least8_t
-- atomic<int_least8_t>
atomic_uint_least8_t
-- atomic<uint_least8_t>
atomic_int_least16_t
-- atomic<int_least16_t>
atomic_uint_least16_t
-- atomic<uint_least16_t>
atomic_int_least32_t
-- atomic<int_least32_t>
atomic_uint_least32_t
-- atomic<uint_least32_t>
atomic_int_least64_t
-- atomic<int_least64_t>
atomic_uint_least64_t
-- atomic<uint_least64_t>
atomic_int_fast8_t
-- atomic<int_fast8_t>
atomic_uint_fast8_t
-- atomic<uint_fast8_t>
atomic_int_fast16_t
-- atomic<int_fast16_t>
atomic_uint_fast16_t
-- atomic<uint_fast16_t>
atomic_int_fast32_t
-- atomic<int_fast32_t>
atomic_uint_fast32_t
-- atomic<uint_fast32_t>
atomic_int_fast64_t
-- atomic<int_fast64_t>
atomic_uint_fast64_t
-- atomic<uint_fast64_t>
atomic_intptr_t
-- atomic<intptr_t>
atomic_uintptr_t
-- atomic<uintptr_t>
atomic_size_t
-- atomic<size_t>
atomic_ptrdiff_t
-- atomic<ptrdiff_t>
atomic_intmax_t
-- atomic<intmax_t>
atomic_uintmax_t
-- atomic<uintmax_t>
There are also non-member atomic functions
for all of the operations provided by the various atomic<Ty>
templates. In
the descriptions of each of these functions, a-type refers to any of the atomic types
and m-type refers to the corresponding managed type.
These functions are divided into three groups:
atomic<Ty>
)
atomic<integral>
and atomic<Ty *>
)
atomic<integral>
)
The managed type of any atomic type is the type of the
data object that it manages. For instantiations of atomic<Ty>
the managed
type is Ty
. For the atomic_integral
types it is the
corresponding integral type.
To create a fence, use the function
atomic_thread_fence
or the function
atomic_signal_fence
.
Some platforms support data dependency analysis. For those platforms, consider using the
memory_order
option
memory_order_consume
and the template function
kill_dependency
.
namespace std { // ENUMERATION TYPES typedef enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst, } memory_order; // TEMPLATE CLASS atomic template<class Ty> struct atomic; template<class Ty> struct atomic<Ty *>; template<> struct atomic<char>; template<> struct atomic<signed char>; template<> struct atomic<unsigned char>; template<> struct atomic<char16_t>; template<> struct atomic<char32_t>; template<> struct atomic<wchar_t>; template<> struct atomic<short>; template<> struct atomic<unsigned short>; template<> struct atomic<int>; template<> struct atomic<unsigned int>; template<> struct atomic<long>; template<> struct atomic<unsigned long>; template<> struct atomic<long long>; template<> struct atomic<unsigned long long>; // ATOMIC TYPEDEFS typedef atomic<int8_t> atomic_int8_t; typedef atomic<uint8_t> atomic_uint8_t; typedef atomic<int16_t> atomic_int16_t; typedef atomic<uint16_t> atomic_uint16_t; typedef atomic<int32_t> atomic_int32_t; typedef atomic<uint32_t> atomic_uint32_t; typedef atomic<int64_t> atomic_int64_t; typedef atomic<uint64_t> atomic_uint64_t; typedef atomic<int_least8_t> atomic_int_least8_t; typedef atomic<uint_least8_t> atomic_uint_least8_t; typedef atomic<int_least16_t> atomic_int_least16_t; typedef atomic<uint_least16_t> atomic_uint_least16_t; typedef atomic<int_least32_t> atomic_int_least32_t; typedef atomic<uint_least32_t> atomic_uint_least32_t; typedef atomic<int_least64_t> atomic_int_least64_t; typedef atomic<uint_least64_t> atomic_uint_least64_t; typedef atomic<int_fast8_t> atomic_int_fast8_t; typedef atomic<uint_fast8_t> atomic_uint_fast8_t; typedef atomic<int_fast16_t> atomic_int_fast16_t; typedef atomic<uint_fast16_t> atomic_uint_fast16_t; typedef atomic<int_fast32_t> atomic_int_fast32_t; typedef atomic<uint_fast32_t> atomic_uint_fast32_t; typedef atomic<int_fast64_t> atomic_int_fast64_t; typedef atomic<uint_fast64_t> atomic_uint_fast64_t; typedef atomic<intptr_t> atomic_intptr_t; typedef atomic<uintptr_t> atomic_uintptr_t; typedef atomic<size_t> atomic_size_t; typedef atomic<ptrdiff_t> atomic_ptrdiff_t; typedef atomic<intmax_t> atomic_intmax_t; typedef atomic<uintmax_t> atomic_uintmax_t; // TEMPLATE FUNCTIONS template<class Ty> Ty kill_dependency(Ty t) noexcept; // MACROS #define ATOMIC_FLAG_INIT initializer #define ATOMIC_VAR_INIT initializer #define ATOMIC_BOOL_LOCK_FREE integer-value #define ATOMIC_CHAR_LOCK_FREE integer-value #define ATOMIC_CHAR16_T_LOCK_FREE integer-value #define ATOMIC_CHAR32_T_LOCK_FREE integer-value #define ATOMIC_WCHAR_T_LOCK_FREE integer-value #define ATOMIC_SHORT_LOCK_FREE integer-value #define ATOMIC_INT_LOCK_FREE integer-value #define ATOMIC_LONG_LOCK_FREE integer-value #define ATOMIC_LLONG_LOCK_FREE integer-value #define ATOMIC_POINTER_LOCK_FREE integer-value // STRUCT atomic_flag typedef struct atomic_flag { ... } atomic_flag; bool atomic_flag_test_and_set(volatile atomic_flag *) noexcept; bool atomic_flag_test_and_set(atomic_flag *) noexcept; bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order) noexcept; bool atomic_flag_test_and_set_explicit(atomic_flag *, memory_order) noexcept; bool atomic_flag_clear(volatile atomic_flag *) noexcept; bool atomic_flag_clear(atomic_flag *) noexcept; bool atomic_flag_clear_explicit(volatile atomic_flag *, memory_order) noexcept; bool atomic_flag_clear_explicit(atomic_flag *, memory_order) noexcept; // GENERAL-PURPOSE ATOMIC TYPES typedef struct atomic_char { ... } atomic_char; typedef struct atomic_schar { ... } atomic_schar; typedef struct atomic_uchar { ... } atomic_uchar; typedef struct atomic_char16_t { ... } atomic_char16_t; typedef struct atomic_char32_t { ... } atomic_char32_t; typedef struct atomic_wchar_t { ... } atomic_wchar_t; typedef struct atomic_short { ... } atomic_short; typedef struct atomic_ushort { ... } atomic_ushort; typedef struct atomic_int { ... } atomic_int; typedef struct atomic_uint { ... } atomic_uint; typedef struct atomic_long { ... } atomic_long; typedef struct atomic_ulong { ... } atomic_ulong; typedef struct atomic_llong { ... } atomic_llong; typedef struct atomic_ullong { ... } atomic_ullong; // GENERAL OPERATIONS template<class Ty> bool atomic_is_lock_free(const volatile a-type *) noexcept; template<class Ty> bool atomic_is_lock_free(volatile a-type *) noexcept; template<class Ty> bool atomic_init(volatile a-type *, Ty) noexcept; template<class Ty> bool atomic_init(a-type *, Ty) noexcept; template<class Ty> void atomic_store(volatile a-type *, Ty) noexcept; template<class Ty> void atomic_store(a-type *, Ty) noexcept; template<class Ty> void atomic_store_explicit(volatile a-type *, Ty, memory_order) noexcept; template<class Ty> void atomic_store_explicit(a-type *, Ty, memory_order) noexcept; template<class Ty> Ty atomic_load(const volatile a-type *) noexcept; template<class Ty> Ty atomic_load(const a-type *) noexcept; template<class Ty> Ty atomic_load_explicit(const volatile a-type *, memory_order) noexcept; template<class Ty> Ty atomic_load_explicit(const a-type *, memory_order) noexcept; template<class Ty> Ty atomic_exchange(const volatile a-type *, Ty) noexcept; template<class Ty> Ty atomic_exchange(const a-type *, Ty) noexcept; template<class Ty> Ty atomic_exchange_explicit(const volatile a-type *, Ty, memory_order) noexcept; template<class Ty> Ty atomic_exchange_explicit(const a-type *, Ty, memory_order) noexcept; template<class Ty> bool atomic_compare_exchange_weak(volatile a-type *, Ty *, Ty) noexcept; template<class Ty> bool atomic_compare_exchange_weak(a-type *, Ty *, Ty) noexcept; template<class Ty> bool atomic_compare_exchange_weak_explicit(volatile a-type *, Ty *, Ty, memory_order, memory_order) noexcept; template<class Ty> bool atomic_compare_exchange_weak_explicit(a-type *, Ty *, Ty, memory_order, memory_order) noexcept; template<class Ty> bool atomic_compare_exchange_strong(volatile a-type *, Ty *, Ty) noexcept; template<class Ty> bool atomic_compare_exchange_strong(a-type *, Ty *, Ty) noexcept; template<class Ty> bool atomic_compare_exchange_strong_explicit(volatile a-type *, Ty *, Ty, memory_order, memory_order) noexcept; template<class Ty> bool atomic_compare_exchange_strong_explicit(a-type *, Ty *, Ty, memory_order, memory_order) noexcept; // ARITHMETIC OPERATIONS template<class Ty> Ty atomic_fetch_add(volatile a-type *, Ty) noexcept; template<class Ty> Ty atomic_fetch_add(a-type *, Ty) noexcept; template<class Ty> Ty atomic_fetch_add_explicit(volatile a-type *, Ty, memory_order) noexcept; template<class Ty> Ty atomic_fetch_add_explicit(a-type *, Ty, memory_order) noexcept; template<class Ty> Ty atomic_fetch_sub(volatile a-type *, Ty) noexcept; template<class Ty> Ty atomic_fetch_sub(a-type *, Ty) noexcept; template<class Ty> Ty atomic_fetch_sub_explicit(volatile a-type *, Ty, memory_order) noexcept; template<class Ty> Ty atomic_fetch_sub_explicit(a-type *, Ty, memory_order) noexcept; // LOGICAL OPERATIONS template<class Ty> Ty atomic_fetch_and(volatile a-type *, Ty) noexcept; template<class Ty> Ty atomic_fetch_and(a-type *, Ty) noexcept; template<class Ty> Ty atomic_fetch_and_explicit(volatile a-type *, Ty, memory_order) noexcept; template<class Ty> Ty atomic_fetch_and_explicit(a-type *, Ty, memory_order) noexcept; template<class Ty> Ty atomic_fetch_or(volatile a-type *, Ty) noexcept; template<class Ty> Ty atomic_fetch_or(a-type *, Ty) noexcept; template<class Ty> Ty atomic_fetch_or_explicit(volatile a-type *, Ty, memory_order) noexcept; template<class Ty> Ty atomic_fetch_or_explicit(a-type *, Ty, memory_order) noexcept; template<class Ty> Ty atomic_fetch_xor(volatile a-type *, Ty) noexcept; template<class Ty> Ty atomic_fetch_xor(a-type *, Ty) noexcept; template<class Ty> Ty atomic_fetch_xor_explicit(volatile a-type *, Ty, memory_order) noexcept; template<class Ty> Ty atomic_fetch_xor_explicit(a-type *, Ty, memory_order) noexcept; // FENCES extern "C" void atomic_thread_fence(memory_order) noexcept; extern "C" void atomic_signal_fence(memory_order) noexcept; } // namespace std
atomic
atomic
· compare_exchange_strong
· compare_exchange_weak
· exchange
· is_lock_free
· load
· operator Ty
· operator=
· store
template<class Ty> struct atomic { atomic() = default; constexpr atomic(Ty); atomic(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; atomic& operator=(const atomic&) = delete; Ty operator=(Ty) volatile noexcept; Ty operator=(Ty) noexcept; operator Ty() const volatile noexcept; operator Ty() const noexcept; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; void store(Ty, memory_order = memory_order_seq_cst) volatile noexcept; void store(Ty, memory_order = memory_order_seq_cst) noexcept; Ty load(memory_order = memory_order_seq_cst) const volatile noexcept; Ty load(memory_order = memory_order_seq_cst) const noexcept; Ty exchange(Ty, memory_order = memory_order_seq_cst) volatile noexcept; Ty exchange(Ty, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_weak(Ty&, Ty, memory_order = memory_order_seq_cst) volatile noexcept; bool compare_exchange_weak(Ty&, Ty, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_weak(Ty&, Ty, memory_order, memory_order) volatile noexcept; bool compare_exchange_weak(Ty&, Ty, memory_order, memory_order) noexcept; bool compare_exchange_strong(Ty&, Ty, memory_order = memory_order_seq_cst) volatile noexcept; bool compare_exchange_strong(Ty&, Ty, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_strong(Ty&, Ty, memory_order, memory_order) volatile noexcept; bool compare_exchange_strong(Ty&, Ty, memory_order, memory_order) noexcept; };
The template class describes an object that performs atomic operations on a
stored value of type Ty
. There are specializations
atomic<integral>
for the built-in
integral types and a partial specialization
atomic<Ty *>
for pointer types. This
template is used for all other types.
The type Ty
must be trivially
copyable, that is, copying its bytes with memcpy
must produce a
valid Ty
object that compares equal to the original object.
Also, the compare_exchange_weak
and compare_exchange_strong
member functions use
memcmp
to determine whether two Ty
values are equal; if Ty
defines its own operator==
these functions will not use it.
The member functions of atomic
use memcpy
to copy
values of Ty
.
Objects of type atomic<Ty>
can be passed to any
of the general operations.
atomic::atomic
atomic<Ty>::atomic() = default; constexpr atomic<Ty>::atomic(Ty val) noexcept; atomic<Ty>::atomic(const atomic&) = delete; atomic<integral>::atomic<integral>() = default; constexpr atomic<integral>::atomic<integral>(integral val) noexcept; atomic<integral>::atomic<integral>(const atomic<integral>&) = delete; atomic<Ty *>::atomic<Ty *>() = default; constexpr atomic<Ty *>::atomic<Ty *>(Ty *) noexcept; atomic<Ty *>::atomic<Ty *>(const atomic<Ty *>&) = delete; atomic_integral::atomic_integral() = default; constexpr atomic_integral::atomic_integral(m-type) noexcept; atomic_integral::atomic_integral(const atomic_integral&) = delete;
Atomic objects cannot be copied and they cannot be moved. They can be initialized with aggregate initialization and with a constructor:
atomic<int> ai0 = { 0 }; atomic<int> ai1 = ATOMIC_VAR_INIT(0); atomic<int> ai2(0);
In this implementation, when
a compiler does not support =delete
or =default
,
objects that are instantiations of atomic<Ty>
can be initialized only
by the contructor that takes an argument of type Ty
and not with
aggregate initialization;
atomic_integral
objects can be initialized only with
aggregate initialization.
atomic::compare_exchange_strong
bool atomic<Ty>::compare_exchange_strong( Ty& exp, Ty val, memory_order order = memory_order_seq_cst) volatile noexcept; bool atomic<Ty>::compare_exchange_strong( Ty& exp, Ty val, memory_order order = memory_order_seq_cst) noexcept; bool atomic<Ty>::compare_exchange_strong( Ty& exp, Ty val, memory_order order1, memory_order order2) volatile noexcept; bool atomic<Ty>::compare_exchange_strong( Ty& exp, Ty val, memory_order order1, memory_order order2) noexcept; bool atomic<integral>::compare_exchange_strong( integral& exp, integral val, memory_order order = memory_order_seq_cst) volatile noexcept; bool atomic<integral>::compare_exchange_strong( integral& exp, integral val, memory_order order = memory_order_seq_cst) noexcept; bool atomic<integral>::compare_exchange_strong( integral& exp, integral val, memory_order order1, memory_order order2) volatile noexcept; bool atomic<integral>::compare_exchange_strong( integral& exp, integral val, memory_order order1, memory_order order2) noexcept; bool atomic<Ty *>::compare_exchange_strong( Ty *& exp, Ty *val, memory_order order = memory_order_seq_cst) volatile noexcept; bool atomic<Ty *>::compare_exchange_strong( Ty *& exp, Ty *val, memory_order order = memory_order_seq_cst) noexcept; bool atomic<Ty *>::compare_exchange_strong( Ty *& exp, Ty *val, memory_order order1, memory_order order2) volatile noexcept; bool atomic<Ty *>::compare_exchange_strong( Ty *& exp, Ty *val, memory_order order1, memory_order order2) noexcept; bool atomic_integral::compare_exchange_strong( m-type& exp, m-type val, memory_order order = memory_order_seq_cst) volatile noexcept; bool atomic_integral::compare_exchange_strong( m-type& exp, m-type val, memory_order order = memory_order_seq_cst) noexcept; bool atomic_integral::compare_exchange_strong( m-type& exp, m-type val, memory_order order1, memory_order order2) volatile noexcept; bool atomic_integral::compare_exchange_strong( m-type& exp, m-type val, memory_order order1, memory_order order2) noexcept;
The member functions that take one memory_order
argument perform an
atomic compare and exchange
operation
on this
, with order1
equal to order
and
order2
equal to memory_order_acquire
if order
is memory_order_acq_rel
, memory_order_relaxed
if order
is memory_order_release
, and
order
otherwise. They return the result of the operation.
The member functions that take two memory_order
arguments perform an
atomic compare and exchange
operation
on this
and return the result.
The value of order2
should not be memory_order_release
or
memory_order_acq_rel
, nor should it be stronger than the value
of order1
.
atomic::compare_exchange_weak
bool atomic<Ty>::compare_exchange_weak( Ty& exp, Ty val, memory_order order = memory_order_seq_cst) volatile noexcept; bool atomic<Ty>::compare_exchange_weak( Ty& exp, Ty val, memory_order order = memory_order_seq_cst) noexcept; bool atomic<Ty>::compare_exchange_weak( Ty& exp, Ty val, memory_order order1, memory_order order2) volatile noexcept; bool atomic<Ty>::compare_exchange_weak( Ty& exp, Ty val, memory_order order1, memory_order order2) noexcept; bool atomic<integral>::compare_exchange_weak( integral& exp, integral val, memory_order order = memory_order_seq_cst) volatile noexcept; bool atomic<integral>::compare_exchange_weak( integral& exp, integral val, memory_order order = memory_order_seq_cst) noexcept; bool atomic<integral>::compare_exchange_weak( integral& exp, integral val, memory_order order1, memory_order order2) volatile noexcept; bool atomic<integral>::compare_exchange_weak( integral& exp, integral val, memory_order order1, memory_order order2) noexcept; bool atomic<Ty *>::compare_exchange_weak( Ty *& exp, Ty *val, memory_order order = memory_order_seq_cst) volatile noexcept; bool atomic<Ty *>::compare_exchange_weak( Ty *& exp, Ty *val, memory_order order = memory_order_seq_cst) noexcept; bool atomic<Ty *>::compare_exchange_weak( Ty *& exp, Ty *val, memory_order order1, memory_order order2) volatile noexcept; bool atomic<Ty *>::compare_exchange_weak( Ty *& exp, Ty *val, memory_order order1, memory_order order2) noexcept; bool atomic_integral::compare_exchange_weak( m-type& exp, m-type val, memory_order order = memory_order_seq_cst) volatile noexcept; bool atomic_integral::compare_exchange_weak( m-type& exp, m-type val, memory_order order = memory_order_seq_cst) noexcept; bool atomic_integral::compare_exchange_weak( m-type& exp, m-type val, memory_order order1, memory_order order2) volatile noexcept; bool atomic_integral::compare_exchange_weak( m-type& exp, m-type val, memory_order order1, memory_order order2) noexcept;
The member functions that take one memory_order
argument perform a
weak atomic compare and exchange operation
on this
, with order1
equal to order
and
order2
equal to memory_order_acquire
if
order
is memory_order_acq_rel
, memory_order_relaxed
if order
is memory_order_release
, and
order
otherwise. They return the result of the operation.
The member functions that take two memory_order
arguments perform a
weak atomic compare and exchange operation
on this
and return the result.
The value of order2
should not be memory_order_release
or
memory_order_acq_rel
, nor should it be stronger than the value
of order1
.
atomic::exchange
Ty atomic<Ty>::exchange( Ty value, memory_order order = memory_order_seq_cst) volatile noexcept; Ty atomic<Ty>::exchange( Ty value, memory_order order = memory_order_seq_cst) noexcept; integral atomic<integral>::exchange( integral value, memory_order order = memory_order_seq_cst) volatile noexcept; integral atomic<integral>::exchange( integral value, memory_order order = memory_order_seq_cst) noexcept; Ty *atomic<Ty *>::exchange( Ty *value, memory_order order = memory_order_seq_cst) volatile noexcept; Ty *atomic<Ty *>::exchange( Ty *value, memory_order order = memory_order_seq_cst) noexcept; m-type atomic_integral::exchange( m-type value, memory_order order = memory_order_seq_cst) volatile noexcept; m-type atomic_integral::exchange( m-type value, memory_order order = memory_order_seq_cst) noexcept;
The member functions atomically store value
as the stored
value in *this
and return the stored value that
*this
held on entry.
They apply the memory constraints specified by order
, and are
read-modify-write operations.
atomic::fetch_add
integral atomic<integral>::fetch_add( integral val, memory_order order = memory_order_seq_cst) volatile noexcept; integral atomic<integral>::fetch_add( integral val, memory_order order = memory_order_seq_cst) noexcept; Ty *atomic<Ty *>::fetch_add( ptrdiff_t val, memory_order order = memory_order_seq_cst) volatile noexcept; Ty *atomic<Ty *>::fetch_add( ptrdiff_t val, memory_order order = memory_order_seq_cst) noexcept; m-type atomic_integral::fetch_add( m-type val, memory_order order = memory_order_seq_cst) volatile noexcept; m-type atomic_integral::fetch_add( m-type val, memory_order order = memory_order_seq_cst) noexcept;
The member functions return
atomic_fetch_add_explicit(this, val, order) + val
.
atomic::fetch_and
integral atomic<integral>::fetch_and( integral val, memory_order order = memory_order_seq_cst) volatile noexcept; integral atomic<integral>::fetch_and( integral val, memory_order order = memory_order_seq_cst); m-type atomic_integral::fetch_and( m-type val, memory_order order = memory_order_seq_cst) volatile; m-type atomic_integral::fetch_and( m-type val, memory_order order = memory_order_seq_cst) noexcept;
The member functions return
atomic_fetch_and_explicit(this, val, order) & val
.
atomic::fetch_or
integral atomic<integral>::fetch_or( integral val, memory_order order = memory_order_seq_cst) volatile noexcept; integral atomic<integral>::fetch_or( integral val, memory_order order = memory_order_seq_cst) noexcept; m-type atomic_integral::fetch_or( m-type val, memory_order order = memory_order_seq_cst) volatile noexcept; m-type atomic_integral::fetch_or( m-type val, memory_order order = memory_order_seq_cst) noexcept;
The member functions return
atomic_fetch_or_explicit(this, val, order) | val
.
atomic::fetch_sub
integral atomic<integral>::fetch_sub( integral val, memory_order order = memory_order_seq_cst) volatile noexcept; integral atomic<integral>::fetch_sub( integral val, memory_order order = memory_order_seq_cst) noexcept; Ty *atomic<Ty *>::fetch_sub( ptrdiff_t val, memory_order order = memory_order_seq_cst) volatile noexcept; Ty *atomic<Ty *>::fetch_sub( ptrdiff_t val, memory_order order = memory_order_seq_cst) noexcept; m-type atomic_integral::fetch_sub( m-type val, memory_order order = memory_order_seq_cst) volatile noexcept; m-type atomic_integral::fetch_sub( m-type val, memory_order order = memory_order_seq_cst) noexcept;
The member functions return
atomic_fetch_sub_explicit(this, val, order) - val
.
atomic::fetch_xor
integral atomic<integral>::fetch_xor( integral val, memory_order order = memory_order_seq_cst) volatile noexcept; integral atomic<integral>::fetch_xor( integral val, memory_order order = memory_order_seq_cst) noexcept; m-type atomic_integral::fetch_xor( m-type val, memory_order order = memory_order_seq_cst) volatile noexcept; m-type atomic_integral::fetch_xor( m-type val, memory_order order = memory_order_seq_cst) noexcept;
The member functions return
atomic_fetch_xor_explicit(this, val, order) ^ val
.
atomic::is_lock_free
bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept;
The member functions return
atomic_is_lock_free(this)
.
atomic::load
Ty atomic<Ty>::load(memory_order order = memory_order_seq_cst) const volatile noexcept; Ty atomic<Ty>::load(memory_order order = memory_order_seq_cst) const noexcept; integral atomic<integral>::load(memory_order order = memory_order_seq_cst) const volatile noexcept; integral atomic<integral>::load(memory_order order = memory_order_seq_cst) const noexcept; Ty *atomic<Ty *>::load(memory_order order = memory_order_seq_cst) const volatile noexcept; Ty *atomic<Ty *>::load(memory_order order = memory_order_seq_cst) const noexcept; m-type atomic_integral::load(memory_order order = memory_order_seq_cst) const volatile noexcept; m-type atomic_integral::load(memory_order order = memory_order_seq_cst) const noexcept;
The member functions atomically read the stored value of *this
and return the result.
They apply the memory constraints specified by order
.
The value of order
should not be
memory_order_release
or memory_order_acq_rel
.
atomic::operator Ty
atomic<Ty>::operator Ty() const volatile noexcept; atomic<Ty>::operator Ty() const noexcept; atomic<integral>::operator integral() const volatile noexcept; atomic<integral>::operator integral() const noexcept; atomic<Ty *>::operator Ty *() const volatile noexcept; atomic<Ty *>::operator Ty *() const noexcept; atomic_integral::operator m-type() const volatile noexcept; atomic_integral::operator m-type() const noexcept;
The member operators return
load(memory_order_seq_cst)
.
atomic::operator=
Ty atomic<Ty>::operator=(Ty val) volatile noexcept; Ty atomic<Ty>::operator=(Ty val) noexcept; integral atomic<integral>::operator=(integral val) volatile noexcept; integral atomic<integral>::operator=(integral val) noexcept; Ty *atomic<Ty *>::operator=(Ty *val) volatile noexcept; Ty *atomic<Ty *>::operator=(Ty *val) noexcept; m-type atomic_integral::operator=(m-type val) volatile noexcept; m-type atomic_integral::operator=(m-type val) noexcept;
The member operators call store(val)
and return val
.
atomic::operator++
atomic<integral>::operator++(int) volatile noexcept; atomic<integral>::operator++(int) noexcept; atomic<Ty *>::operator++(int) volatile noexcept; atomic<Ty *>::operator++(int) noexcept; atomic_integral::operator++(int) volatile noexcept; atomic_integral::operator++(int) noexcept; atomic<integral>::operator++() volatile noexcept; atomic<integral>::operator++() noexcept; atomic<Ty *>::operator++() volatile noexcept; atomic<Ty *>::operator++() noexcept; atomic_integral::operator++() volatile noexcept; atomic_integral::operator++() noexcept;
The first six member operators return
atomic_fetch_add_explicit(this, 1, memory_order_seq_cst)
.
The last six member operators return
atomic_fetch_add_explicit(this, 1, memory_order_seq_cst) + 1
.
atomic::operator+=
atomic<integral>::operator+=(integral val) volatile noexcept; atomic<integral>::operator+=(integral val) noexcept; atomic<Ty *>::operator+=(ptrdiff_t val) volatile noexcept; atomic<Ty *>::operator+=(ptrdiff_t val) noexcept; atomic_integral::operator+=(m-type val) volatile noexcept; atomic_integral::operator+=(m-type val) noexcept;
The member operators return
atomic_fetch_add_explicit(this, val, memory_order_seq_cst) + val
.
atomic::operator--
atomic<integral>::operator--(int) volatile noexcept; atomic<integral>::operator--(int) noexcept; atomic<Ty *>::operator--(int) volatile noexcept; atomic<Ty *>::operator--(int) noexcept; atomic_integral::operator--(int) volatile noexcept; atomic_integral::operator--(int) noexcept; atomic<integral>::operator--() volatile noexcept; atomic<integral>::operator--() noexcept; atomic<Ty *>::operator--() volatile noexcept; atomic<Ty *>::operator--() noexcept; atomic_integral::operator--() volatile noexcept; atomic_integral::operator--() noexcept;
The first six member operators return
atomic_fetch_sub_explicit(this, 1, memory_order_seq_cst)
.
The last six member operators return
atomic_fetch_sub_explicit(this, 1, memory_order_seq_cst) - 1
.
atomic::operator-=
atomic<integral>::operator-=(integral val) volatile noexcept; atomic<integral>::operator-=(integral val) noexcept; atomic<Ty *>::operator-=(ptrdiff_t val) volatile noexcept; atomic<Ty *>::operator-=(ptrdiff_t val) noexcept; atomic_integral::operator-=(m-type val) volatile noexcept; atomic_integral::operator-=(m-type val) noexcept;
The member operators return
atomic_fetch_sub_explicit(this, val, memory_order_seq_cst) - val
.
atomic::operator&=
atomic<integral>::operator&=(integral val) volatile noexcept; atomic<integral>::operator&=(integral val) noexcept; atomic_integral::operator&=(m-type val) volatile noexcept; atomic_integral::operator&=(m-type val) noexcept;
The member operators return
atomic_fetch_and_explicit(this, val, memory_order_seq_cst) & val
.
atomic::operator|=
atomic<integral>::operator|=(integral val) volatile noexcept; atomic<integral>::operator|=(integral val) noexcept; atomic_integral::operator|=(m-type val) volatile noexcept; atomic_integral::operator|=(m-type val) noexcept;
The member operators return
atomic_fetch_or_explicit(this, val, memory_order_seq_cst) | val
.
atomic::operator^=
atomic<integral>::operator^=(integral val) volatile noexcept; atomic<integral>::operator^=(integral val) noexcept; atomic_integral::operator^=(m-type val) volatile noexcept; atomic_integral::operator^=(m-type val) noexcept;
The member operators return
atomic_fetch_xor_explicit(this, val, memory_order_seq_cst) ^ val
.
atomic::store
void atomic<Ty>::store( Ty val, memory_order order = memory_order_seq_cst) volatile noexcept; void atomic<Ty>::store( Ty val, memory_order order = memory_order_seq_cst) noexcept; void atomic<integral>::store( integral val, memory_order order = memory_order_seq_cst) volatile noexcept; void atomic<integral>::store( integral val, memory_order order = memory_order_seq_cst) noexcept; void atomic<Ty *>::store( Ty *val, memory_order order = memory_order_seq_cst) volatile noexcept; void atomic<Ty *>::store( Ty *val, memory_order order = memory_order_seq_cst) noexcept; void atomic_integral::store( m-type val, memory_order order = memory_order_seq_cst) volatile noexcept; void atomic_integral::store( m-type val, memory_order order = memory_order_seq_cst) noexcept;
The member functions atomically store val
as the
stored value in *this
.
They apply the memory constraints specified by order
.
The value of order
should not be
memory_order_consume
,
memory_order_acquire
, or memory_order_acq_rel
.
atomic<integral>
atomic<integral>
· compare_exchange_strong
· compare_exchange_weak
· exchange
· fetch_add
· fetch_and
· fetch_or
· fetch_sub
· fetch_xor
· is_lock_free
· load
· operator integral
· operator=
· operator++
· operator+=
· operator--
· operator-=
· operator&=
· operator|=
· operator^=
· store
template<> struct atomic<integral> { atomic() = default; constexpr atomic(integral) noexcept; atomic(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; atomic& operator=(const atomic&) = delete; integral operator=(integral) volatile noexcept; integral operator=(integral) noexcept; atomic& operator=(const atomic&) volatile = delete; atomic& operator=(const atomic&) = delete; integral operator=(integral) volatile noexcept; integral operator=(integral) noexcept; operator integral() const volatile noexcept; operator integral() const noexcept; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; void store(integral, memory_order = memory_order_seq_cst) volatile noexcept; void store(integral, memory_order = memory_order_seq_cst) noexcept; integral load(memory_order = memory_order_seq_cst) const volatile noexcept; integral load(memory_order = memory_order_seq_cst) const noexcept; integral exchange(integral, memory_order = memory_order_seq_cst) volatile noexcept; integral exchange(integral, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_weak(integral&, integral, memory_order = memory_order_seq_cst) volatile noexcept; bool compare_exchange_weak(integral&, integral, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_weak(integral&, integral, memory_order, memory_order) volatile noexcept; bool compare_exchange_weak(integral&, integral, memory_order, memory_order) noexcept; bool compare_exchange_strong(integral&, integral, memory_order = memory_order_seq_cst) volatile noexcept; bool compare_exchange_strong(integral&, integral, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_strong(integral&, integral, memory_order, memory_order) volatile; bool compare_exchange_strong(integral&, integral, memory_order, memory_order) noexcept; integral fetch_add(integral, memory_order = memory_order_seq_cst) volatile noexcept; integral fetch_add(integral, memory_order = memory_order_seq_cst) noexcept; integral fetch_sub(integral, memory_order = memory_order_seq_cst) volatile noexcept; integral fetch_sub(integral, memory_order = memory_order_seq_cst) noexcept; integral fetch_and(integral, memory_order = memory_order_seq_cst) volatile noexcept; integral fetch_and(integral, memory_order = memory_order_seq_cst) noexcept; integral fetch_or(integral, memory_order = memory_order_seq_cst) volatile noexcept; integral fetch_or(integral, memory_order = memory_order_seq_cst) noexcept; integral fetch_xor(integral, memory_order = memory_order_seq_cst) volatile noexcept; integral fetch_xor(integral, memory_order = memory_order_seq_cst) noexcept; integral operator++(int) volatile noexcept; integral operator++(int) noexcept; integral operator++() volatile noexcept; integral operator++() noexcept; integral operator+=(integral) volatile noexcept; integral operator+=(integral) noexcept; integral operator--(int) volatile noexcept; integral operator--(int) noexcept; integral operator--() volatile noexcept; integral operator--() noexcept; integral operator-=(integral) volatile noexcept; integral operator-=(integral) noexcept; integral operator&=(integral) volatile noexcept; integral operator&=(integral) noexcept; integral operator|=(integral) volatile noexcept; integral operator|=(integral) noexcept; integral operator^=(integral) volatile noexcept; integral operator^=(integral) noexcept; };
For each of the integral types except bool
there is a corresponding specialization of the template class
atomic
<Ty>
instantiated with the integral type:
atomic<char>
atomic<signed char>
atomic<unsigned char>
atomic<char16_t>
atomic<char32_t>
atomic<wchar_t>
atomic<short>
atomic<unsigned short>
atomic<int>
atomic<unsigned int>
atomic<long>
atomic<unsigned long>
atomic<long long>
atomic<unsigned long long>
Objects of these types can be passed to any of the non-member atomic functions described earlier.
In this implementation the template
specialization is derived from the corresponding
atomic_integral
type. For example, the specialization
atomic<unsigned int>
is derived from
atomic_uint
.
atomic<Ty *>
atomic<Ty *>
· compare_exchange_strong
· compare_exchange_weak
· exchange
· fetch_add
· fetch_sub
· is_lock_free
· load
· operator Ty *
· operator=
· operator++
· operator+=
· operator--
· operator-=
· store
template<class Ty> struct atomic<Ty *> { atomic() = default; constexpr atomic(Ty *) noexcept; atomic(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; atomic& operator=(const atomic&) = delete; Ty *operator=(Ty *) volatile noexcept; Ty *operator=(Ty *) noexcept; operator Ty *() const volatile noexcept; operator Ty *() const noexcept; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; void store(Ty *, memory_order = memory_order_seq_cst) volatile noexcept; void store(Ty *, memory_order = memory_order_seq_cst) noexcept; Ty *load(memory_order = memory_order_seq_cst) const volatile noexcept; Ty *load(memory_order = memory_order_seq_cst) const noexcept; Ty *exchange(Ty *, memory_order = memory_order_seq_cst) volatile noexcept; Ty *exchange(Ty *, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_weak(Ty *&, Ty *, memory_order = memory_order_seq_cst) volatile noexcept; bool compare_exchange_weak(Ty *&, Ty *, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_weak(Ty *&, Ty *, memory_order, memory_order) volatile noexcept; bool compare_exchange_weak(Ty *&, Ty *, memory_order, memory_order) noexcept; bool compare_exchange_strong(Ty *&, Ty *, memory_order = memory_order_seq_cst) volatile noexcept; bool compare_exchange_strong(Ty *&, Ty *, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_strong(Ty *&, Ty *, memory_order, memory_order) volatile noexcept; bool compare_exchange_strong(Ty *&, Ty *, memory_order, memory_order) noexcept; Ty *fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept; Ty *fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept; Ty *fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept; Ty *fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept noexcept; Ty *operator++(int) volatile noexcept; Ty *operator++(int) noexcept; Ty *operator++() volatile noexcept; Ty *operator++() noexcept; Ty *operator--(int) volatile noexcept; Ty *operator--(int) noexcept; Ty *operator--() volatile noexcept; Ty *operator--() noexcept; Ty *operator+=(ptrdiff_t) volatile noexcept; Ty *operator+=(ptrdiff_t) noexcept; Ty *operator-=(ptrdiff_t) volatile noexcept; Ty *operator-=(ptrdiff_t) noexcept; };
The partial specialization describes an object that performs atomic
operations on a
stored value of type Ty *
. Its arithmetic operations are a bit
different from
those in atomic<integral>
: they take an argument of
type ptrdiff_t
and they adjust that argument according to
the size of Ty
to be consistent with ordinary address
arithmetic.
Objects of any of these partial specializations can be passed to the general operations and the arithmetic operations.
ATOMIC_BOOL_LOCK_FREE
#define ATOMIC_BOOL_LOCK_FREE integer-value
The macro has a value that
indicates whether the type
atomic<bool>
is lock free.
ATOMIC_CHAR_LOCK_FREE
#define ATOMIC_CHAR_LOCK_FREE integer-value
The macro has a value that indicates whether
the types
atomic_char
,
atomic_schar
,
and
atomic_uchar
are lock free.
ATOMIC_CHAR16_T_LOCK_FREE
#define ATOMIC_CHAR16_T_LOCK_FREE integer-value
The macro has a value that indicates whether
the type
atomic_char16_t
is lock free.
ATOMIC_CHAR32_T_LOCK_FREE
#define ATOMIC_CHAR32_T_LOCK_FREE integer-value
The macro has a value that indicates whether
the type
atomic_char32_t
is lock free.
atomic_compare_exchange_strong
template<class Ty> bool atomic_compare_exchange_strong(volatile a-type *atom, Ty *exp, Ty val) noexcept; template<class Ty> bool atomic_compare_exchange_strong(a-type *atom, Ty *exp, Ty val) noexcept;
The template functions return
atomic_compare_exchange_strong_explicit(atom,
exp, val, memory_order_seq_cst, memory_order_seq_cst)
.
atomic_compare_exchange_strong_explicit
template<class Ty> bool atomic_compare_exchange_strong_explicit(volatile a-type *atom, Ty *exp, Ty val, memory_order order1, memory_order order2) noexcept; template<class Ty> bool atomic_compare_exchange_strong_explicit(a-type *atom, Ty *exp, Ty val, memory_order order1, memory_order order2) noexcept;
The template functions perform an
atomic compare and exchange operation
on their arguments and return the result.
The value of order2
should not be memory_order_release
or
memory_order_acq_rel
, nor should it be stronger than the value
of order1
.
An atomic compare and exchange operation takes
five arguments: an atom
, which is a pointer to the object that the operation
is applied to; a pointer or reference named exp
that refers to a value; a value
named val
; and two memory order arguments, order1
and
order2
. The operation does the following, all atomically: it compares
the value stored in the object pointed to by atom
with the value pointed
to by exp
; if they are equal, it replaces the value stored in the
object pointed to by atom
with the value val
with a
read-modify-write operation
and applies
the memory order constraints specified by order1
; if they are not equal,
it replaces the value pointed to by exp
with the value stored in the
object pointed to by atom
and applies the memory order constraints specified
by order2
. It returns the boolean value that was the result of the comparison.
atomic_compare_exchange_weak
template<class Ty> bool atomic_compare_exchange_weak(volatile a-type *atom, Ty *exp, Ty val) noexcept; template<class Ty> bool atomic_compare_exchange_weak(a-type *atom, Ty *exp, Ty val) noexcept;
The template functions return
atomic_compare_exchange_weak_explicit(atom,
exp, val, memory_order_seq_cst, memory_order_seq_cst)
.
atomic_compare_exchange_weak_explicit
template<class Ty> bool atomic_compare_exchange_weak_explicit(volatile a-type *atom, Ty *exp, Ty val, memory_order order1, memory_order order2) noexcept; template<class Ty> bool atomic_compare_exchange_weak_explicit(a-type *atom, Ty *exp, Ty val, memory_order order1, memory_order order2) noexcept;
The template functions perform a
weak atomic compare and exchange
operation on their arguments and return the result.
The value of order2
should not be memory_order_release
or
memory_order_acq_rel
, nor should it be stronger than the value
of order1
.
A weak atomic compare and exchange
is an atomic compare and exchange
operation that may return spuriously. If it returns true
, the comparison
succeeded and the success exchange was made; if it returns false
, the comparison
failed and the failure exchange may or may not have been made.
atomic_exchange
template<class Ty> Ty atomic_exchange(volatile a-type *atom, Ty value) noexcept; template<class Ty> Ty atomic_exchange(a-type *atom, Ty value) noexcept;
The template functions return
atomic_exchange_explicit(atom, value, memory_order_seq_cst)
.
atomic_exchange_explicit
template<class Ty> Ty atomic_exchange_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept; template<class Ty> Ty atomic_exchange_explicit(a-type *atom, Ty value, memory_order order) noexcept;
The template functions atomically store value
as the stored
value in *atom
and return the stored value that *atom
held on entry.
They apply the memory constraints specified by order
, and are
read-modify-write operations.
atomic_fetch_add
template<class Ty> Ty atomic_fetch_add(volatile a-type *atom, Ty value) noexcept; template<class Ty> Ty atomic_fetch_add(a-type *atom, Ty value) noexcept;
The template functions return
atomic_fetch_add_explicit(atom, value, memory_order_seq_cst)
.
atomic_fetch_add_explicit
template<class Ty> Ty atomic_fetch_add_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept; template<class Ty> Ty atomic_fetch_add_explicit(a-type *atom, Ty value, memory_order order) noexcept;
The template functions atomically add value
to the stored value held in
*atom
, store the result in *atom
, and return the result.
They apply the memory constraints specified by order
, and are
read-modify-write operations.
atomic_fetch_and
template<class Ty> Ty atomic_fetch_and(volatile a-type *atom, Ty value) noexcept; template<class Ty> Ty atomic_fetch_and(a-type *atom, Ty value) noexcept;
The template functions return
atomic_fetch_and_explicit(atom, value, memory_order_seq_cst)
.
atomic_fetch_and_explicit
template<class Ty> Ty atomic_fetch_and_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept; template<class Ty> Ty atomic_fetch_and_explicit(a-type *atom, Ty value, memory_order order) noexcept;
The template functions atomically store into *atom
the bitwise and
of value
and the stored value held in *atom
and return the result.
They apply the memory constraints specified by order
, and are
read-modify-write operations.
atomic_fetch_or
template<class Ty> Ty atomic_fetch_or(volatile a-type *atom, Ty value) noexcept; template<class Ty> Ty atomic_fetch_or(a-type *atom, Ty value) noexcept;
The template functions return
atomic_fetch_or_explicit(atom, value, memory_order_seq_cst)
.
atomic_fetch_or_explicit
template<class Ty> Ty atomic_fetch_or_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept; template<class Ty> Ty atomic_fetch_or_explicit(a-type *atom, Ty value, memory_order order) noexcept;
The template functions atomically store into *atom
the bitwise inclusive or
of value
and the stored value held in *atom
and return the result.
They apply the memory constraints specified by order
, and are
read-modify-write operations.
atomic_fetch_sub
template<class Ty> Ty atomic_fetch_sub(volatile a-type *atom, Ty value) noexcept; template<class Ty> Ty atomic_fetch_sub(a-type *atom, Ty value) noexcept;
The template functions return
atomic_fetch_sub_explicit(atom, value, memory_order_seq_cst)
.
atomic_fetch_sub_explicit
template<class Ty> Ty atomic_fetch_sub_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept; template<class Ty> Ty atomic_fetch_sub_explicit(a-type *atom, Ty value, memory_order order) noexcept;
The template functions atomically subtract value
from the stored value held in
*atom
, store the result in *atom
, and return the result.
They apply the memory constraints specified by order
, and are
read-modify-write operations.
When a-type is
atomic_address
,
the argument value
has type ptrdiff_t
and the subtraction
is done as if the stored pointer had type char *
.
atomic_fetch_xor
template<class Ty> Ty atomic_fetch_xor(volatile a-type *atom, Ty value) noexcept; template<class Ty> Ty atomic_fetch_xor(a-type *atom, Ty value) noexcept;
The template functions return
atomic_fetch_xor_explicit(atom, value, memory_order_seq_cst)
.
atomic_fetch_xor_explicit
template<class Ty> Ty atomic_fetch_xor_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept; template<class Ty> Ty atomic_fetch_xor_explicit(a-type *atom, Ty value, memory_order order) noexcept;
The template functions atomically store into *atom
the bitwise exclusive or
of value
and the stored value held in *atom
and return the result.
They apply the memory constraints specified by order
, and are
read-modify-write operations.
atomic_flag
atomic_flag
· clear
· test_and_set
typef struct atomic_flag { atomic_flag() = default; atomic_flag(const atomic_flag&) = delete; atomic_flag& operator=(const atomic_flag&) volatile = delete; atomic_flag& operator=(const atomic_flag&) = delete; bool test_and_set(memory_order = memory_order_seq_cst) volatile noexcept; bool test_and_set(memory_order = memory_order_seq_cst) noexcept; void clear(memory_order = memory_order_seq_cst) volatile noexcept; void clear(memory_order = memory_order_seq_cst) noexcept; } atomic_flag;
The class describes an object that atomically sets and clears a boolean flag. These operations are always lock free.
Objects of type atomic_flag
can be passed to the non-member functions
atomic_flag_clear
,
atomic_flag_clear_explicit
,
atomic_flag_test_and_set
, and
atomic_flag_test_and_set_explicit
,
and can be initialized with the value
ATOMIC_FLAG_INIT
.
atomic_flag::atomic_flag
atomic_flag() noexcept;
The constructor constructs an object that holds an unspecified value.
atomic_flag::clear
void clear(memory_order order = memory_order_seq_cst) volatile noexcept; void clear(memory_order order = memory_order_seq_cst) noexcept;
The member functions call
atomic_flag_clear_explicit(this, order)
.
atomic_flag::test_and_set
bool test_and_set(memory_order order = memory_order_seq_cst) volatile noexcept; bool test_and_set(memory_order order = memory_order_seq_cst) noexcept;
The member functions return
atomic_flag_test_and_set_explicit(this, order)
.
atomic_flag_clear
void atomic_flag_clear(volatile atomic_flag *atom) noexcept; void atomic_flag_clear(atomic_flag *atom) noexcept;
The functions call atomic_flag_clear_explicit(atom, memory_order_seq_cst)
.
atomic_flag_clear_explicit
void atomic_flag_clear_explicit(volatile atomic_flag *atom, memory_order order) noexcept; void atomic_flag_clear_explicit(atomic_flag *atom, memory_order order) noexcept;
The functions atomically set the flag stored in atom
to false
and
apply the memory order constraints specified by order
.
ATOMIC_FLAG_INIT
#define ATOMIC_FLAG_INIT initializer
The macro defines a value that can be used to statically initialize an object
of type atomic_flag
to its cleared state.
atomic_flag_test_and_set
bool atomic_flag_test_and_set(volatile atomic_flag *atom) noexcept; bool atomic_flag_test_and_set(atomic_flag *atom) noexcept;
The functions return
atomic_flag_test_and_set_explicit(atom, memory_order_seq_cst)
.
atomic_flag_test_and_set_explicit
bool atomic_flag_test_and_set_explicit(volatile atomic_flag *atom, memory_order order) noexcept; bool atomic_flag_test_and_set_explicit(atomic_flag *atom, memory_order order) noexcept;
The functions atomically set the flag stored in atom
to true
and
return the value that the flag had on entry.
They apply the memory constraints specified by order
, and are
read-modify-write operations.
atomic_init
template<class Ty> bool atomic_init(volatile a-type *, Ty) noexcept; template<class Ty> bool atomic_init(a-type *, Ty) noexcept;
The template functions set the value stored in atom
to value
. They
are not atomic and not thread-safe.
atomic_integral
atomic_integral
· compare_exchange_strong
· compare_exchange_weak
· exchange
· fetch_add
· fetch_and
· fetch_or
· fetch_sub
· fetch_xor
· is_lock_free
· load
· operator m-type
· operator=
· operator++
· operator+=
· operator--
· operator-=
· operator&=
· operator|=
· operator^=
· store
typedef struct atomic_char { /* ... */ } atomic_char; typedef struct atomic_schar { /* ... */ } atomic_schar; typedef struct atomic_uchar { /* ... */ } atomic_uchar; typedef struct atomic_char16_t { /* ... */ } atomic_char16_6; typedef struct atomic_char32_t { /* ... */ } atomic_char32_t; typedef struct atomic_wchar_t { /* ... */ } atomic_wchar_t; typedef struct atomic_short { /* ... */ } atomic_short; typedef struct atomic_ushort { /* ... */ } atomic_ushort; typedef struct atomic_int { /* ... */ } atomic_int; typedef struct atomic_uint { /* ... */ } atomic_uint; typedef struct atomic_long { /* ... */ } atomic_long; typedef struct atomic_ulong { /* ... */ } atomic_ulong; typedef struct atomic_llong { /* ... */ } atomic_llong; typedef struct atomic_ullong { /* ... */ } atomic_ullong; typedef struct atomic_integral { atomic_integral() = default; constexpr atomic_integral(m-type) noexcept; atomic_integral(const atomic_integral&) = delete; atomic_integral& operator=(const atomic_integral&) volatile = delete; atomic_integral& operator=(const atomic_integral&) = delete; m-type operator=(m-type) volatile; m-type operator=(m-type) noexcept; operator m-type() const volatile noexcept; operator m-type() const noexcept; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; void store(m-type, memory_order = memory_order_seq_cst) volatile noexcept; void store(m-type, memory_order = memory_order_seq_cst) noexcept; m-type load(memory_order = memory_order_seq_cst) const volatile noexcept; m-type load(memory_order = memory_order_seq_cst) const noexcept; m-type exchange(m-type, memory_order = memory_order_seq_cst) volatile noexcept; m-type exchange(m-type, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_weak(m-type&, m-type, memory_order = memory_order_seq_cst) volatile noexcept; bool compare_exchange_weak(m-type&, m-type, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_weak(m-type&, m-type, memory_order, memory_order) volatile noexcept; bool compare_exchange_weak(m-type&, m-type, memory_order, memory_order) noexcept; bool compare_exchange_strong(m-type&, m-type, memory_order = memory_order_seq_cst) volatile noexcept; bool compare_exchange_strong(m-type&, m-type, memory_order = memory_order_seq_cst) noexcept; bool compare_exchange_strong(m-type&, m-type, memory_order, memory_order) volatile noexcept; bool compare_exchange_strong(m-type&, m-type, memory_order, memory_order) noexcept; m-type fetch_add(m-type, memory_order = memory_order_seq_cst) volatile noexcept; m-type fetch_add(m-type, memory_order = memory_order_seq_cst) noexcept; m-type fetch_sub(m-type, memory_order = memory_order_seq_cst) volatile noexcept; m-type fetch_sub(m-type, memory_order = memory_order_seq_cst) noexcept; m-type fetch_and(m-type, memory_order = memory_order_seq_cst) volatile noexcept; m-type fetch_and(m-type, memory_order = memory_order_seq_cst) noexcept; m-type fetch_or(m-type, memory_order = memory_order_seq_cst) volatile noexcept; m-type fetch_or(m-type, memory_order = memory_order_seq_cst) noexcept; m-type fetch_xor(m-type, memory_order = memory_order_seq_cst) volatile noexcept; m-type fetch_xor(m-type, memory_order = memory_order_seq_cst) noexcept; m-type operator++(int) volatile noexcept; m-type operator++(int) noexcept; m-type operator++() volatile noexcept; m-type operator++() noexcept; m-type operator--(int) volatile noexcept; m-type operator--(int) noexcept; m-type operator--() volatile noexcept; m-type operator--() noexcept; m-type operator+=(m-type) volatile noexcept; m-type operator+=(m-type) noexcept; m-type operator-=(m-type) volatile noexcept; m-type operator-=(m-type) noexcept; m-type operator&=(m-type) volatile noexcept; m-type operator&=(m-type) noexcept; m-type operator|=(m-type) volatile noexcept; m-type operator|=(m-type) noexcept; m-type operator^=(m-type) volatile noexcept; m-type operator^=(m-type) noexcept; } atomic_integral;
The integral atomic types consist of all of the
general-purpose atomic types except
atomic_address
and atomic_bool
. Each integral
atomic type describes an object that performs atomic operations on a stored
value of its managed type.
Objects of these types can be passed to the general operations, the arithmetic operations, and the logical operations.
ATOMIC_INT_LOCK_FREE
#define ATOMIC_INT_LOCK_FREE integer-value
The macro has a value that
indicates whether the types
atomic_int
and
atomic_uint
are lock free.
atomic_is_lock_free
template<class Ty> bool atomic_is_lock_free(const volatile a-type *atom) noexcept; template<class Ty> bool atomic_is_lock_free(const a-type *atom) noexcept;
The template functions return true
only if atomic operations on
*atom
are lock free.
ATOMIC_LLONG_LOCK_FREE
#define ATOMIC_LLONG_LOCK_FREE integer-value
The macro has a value that
indicates whether the types
atomic_llong
and
atomic_ullong
are lock free.
atomic_load
Ty atomic_load(const volatile a-type *atom) noexcept; Ty atomic_load(const a-type *atom) noexcept;
The functions return
atomic_load_explicit(atom, memory_order_seq_cst)
.
atomic_load_explicit
Ty atomic_load_explicit(const volatile a-type *atom, memory_order order); Ty atomic_load_explicit(const a-type *atom, memory_order order);
The functions atomically load the stored value held in
*atom
and return the result.
They apply the memory constraints specified by order
.
The value of order
should not be
memory_order_release
or memory_order_acq_rel
.
ATOMIC_LONG_LOCK_FREE
#define ATOMIC_LONG_LOCK_FREE integer-value
The macro has a value that
indicates whether the types
atomic_long
and
atomic_ulong
are lock free.
ATOMIC_POINTER_LOCK_FREE
#define ATOMIC_POINTER_LOCK_FREE integer-value
The macro has a value that
indicates whether the type
atomic<Ty *>
,
where Ty
is any object type,
is lock free.
ATOMIC_SHORT_LOCK_FREE
#define ATOMIC_SHORT_LOCK_FREE integer-value
The macro has a value that
indicates whether the types
atomic_short
and
atomic_ushort
are lock free.
atomic_signal_fence
extern "C" void atomic_signal_fence(memory_order order) noexcept;
The function acts the same as atomic_thread_fence except that it establishes ordering requirements only between fences in the calling thread and in signal handlers executed in the same thread.
atomic_store
template<class Ty> void atomic_store(volatile a-type *atom, Ty value) noexcept; template<class Ty> void atomic_store(Ty *atom, a-type value) noexcept;
The template functions call atomic_store_explicit(atom, value, memory_order_seq_cst)
.
atomic_store_explicit
template<class Ty> void atomic_store_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept; template<class Ty> void atomic_store_explicit(a-type *atom, Ty value, memory_order order) noexcept;
The template functions atomically store value
as the stored value
in *atom
.
They apply the memory constraints specified by order
.
The value of order
should not be
memory_order_consume
,
memory_order_acquire
, or memory_order_acq_rel
.
atomic_thread_fence
extern "C" void atomic_thread_fence(memory_order order) noexcept;
The function acts as a fence that establishes memory ordering
requirements with respect to other fences. The order
argument
determines the type of the fence:
memory_order_relaxed
--
the fence has no effect.memory_order_consume
--
the fence is an acquire fence.memory_order_acquire
--
the fence is an acquire fence.memory_order_release
--
the fence is a release fence.memory_order_acq_rel
--
the fence is both an acquire fence and
a release fence.memory_order_seq_cst
--
the fence is both an acquire fence and a release fence and
it is sequentially consistentATOMIC_VAR_INIT
#define ATOMIC_VAR_INIT(x) initializer
The macro expands to an expression that can be used to statically
initialize
a general-purpose atomic type to the value
x
, when x
can be converted to
atomic type's
managed type.
ATOMIC_WCHAR_T_LOCK_FREE
#define ATOMIC_WCHAR_T_LOCK_FREE integer-value
The macro has a value that
indicates whether the type
atomic_wchar_t
is lock free.
kill_dependency
template<class Ty> kill_dependency(Ty) noexcept;
The template function returns its argument. The evaluation of the argument
does not carry a dependency to the function call. By breaking
a possible dependency chain, the function might permit the compiler
to generate more efficient code. See the discussion of the attribute
[[carries_dependency]]
in the C++ standard.
memory_order
typedef enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst } memory_order;
The enumeration supplies symbolic names for synchronization operations on memory locations. These operations affect how assignments in one thread become visible in another, as set out in [intro.mulththread] in the C++ standard. The meanings of these names are:
memory_order_relaxed
--
no ordering required.memory_order_consume
--
a load operation acts as a consume operation
on the memory location.memory_order_acquire
--
a load operation acts as an acquire operation
on the memory location.memory_order_release
--
a store operation acts as a release operation
on the memory location.memory_order_acq_rel
--
combines memory_order_acquire
and memory_order_release
.memory_order_seq_cst
--
combines memory_order_acquire
and memory_order_release
and requires that all memory accesses marked as memory_order_seq_cst
be sequentially consistent.See also the Table of Contents and the Index.
Copyright © 1992-2013 by P.J. Plauger. All rights reserved.