- tmp/tmpkj4dwtow/{from.md → to.md} +103 -34
tmp/tmpkj4dwtow/{from.md → to.md}
RENAMED
|
@@ -1,31 +1,29 @@
|
|
| 1 |
## Flag type and operations <a id="atomics.flag">[[atomics.flag]]</a>
|
| 2 |
|
| 3 |
``` cpp
|
| 4 |
namespace std {
|
| 5 |
struct atomic_flag {
|
| 6 |
-
|
| 7 |
-
bool test_and_set(memory_order = memory_order_seq_cst) noexcept;
|
| 8 |
-
void clear(memory_order = memory_order_seq_cst) volatile noexcept;
|
| 9 |
-
void clear(memory_order = memory_order_seq_cst) noexcept;
|
| 10 |
-
|
| 11 |
-
atomic_flag() noexcept = default;
|
| 12 |
atomic_flag(const atomic_flag&) = delete;
|
| 13 |
atomic_flag& operator=(const atomic_flag&) = delete;
|
| 14 |
atomic_flag& operator=(const atomic_flag&) volatile = delete;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
};
|
| 16 |
-
|
| 17 |
-
bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept;
|
| 18 |
-
bool atomic_flag_test_and_set(atomic_flag*) noexcept;
|
| 19 |
-
bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order) noexcept;
|
| 20 |
-
bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept;
|
| 21 |
-
void atomic_flag_clear(volatile atomic_flag*) noexcept;
|
| 22 |
-
void atomic_flag_clear(atomic_flag*) noexcept;
|
| 23 |
-
void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept;
|
| 24 |
-
void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept;
|
| 25 |
-
|
| 26 |
-
#define ATOMIC_FLAG_INIT see below
|
| 27 |
}
|
| 28 |
```
|
| 29 |
|
| 30 |
The `atomic_flag` type provides the classic test-and-set functionality.
|
| 31 |
It has two states, set and clear.
|
|
@@ -34,53 +32,124 @@ Operations on an object of type `atomic_flag` shall be lock-free.
|
|
| 34 |
|
| 35 |
[*Note 1*: Hence the operations should also be
|
| 36 |
address-free. — *end note*]
|
| 37 |
|
| 38 |
The `atomic_flag` type is a standard-layout struct. It has a trivial
|
| 39 |
-
|
| 40 |
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
|
|
|
|
|
|
| 44 |
|
| 45 |
``` cpp
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
```
|
| 48 |
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
|
| 55 |
``` cpp
|
| 56 |
bool atomic_flag_test_and_set(volatile atomic_flag* object) noexcept;
|
| 57 |
bool atomic_flag_test_and_set(atomic_flag* object) noexcept;
|
| 58 |
bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object, memory_order order) noexcept;
|
| 59 |
bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept;
|
| 60 |
-
bool atomic_flag::test_and_set(memory_order order =
|
| 61 |
-
bool atomic_flag::test_and_set(memory_order order =
|
| 62 |
```
|
| 63 |
|
| 64 |
*Effects:* Atomically sets the value pointed to by `object` or by `this`
|
| 65 |
to `true`. Memory is affected according to the value of `order`. These
|
| 66 |
operations are atomic read-modify-write
|
| 67 |
-
operations
|
| 68 |
|
| 69 |
*Returns:* Atomically, the value of the object immediately before the
|
| 70 |
effects.
|
| 71 |
|
| 72 |
``` cpp
|
| 73 |
void atomic_flag_clear(volatile atomic_flag* object) noexcept;
|
| 74 |
void atomic_flag_clear(atomic_flag* object) noexcept;
|
| 75 |
void atomic_flag_clear_explicit(volatile atomic_flag* object, memory_order order) noexcept;
|
| 76 |
void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept;
|
| 77 |
-
void atomic_flag::clear(memory_order order =
|
| 78 |
-
void atomic_flag::clear(memory_order order =
|
| 79 |
```
|
| 80 |
|
| 81 |
-
*
|
| 82 |
-
`
|
|
|
|
| 83 |
|
| 84 |
*Effects:* Atomically sets the value pointed to by `object` or by `this`
|
| 85 |
to `false`. Memory is affected according to the value of `order`.
|
| 86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
## Flag type and operations <a id="atomics.flag">[[atomics.flag]]</a>
|
| 2 |
|
| 3 |
``` cpp
|
| 4 |
namespace std {
|
| 5 |
struct atomic_flag {
|
| 6 |
+
constexpr atomic_flag() noexcept;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
atomic_flag(const atomic_flag&) = delete;
|
| 8 |
atomic_flag& operator=(const atomic_flag&) = delete;
|
| 9 |
atomic_flag& operator=(const atomic_flag&) volatile = delete;
|
| 10 |
+
|
| 11 |
+
bool test(memory_order = memory_order::seq_cst) const volatile noexcept;
|
| 12 |
+
bool test(memory_order = memory_order::seq_cst) const noexcept;
|
| 13 |
+
bool test_and_set(memory_order = memory_order::seq_cst) volatile noexcept;
|
| 14 |
+
bool test_and_set(memory_order = memory_order::seq_cst) noexcept;
|
| 15 |
+
void clear(memory_order = memory_order::seq_cst) volatile noexcept;
|
| 16 |
+
void clear(memory_order = memory_order::seq_cst) noexcept;
|
| 17 |
+
|
| 18 |
+
void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
|
| 19 |
+
void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
|
| 20 |
+
void notify_one() volatile noexcept;
|
| 21 |
+
void notify_one() noexcept;
|
| 22 |
+
void notify_all() volatile noexcept;
|
| 23 |
+
void notify_all() noexcept;
|
| 24 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
}
|
| 26 |
```
|
| 27 |
|
| 28 |
The `atomic_flag` type provides the classic test-and-set functionality.
|
| 29 |
It has two states, set and clear.
|
|
|
|
| 32 |
|
| 33 |
[*Note 1*: Hence the operations should also be
|
| 34 |
address-free. — *end note*]
|
| 35 |
|
| 36 |
The `atomic_flag` type is a standard-layout struct. It has a trivial
|
| 37 |
+
destructor.
|
| 38 |
|
| 39 |
+
``` cpp
|
| 40 |
+
constexpr atomic_flag::atomic_flag() noexcept;
|
| 41 |
+
```
|
| 42 |
+
|
| 43 |
+
*Effects:* Initializes `*this` to the clear state.
|
| 44 |
|
| 45 |
``` cpp
|
| 46 |
+
bool atomic_flag_test(const volatile atomic_flag* object) noexcept;
|
| 47 |
+
bool atomic_flag_test(const atomic_flag* object) noexcept;
|
| 48 |
+
bool atomic_flag_test_explicit(const volatile atomic_flag* object,
|
| 49 |
+
memory_order order) noexcept;
|
| 50 |
+
bool atomic_flag_test_explicit(const atomic_flag* object,
|
| 51 |
+
memory_order order) noexcept;
|
| 52 |
+
bool atomic_flag::test(memory_order order = memory_order::seq_cst) const volatile noexcept;
|
| 53 |
+
bool atomic_flag::test(memory_order order = memory_order::seq_cst) const noexcept;
|
| 54 |
```
|
| 55 |
|
| 56 |
+
For `atomic_flag_test`, let `order` be `memory_order::seq_cst`.
|
| 57 |
+
|
| 58 |
+
*Preconditions:* `order` is neither `memory_order::release` nor
|
| 59 |
+
`memory_order::acq_rel`.
|
| 60 |
+
|
| 61 |
+
*Effects:* Memory is affected according to the value of `order`.
|
| 62 |
+
|
| 63 |
+
*Returns:* Atomically returns the value pointed to by `object` or
|
| 64 |
+
`this`.
|
| 65 |
|
| 66 |
``` cpp
|
| 67 |
bool atomic_flag_test_and_set(volatile atomic_flag* object) noexcept;
|
| 68 |
bool atomic_flag_test_and_set(atomic_flag* object) noexcept;
|
| 69 |
bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object, memory_order order) noexcept;
|
| 70 |
bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept;
|
| 71 |
+
bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) volatile noexcept;
|
| 72 |
+
bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) noexcept;
|
| 73 |
```
|
| 74 |
|
| 75 |
*Effects:* Atomically sets the value pointed to by `object` or by `this`
|
| 76 |
to `true`. Memory is affected according to the value of `order`. These
|
| 77 |
operations are atomic read-modify-write
|
| 78 |
+
operations [[intro.multithread]].
|
| 79 |
|
| 80 |
*Returns:* Atomically, the value of the object immediately before the
|
| 81 |
effects.
|
| 82 |
|
| 83 |
``` cpp
|
| 84 |
void atomic_flag_clear(volatile atomic_flag* object) noexcept;
|
| 85 |
void atomic_flag_clear(atomic_flag* object) noexcept;
|
| 86 |
void atomic_flag_clear_explicit(volatile atomic_flag* object, memory_order order) noexcept;
|
| 87 |
void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept;
|
| 88 |
+
void atomic_flag::clear(memory_order order = memory_order::seq_cst) volatile noexcept;
|
| 89 |
+
void atomic_flag::clear(memory_order order = memory_order::seq_cst) noexcept;
|
| 90 |
```
|
| 91 |
|
| 92 |
+
*Preconditions:* The `order` argument is neither
|
| 93 |
+
`memory_order::consume`, `memory_order::acquire`, nor
|
| 94 |
+
`memory_order::acq_rel`.
|
| 95 |
|
| 96 |
*Effects:* Atomically sets the value pointed to by `object` or by `this`
|
| 97 |
to `false`. Memory is affected according to the value of `order`.
|
| 98 |
|
| 99 |
+
``` cpp
|
| 100 |
+
void atomic_flag_wait(const volatile atomic_flag* object, bool old) noexcept;
|
| 101 |
+
void atomic_flag_wait(const atomic_flag* object, bool old) noexcept;
|
| 102 |
+
void atomic_flag_wait_explicit(const volatile atomic_flag* object,
|
| 103 |
+
bool old, memory_order order) noexcept;
|
| 104 |
+
void atomic_flag_wait_explicit(const atomic_flag* object,
|
| 105 |
+
bool old, memory_order order) noexcept;
|
| 106 |
+
void atomic_flag::wait(bool old, memory_order order =
|
| 107 |
+
memory_order::seq_cst) const volatile noexcept;
|
| 108 |
+
void atomic_flag::wait(bool old, memory_order order =
|
| 109 |
+
memory_order::seq_cst) const noexcept;
|
| 110 |
+
```
|
| 111 |
+
|
| 112 |
+
For `atomic_flag_wait`, let `order` be `memory_order::seq_cst`. Let
|
| 113 |
+
`flag` be `object` for the non-member functions and `this` for the
|
| 114 |
+
member functions.
|
| 115 |
+
|
| 116 |
+
*Preconditions:* `order` is neither `memory_order::release` nor
|
| 117 |
+
`memory_order::acq_rel`.
|
| 118 |
+
|
| 119 |
+
*Effects:* Repeatedly performs the following steps, in order:
|
| 120 |
+
|
| 121 |
+
- Evaluates `flag->test(order) != old`.
|
| 122 |
+
- If the result of that evaluation is `true`, returns.
|
| 123 |
+
- Blocks until it is unblocked by an atomic notifying operation or is
|
| 124 |
+
unblocked spuriously.
|
| 125 |
+
|
| 126 |
+
*Remarks:* This function is an atomic waiting
|
| 127 |
+
operation [[atomics.wait]].
|
| 128 |
+
|
| 129 |
+
``` cpp
|
| 130 |
+
void atomic_flag_notify_one(volatile atomic_flag* object) noexcept;
|
| 131 |
+
void atomic_flag_notify_one(atomic_flag* object) noexcept;
|
| 132 |
+
void atomic_flag::notify_one() volatile noexcept;
|
| 133 |
+
void atomic_flag::notify_one() noexcept;
|
| 134 |
+
```
|
| 135 |
+
|
| 136 |
+
*Effects:* Unblocks the execution of at least one atomic waiting
|
| 137 |
+
operation that is eligible to be unblocked [[atomics.wait]] by this
|
| 138 |
+
call, if any such atomic waiting operations exist.
|
| 139 |
+
|
| 140 |
+
*Remarks:* This function is an atomic notifying
|
| 141 |
+
operation [[atomics.wait]].
|
| 142 |
+
|
| 143 |
+
``` cpp
|
| 144 |
+
void atomic_flag_notify_all(volatile atomic_flag* object) noexcept;
|
| 145 |
+
void atomic_flag_notify_all(atomic_flag* object) noexcept;
|
| 146 |
+
void atomic_flag::notify_all() volatile noexcept;
|
| 147 |
+
void atomic_flag::notify_all() noexcept;
|
| 148 |
+
```
|
| 149 |
+
|
| 150 |
+
*Effects:* Unblocks the execution of all atomic waiting operations that
|
| 151 |
+
are eligible to be unblocked [[atomics.wait]] by this call.
|
| 152 |
+
|
| 153 |
+
*Remarks:* This function is an atomic notifying
|
| 154 |
+
operation [[atomics.wait]].
|
| 155 |
+
|