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

250 lines
10 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.flag]
# 32 Concurrency support library [[thread]](./#thread)
## 32.5 Atomic operations [[atomics]](atomics#flag)
### 32.5.10 Flag type and operations [atomics.flag]
namespace std {struct atomic_flag {constexpr atomic_flag() noexcept;
atomic_flag(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) volatile = delete; bool test(memory_order = memory_order::seq_cst) const volatile noexcept; constexpr bool test(memory_order = memory_order::seq_cst) const noexcept; bool test_and_set(memory_order = memory_order::seq_cst) volatile noexcept; constexpr bool test_and_set(memory_order = memory_order::seq_cst) noexcept; void clear(memory_order = memory_order::seq_cst) volatile noexcept; constexpr void clear(memory_order = memory_order::seq_cst) noexcept; void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept; constexpr void wait(bool, memory_order = memory_order::seq_cst) const noexcept; void notify_one() volatile noexcept; constexpr void notify_one() noexcept; void notify_all() volatile noexcept; constexpr void notify_all() noexcept; };}
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6822)
The atomic_flag type provides the classic test-and-set functionality[.](#1.sentence-1)
It has two states, set and clear[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6825)
Operations on an object of type atomic_flag shall be lock-free[.](#2.sentence-1)
The operations should also be address-free[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6829)
The atomic_flag type is a standard-layout struct[.](#3.sentence-1)
It has a trivial destructor[.](#3.sentence-2)
[🔗](#lib:atomic_flag,constructor)
`constexpr atomic_flag::atomic_flag() noexcept;
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6839)
*Effects*: Initializes *this to the clear state[.](#4.sentence-1)
[🔗](#lib:atomic_flag_test)
`bool atomic_flag_test(const volatile atomic_flag* object) noexcept;
constexpr bool atomic_flag_test(const atomic_flag* object) noexcept;
bool atomic_flag_test_explicit(const volatile atomic_flag* object,
memory_order order) noexcept;
constexpr bool atomic_flag_test_explicit(const atomic_flag* object,
memory_order order) noexcept;
bool atomic_flag::test(memory_order order = memory_order::seq_cst) const volatile noexcept;
constexpr bool atomic_flag::test(memory_order order = memory_order::seq_cst) const noexcept;
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6859)
For atomic_flag_test, let order be memory_order::seq_cst[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6862)
*Preconditions*: order ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6869)
*Effects*: Memory is affected according to the value of order[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6873)
*Returns*: Atomically returns the value pointed to by object or this[.](#8.sentence-1)
[🔗](#lib:atomic_flag_test_and_set)
`bool atomic_flag_test_and_set(volatile atomic_flag* object) noexcept;
constexpr bool atomic_flag_test_and_set(atomic_flag* object) noexcept;
bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object, memory_order order) noexcept;
constexpr bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept;
bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) noexcept;
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6891)
*Effects*: Atomically sets the value pointed to by object or by this to true[.](#9.sentence-1)
Memory is affected according to the value oforder[.](#9.sentence-2)
These operations are atomic read-modify-write operations ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races"))[.](#9.sentence-3)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6896)
*Returns*: Atomically, the value of the object immediately before the effects[.](#10.sentence-1)
[🔗](#lib:atomic_flag_clear)
`void atomic_flag_clear(volatile atomic_flag* object) noexcept;
constexpr void atomic_flag_clear(atomic_flag* object) noexcept;
void atomic_flag_clear_explicit(volatile atomic_flag* object, memory_order order) noexcept;
constexpr void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept;
void atomic_flag::clear(memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr void atomic_flag::clear(memory_order order = memory_order::seq_cst) noexcept;
`
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6914)
*Preconditions*: order ismemory_order::relaxed,memory_order::release, ormemory_order::seq_cst[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6921)
*Effects*: Atomically sets the value pointed to by object or by this tofalse[.](#12.sentence-1)
Memory is affected according to the value of order[.](#12.sentence-2)
[🔗](#lib:atomic_flag_wait)
`void atomic_flag_wait(const volatile atomic_flag* object, bool old) noexcept;
constexpr void atomic_flag_wait(const atomic_flag* object, bool old) noexcept;
void atomic_flag_wait_explicit(const volatile atomic_flag* object,
bool old, memory_order order) noexcept;
constexpr void atomic_flag_wait_explicit(const atomic_flag* object,
bool old, memory_order order) noexcept;
void atomic_flag::wait(bool old, memory_order order =
memory_order::seq_cst) const volatile noexcept;
constexpr void atomic_flag::wait(bool old, memory_order order =
memory_order::seq_cst) const noexcept;
`
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6944)
For atomic_flag_wait,
let order be memory_order::seq_cst[.](#13.sentence-1)
Let flag be object for the non-member functions andthis for the member functions[.](#13.sentence-2)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6950)
*Preconditions*: order ismemory_order::relaxed,memory_order::acquire, ormemory_order::seq_cst[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6957)
*Effects*: Repeatedly performs the following steps, in order:
- [(15.1)](#15.1)
Evaluates flag->test(order) != old[.](#15.1.sentence-1)
- [(15.2)](#15.2)
If the result of that evaluation is true, returns[.](#15.2.sentence-1)
- [(15.3)](#15.3)
Blocks until it
is unblocked by an atomic notifying operation or is unblocked spuriously[.](#15.3.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6970)
*Remarks*: This function is an atomic waiting operation ([[atomics.wait]](atomics.wait "32.5.6Waiting and notifying"))[.](#16.sentence-1)
[🔗](#itemdecl:6)
`void atomic_flag_notify_one(volatile atomic_flag* object) noexcept;
constexpr void atomic_flag_notify_one(atomic_flag* object) noexcept;
void atomic_flag::notify_one() volatile noexcept;
constexpr void atomic_flag::notify_one() noexcept;
`
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6983)
*Effects*: Unblocks the execution of at least one atomic waiting operation
that is eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6Waiting and notifying")) by this call,
if any such atomic waiting operations exist[.](#17.sentence-1)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L6989)
*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6Waiting and notifying"))[.](#18.sentence-1)
[🔗](#itemdecl:7)
`void atomic_flag_notify_all(volatile atomic_flag* object) noexcept;
constexpr void atomic_flag_notify_all(atomic_flag* object) noexcept;
void atomic_flag::notify_all() volatile noexcept;
constexpr void atomic_flag::notify_all() noexcept;
`
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7002)
*Effects*: Unblocks the execution of all atomic waiting operations
that are eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6Waiting and notifying")) by this call[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7007)
*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6Waiting and notifying"))[.](#20.sentence-1)
[🔗](#itemdecl:8)
`#define ATOMIC_FLAG_INIT see below
`
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L7017)
*Remarks*: The macro ATOMIC_FLAG_INIT is defined in such a way that
it can be used to initialize an object of type atomic_flag to the clear state[.](#21.sentence-1)
The macro can be used in the form:atomic_flag guard = ATOMIC_FLAG_INIT;
It is unspecified whether the macro can be used
in other initialization contexts[.](#21.sentence-3)
For a complete static-duration object, that initialization shall be static[.](#21.sentence-4)