[atomics.order] # 32 Concurrency support library [[thread]](./#thread) ## 32.5 Atomic operations [[atomics]](atomics#order) ### 32.5.4 Order and consistency [atomics.order] namespace std {enum class memory_order : *unspecified* { relaxed = 0, acquire = 2, release = 3, acq_rel = 4, seq_cst = 5};} [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2903) The enumeration memory_order specifies the detailed regular (non-atomic) memory synchronization order as defined in[[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races") and may provide for operation ordering[.](#1.sentence-1) Its enumerated values and their meanings are as follows: - [(1.1)](#1.1) memory_order​::​relaxed: no operation orders memory[.](#1.1.sentence-1) - [(1.2)](#1.2) memory_order​::​release, memory_order​::​acq_rel, andmemory_order​::​seq_cst: a store operation performs a release operation on the affected memory location[.](#1.2.sentence-1) - [(1.3)](#1.3) memory_order​::​acquire, memory_order​::​acq_rel, andmemory_order​::​seq_cst: a load operation performs an acquire operation on the affected memory location[.](#1.3.sentence-1) [*Note [1](#note-1)*: Atomic operations specifying memory_order​::​relaxed are relaxed with respect to memory ordering[.](#1.sentence-3) Implementations must still guarantee that any given atomic access to a particular atomic object be indivisible with respect to all other atomic accesses to that object[.](#1.sentence-4) — *end note*] [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2928) An atomic operation A that performs a release operation on an atomic object M synchronizes with an atomic operation B that performs an acquire operation on M and takes its value from any side effect in the release sequence headed by A[.](#2.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2934) An atomic operation A on some atomic object M is[*coherence-ordered before*](#def:coherence-ordered_before "32.5.4 Order and consistency [atomics.order]") another atomic operation B on M if - [(3.1)](#3.1) A is a modification, andB reads the value stored by A, or - [(3.2)](#3.2) A precedes B in the modification order of M, or - [(3.3)](#3.3) A and B are not the same atomic read-modify-write operation, and there exists an atomic modification X of M such that A reads the value stored by X andX precedes B in the modification order of M, or - [(3.4)](#3.4) there exists an atomic modification X of M such that A is coherence-ordered before X andX is coherence-ordered before B[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2954) There is a single total order S on all memory_order​::​seq_cst operations, including fences, that satisfies the following constraints[.](#4.sentence-1) First, if A and B arememory_order​::​seq_cst operations andA strongly happens before B, then A precedes B in S[.](#4.sentence-2) Second, for every pair of atomic operations A andB on an object M, where A is coherence-ordered before B, the following four conditions are required to be satisfied by S: - [(4.1)](#4.1) if A and B are bothmemory_order​::​seq_cst operations, then A precedes B in S; and - [(4.2)](#4.2) if A is a memory_order​::​seq_cst operation andB happens before a memory_order​::​seq_cst fence Y, then A precedes Y in S; and - [(4.3)](#4.3) if a memory_order​::​seq_cst fence X happens before A andB is a memory_order​::​seq_cst operation, then X precedes B in S; and - [(4.4)](#4.4) if a memory_order​::​seq_cst fence X happens before A andB happens before a memory_order​::​seq_cst fence Y, then X precedes Y in S[.](#4.sentence-3) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2985) [*Note [2](#note-2)*: This definition ensures that S is consistent with the modification order of any atomic object M[.](#5.sentence-1) It also ensures that a memory_order​::​seq_cst load A of M gets its value either from the last modification of M that precedes A in S or from some non-memory_order​::​seq_cst modification of M that does not happen before any modification of M that precedes A in S[.](#5.sentence-2) — *end note*] [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L2998) [*Note [3](#note-3)*: We do not require that S be consistent with “happens before” ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#6.sentence-1) This allows more efficient implementation of memory_order​::​acquire and memory_order​::​release on some machine architectures[.](#6.sentence-2) It can produce surprising results when these are mixed with memory_order​::​seq_cst accesses[.](#6.sentence-3) — *end note*] [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3009) [*Note [4](#note-4)*: memory_order​::​seq_cst ensures sequential consistency only for a program that is free of data races and uses exclusively memory_order​::​seq_cst atomic operations[.](#7.sentence-1) Any use of weaker ordering will invalidate this guarantee unless extreme care is used[.](#7.sentence-2) In many cases, memory_order​::​seq_cst atomic operations are reorderable with respect to other atomic operations performed by the same thread[.](#7.sentence-3) — *end note*] [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3020) Implementations should ensure that no “out-of-thin-air” values are computed that circularly depend on their own computation[.](#8.sentence-1) [*Note [5](#note-5)*: For example, with x and y initially zero,// Thread 1: r1 = y.load(memory_order::relaxed); x.store(r1, memory_order::relaxed); // Thread 2: r2 = x.load(memory_order::relaxed); y.store(r2, memory_order::relaxed); this recommendation discourages producing r1 == r2 == 42, since the store of 42 to y is only possible if the store to x stores 42, which circularly depends on the store to y storing 42[.](#8.sentence-3) Note that without this restriction, such an execution is possible[.](#8.sentence-4) — *end note*] [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3043) [*Note [6](#note-6)*: The recommendation similarly disallows r1 == r2 == 42 in the following example, with x and y again initially zero: // Thread 1: r1 = x.load(memory_order::relaxed);if (r1 == 42) y.store(42, memory_order::relaxed); // Thread 2: r2 = y.load(memory_order::relaxed);if (r2 == 42) x.store(42, memory_order::relaxed); — *end note*] [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3061) Atomic read-modify-write operations shall always read the last value (in the modification order) written before the write associated with the read-modify-write operation[.](#10.sentence-1) [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3066) An [*atomic modify-write operation*](#def:modify-write_operation,atomic "32.5.4 Order and consistency [atomics.order]") is an atomic read-modify-write operation with weaker synchronization requirements as specified in [[atomics.fences]](atomics.fences "32.5.11 Fences")[.](#11.sentence-1) [*Note [7](#note-7)*: The intent is for atomic modify-write operations to be implemented using mechanisms that are not ordered, in hardware, by the implementation of acquire fences[.](#11.sentence-2) No other semantic or hardware property (e.g., that the mechanism is a far atomic operation) is implied[.](#11.sentence-3) — *end note*] [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3078) *Recommended practice*: The implementation should make atomic stores visible to atomic loads, and atomic loads should observe atomic stores, within a reasonable amount of time[.](#12.sentence-1)