[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)
