Files
2025-10-25 03:02:53 +03:00

234 lines
8.2 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.2Multi-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.4Order 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.2Data 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.4Order and consistency[atomics.order]") is
an atomic read-modify-write operation
with weaker synchronization requirements as specified in [[atomics.fences]](atomics.fences "32.5.11Fences")[.](#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)