[atomics.fences] # 32 Concurrency support library [[thread]](./#thread) ## 32.5 Atomic operations [[atomics]](atomics#fences) ### 32.5.11 Fences [atomics.fences] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7033) This subclause introduces synchronization primitives called [*fences*](#def:fences)[.](#1.sentence-1) Fences can have acquire semantics, release semantics, or both[.](#1.sentence-2) A fence with acquire semantics is called an [*acquire fence*](#def:acquire_fence)[.](#1.sentence-3) A fence with release semantics is called a [*release fence*](#def:release_fence)[.](#1.sentence-4) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7039) A release fence A synchronizes with an acquire fence B if there exist atomic operations X and Y, where Y is not an atomic modify-write operation ([[atomics.order]](atomics.order "32.5.4 Order and consistency")), both operating on some atomic objectM, such that A is sequenced before X, X modifiesM, Y is sequenced before B, and Y reads the value written by X or a value written by any side effect in the hypothetical release sequence X would head if it were a release operation[.](#2.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7049) A release fence A synchronizes with an atomic operation B that performs an acquire operation on an atomic object M if there exists an atomic operation X such that A is sequenced before X, X modifies M, and B reads the value written by X or a value written by any side effect in the hypothetical release sequence X would head if it were a release operation[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7057) An atomic operation A that is a release operation on an atomic objectM synchronizes with an acquire fence B if there exists some atomic operation X on M such that X is sequenced before B and reads the value written by A or a value written by any side effect in the release sequence headed by A[.](#4.sentence-1) [🔗](#lib:atomic_thread_fence) `extern "C" constexpr void atomic_thread_fence(memory_order order) noexcept; ` [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7070) *Effects*: Depending on the value of order, this operation: - [(5.1)](#5.1) has no effects, if order == memory_order​::​relaxed; - [(5.2)](#5.2) is an acquire fence, if order == memory_order​::​acquire; - [(5.3)](#5.3) is a release fence, if order == memory_order​::​release; - [(5.4)](#5.4) is both an acquire fence and a release fence, if order == memory_order​::​acq_rel; - [(5.5)](#5.5) is a sequentially consistent acquire and release fence, if order == memory_order​::​seq_cst[.](#5.sentence-1) [🔗](#lib:atomic_signal_fence) `extern "C" constexpr void atomic_signal_fence(memory_order order) noexcept; ` [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7092) *Effects*: Equivalent to atomic_thread_fence(order), except that the resulting ordering constraints are established only between a thread and a signal handler executed in the same thread[.](#6.sentence-1) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7098) [*Note [1](#note-1)*: atomic_signal_fence can be used to specify the order in which actions performed by the thread become visible to the signal handler[.](#7.sentence-1) Compiler optimizations and reorderings of loads and stores are inhibited in the same way as with atomic_thread_fence, but the hardware fence instructions that atomic_thread_fence would have inserted are not emitted[.](#7.sentence-2) — *end note*]