- tmp/tmp_1sed6wx/{from.md → to.md} +89 -148
tmp/tmp_1sed6wx/{from.md → to.md}
RENAMED
|
@@ -9,12 +9,12 @@ subsequently executed by the thread.
|
|
| 9 |
|
| 10 |
[*Note 1*: When one thread creates another, the initial call to the
|
| 11 |
top-level function of the new thread is executed by the new thread, not
|
| 12 |
by the creating thread. — *end note*]
|
| 13 |
|
| 14 |
-
Every thread in a program can potentially
|
| 15 |
-
|
| 16 |
|
| 17 |
Under a hosted implementation, a C++ program can have more than one
|
| 18 |
thread running concurrently. The execution of each thread proceeds as
|
| 19 |
defined by the remainder of this document. The execution of the entire
|
| 20 |
program consists of an execution of all of its threads.
|
|
@@ -42,27 +42,37 @@ below.
|
|
| 42 |
Much of this subclause is motivated by the desire to support atomic
|
| 43 |
operations with explicit and detailed visibility constraints. However,
|
| 44 |
it also implicitly supports a simpler view for more restricted
|
| 45 |
programs. — *end note*]
|
| 46 |
|
| 47 |
-
Two expression evaluations *conflict* if one of them
|
| 48 |
-
|
| 49 |
-
memory location.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
The library defines a number of atomic operations [[atomics]] and
|
| 52 |
operations on mutexes [[thread]] that are specially identified as
|
| 53 |
synchronization operations. These operations play a special role in
|
| 54 |
making assignments in one thread visible to another. A synchronization
|
| 55 |
-
operation on one or more memory locations is either
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
|
| 63 |
-
[*Note
|
| 64 |
acquire operation on the locations comprising the mutex.
|
| 65 |
Correspondingly, a call that releases the same mutex will perform a
|
| 66 |
release operation on those same locations. Informally, performing a
|
| 67 |
release operation on A forces prior side effects on other memory
|
| 68 |
locations to become visible to other threads that later perform a
|
|
@@ -71,11 +81,11 @@ not synchronization operations even though, like synchronization
|
|
| 71 |
operations, they cannot contribute to data races. — *end note*]
|
| 72 |
|
| 73 |
All modifications to a particular atomic object M occur in some
|
| 74 |
particular total order, called the *modification order* of M.
|
| 75 |
|
| 76 |
-
[*Note
|
| 77 |
no requirement that these can be combined into a single total order for
|
| 78 |
all objects. In general this will be impossible since different threads
|
| 79 |
can observe modifications to different objects in inconsistent
|
| 80 |
orders. — *end note*]
|
| 81 |
|
|
@@ -87,181 +97,107 @@ subsequent operation is an atomic read-modify-write operation.
|
|
| 87 |
Certain library calls *synchronize with* other library calls performed
|
| 88 |
by another thread. For example, an atomic store-release synchronizes
|
| 89 |
with a load-acquire that takes its value from the store
|
| 90 |
[[atomics.order]].
|
| 91 |
|
| 92 |
-
[*Note
|
| 93 |
not necessarily ensure visibility as described below. Such a requirement
|
| 94 |
would sometimes interfere with efficient implementation. — *end note*]
|
| 95 |
|
| 96 |
-
[*Note
|
| 97 |
when one reads the value written by another. For atomic objects, the
|
| 98 |
definition is clear. All operations on a given mutex occur in a single
|
| 99 |
total order. Each mutex acquisition “reads the value written” by the
|
| 100 |
last mutex release. — *end note*]
|
| 101 |
|
| 102 |
-
An evaluation A *carries a dependency* to an evaluation B if
|
| 103 |
-
|
| 104 |
-
- the value of A is used as an operand of B, unless:
|
| 105 |
-
- B is an invocation of any specialization of `std::kill_dependency`
|
| 106 |
-
[[atomics.order]], or
|
| 107 |
-
- A is the left operand of a built-in logical (`&&`, see
|
| 108 |
-
[[expr.log.and]]) or logical (`||`, see [[expr.log.or]]) operator,
|
| 109 |
-
or
|
| 110 |
-
- A is the left operand of a conditional (`?:`, see [[expr.cond]])
|
| 111 |
-
operator, or
|
| 112 |
-
- A is the left operand of the built-in comma (`,`) operator
|
| 113 |
-
[[expr.comma]];
|
| 114 |
-
|
| 115 |
-
or
|
| 116 |
-
- A writes a scalar object or bit-field M, B reads the value written by
|
| 117 |
-
A from M, and A is sequenced before B, or
|
| 118 |
-
- for some evaluation X, A carries a dependency to X, and X carries a
|
| 119 |
-
dependency to B.
|
| 120 |
-
|
| 121 |
-
[*Note 6*: “Carries a dependency to” is a subset of “is sequenced
|
| 122 |
-
before”, and is similarly strictly intra-thread. — *end note*]
|
| 123 |
-
|
| 124 |
-
An evaluation A is *dependency-ordered before* an evaluation B if
|
| 125 |
-
|
| 126 |
-
- A performs a release operation on an atomic object M, and, in another
|
| 127 |
-
thread, B performs a consume operation on M and reads the value
|
| 128 |
-
written by A, or
|
| 129 |
-
- for some evaluation X, A is dependency-ordered before X and X carries
|
| 130 |
-
a dependency to B.
|
| 131 |
-
|
| 132 |
-
[*Note 7*: The relation “is dependency-ordered before” is analogous to
|
| 133 |
-
“synchronizes with”, but uses release/consume in place of
|
| 134 |
-
release/acquire. — *end note*]
|
| 135 |
-
|
| 136 |
-
An evaluation A *inter-thread happens before* an evaluation B if
|
| 137 |
-
|
| 138 |
-
- A synchronizes with B, or
|
| 139 |
-
- A is dependency-ordered before B, or
|
| 140 |
-
- for some evaluation X
|
| 141 |
-
- A synchronizes with X and X is sequenced before B, or
|
| 142 |
-
- A is sequenced before X and X inter-thread happens before B, or
|
| 143 |
-
- A inter-thread happens before X and X inter-thread happens before B.
|
| 144 |
-
|
| 145 |
-
[*Note 8*: The “inter-thread happens before” relation describes
|
| 146 |
-
arbitrary concatenations of “sequenced before”, “synchronizes with” and
|
| 147 |
-
“dependency-ordered before” relationships, with two exceptions. The
|
| 148 |
-
first exception is that a concatenation is not permitted to end with
|
| 149 |
-
“dependency-ordered before” followed by “sequenced before”. The reason
|
| 150 |
-
for this limitation is that a consume operation participating in a
|
| 151 |
-
“dependency-ordered before” relationship provides ordering only with
|
| 152 |
-
respect to operations to which this consume operation actually carries a
|
| 153 |
-
dependency. The reason that this limitation applies only to the end of
|
| 154 |
-
such a concatenation is that any subsequent release operation will
|
| 155 |
-
provide the required ordering for a prior consume operation. The second
|
| 156 |
-
exception is that a concatenation is not permitted to consist entirely
|
| 157 |
-
of “sequenced before”. The reasons for this limitation are (1) to permit
|
| 158 |
-
“inter-thread happens before” to be transitively closed and (2) the
|
| 159 |
-
“happens before” relation, defined below, provides for relationships
|
| 160 |
-
consisting entirely of “sequenced before”. — *end note*]
|
| 161 |
-
|
| 162 |
An evaluation A *happens before* an evaluation B (or, equivalently, B
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
- A is sequenced before B, or
|
| 166 |
-
- A inter-thread happens before B.
|
| 167 |
-
|
| 168 |
-
The implementation shall ensure that no program execution demonstrates a
|
| 169 |
-
cycle in the “happens before” relation.
|
| 170 |
-
|
| 171 |
-
[*Note 9*: This cycle would otherwise be possible only through the use
|
| 172 |
-
of consume operations. — *end note*]
|
| 173 |
-
|
| 174 |
-
An evaluation A *simply happens before* an evaluation B if either
|
| 175 |
|
| 176 |
- A is sequenced before B, or
|
| 177 |
- A synchronizes with B, or
|
| 178 |
-
- A
|
| 179 |
|
| 180 |
-
[*Note
|
| 181 |
-
and simply happens before relations are identical. — *end note*]
|
| 182 |
|
| 183 |
An evaluation A *strongly happens before* an evaluation D if, either
|
| 184 |
|
| 185 |
- A is sequenced before D, or
|
| 186 |
- A synchronizes with D, and both A and D are sequentially consistent
|
| 187 |
atomic operations [[atomics.order]], or
|
| 188 |
- there are evaluations B and C such that A is sequenced before B, B
|
| 189 |
-
|
| 190 |
- there is an evaluation B such that A strongly happens before B, and B
|
| 191 |
strongly happens before D.
|
| 192 |
|
| 193 |
-
[*Note
|
| 194 |
-
to be evaluated before B in all contexts.
|
| 195 |
-
excludes consume operations. — *end note*]
|
| 196 |
|
| 197 |
A *visible side effect* A on a scalar object or bit-field M with respect
|
| 198 |
to a value computation B of M satisfies the conditions:
|
| 199 |
|
| 200 |
- A happens before B and
|
| 201 |
- there is no other side effect X to M such that A happens before X and
|
| 202 |
X happens before B.
|
| 203 |
|
| 204 |
The value of a non-atomic scalar object or bit-field M, as determined by
|
| 205 |
-
evaluation B,
|
| 206 |
|
| 207 |
-
[*Note
|
| 208 |
non-atomic object or bit-field is visible, then the behavior is either
|
| 209 |
unspecified or undefined. — *end note*]
|
| 210 |
|
| 211 |
-
[*Note
|
| 212 |
visibly reordered. This is not actually detectable without data races,
|
| 213 |
-
but
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
execution. — *end note*]
|
| 217 |
|
| 218 |
-
The value of an atomic object M, as determined by evaluation B,
|
| 219 |
-
|
| 220 |
-
happen before A.
|
| 221 |
|
| 222 |
-
[*Note
|
| 223 |
of the rules described here, and in particular, by the coherence
|
| 224 |
requirements below. — *end note*]
|
| 225 |
|
| 226 |
If an operation A that modifies an atomic object M happens before an
|
| 227 |
-
operation B that modifies M, then A
|
| 228 |
modification order of M.
|
| 229 |
|
| 230 |
-
[*Note
|
| 231 |
coherence. — *end note*]
|
| 232 |
|
| 233 |
If a value computation A of an atomic object M happens before a value
|
| 234 |
computation B of M, and A takes its value from a side effect X on M,
|
| 235 |
-
then the value computed by B
|
| 236 |
-
|
| 237 |
modification order of M.
|
| 238 |
|
| 239 |
-
[*Note
|
| 240 |
coherence. — *end note*]
|
| 241 |
|
| 242 |
If a value computation A of an atomic object M happens before an
|
| 243 |
-
operation B that modifies M, then A
|
| 244 |
-
|
| 245 |
|
| 246 |
-
[*Note
|
| 247 |
coherence. — *end note*]
|
| 248 |
|
| 249 |
If a side effect X on an atomic object M happens before a value
|
| 250 |
-
computation B of M, then the evaluation B
|
| 251 |
-
|
| 252 |
|
| 253 |
-
[*Note
|
| 254 |
coherence. — *end note*]
|
| 255 |
|
| 256 |
-
[*Note
|
| 257 |
disallow compiler reordering of atomic operations to a single object,
|
| 258 |
even if both operations are relaxed loads. This effectively makes the
|
| 259 |
cache coherence guarantee provided by most hardware available to C++
|
| 260 |
atomic operations. — *end note*]
|
| 261 |
|
| 262 |
-
[*Note
|
| 263 |
“happens before” relation, which depends on the values observed by loads
|
| 264 |
of atomics. The intended reading is that there must exist an association
|
| 265 |
of atomic loads with modifications they observe that, together with
|
| 266 |
suitably chosen modification orders and the “happens before” relation
|
| 267 |
derived as described above, satisfy the resulting constraints as imposed
|
|
@@ -277,67 +213,71 @@ The execution of a program contains a *data race* if it contains two
|
|
| 277 |
potentially concurrent conflicting actions, at least one of which is not
|
| 278 |
atomic, and neither happens before the other, except for the special
|
| 279 |
case for signal handlers described below. Any such data race results in
|
| 280 |
undefined behavior.
|
| 281 |
|
| 282 |
-
[*Note
|
| 283 |
and `memory_order::seq_cst` operations to prevent all data races and use
|
| 284 |
no other synchronization operations behave as if the operations executed
|
| 285 |
by their constituent threads were simply interleaved, with each value
|
| 286 |
computation of an object being taken from the last side effect on that
|
| 287 |
object in that interleaving. This is normally referred to as “sequential
|
| 288 |
consistency”. However, this applies only to data-race-free programs, and
|
| 289 |
data-race-free programs cannot observe most program transformations that
|
| 290 |
do not change single-threaded program semantics. In fact, most
|
| 291 |
-
single-threaded program transformations
|
| 292 |
-
|
| 293 |
behavior. — *end note*]
|
| 294 |
|
| 295 |
-
Two accesses to the same object of type
|
| 296 |
-
not result in a data race if both occur
|
| 297 |
-
or more occurs in a signal handler. For
|
| 298 |
-
evaluations performed by the thread
|
| 299 |
-
divided into two groups A and B, such
|
| 300 |
-
before evaluations in A, and the
|
| 301 |
-
`volatile std::sig_atomic_t` objects take values as
|
| 302 |
-
evaluations in A happened before the execution of the signal
|
| 303 |
-
the execution of the signal handler happened before all
|
| 304 |
-
B.
|
| 305 |
|
| 306 |
-
[*Note
|
| 307 |
potentially shared memory location that would not be modified by the
|
| 308 |
abstract machine are generally precluded by this document, since such an
|
| 309 |
assignment might overwrite another assignment by a different thread in
|
| 310 |
cases in which an abstract machine execution would not have encountered
|
| 311 |
a data race. This includes implementations of data member assignment
|
| 312 |
that overwrite adjacent members in separate memory locations. Reordering
|
| 313 |
of atomic loads in cases in which the atomics in question might alias is
|
| 314 |
also generally precluded, since this could violate the coherence
|
| 315 |
rules. — *end note*]
|
| 316 |
|
| 317 |
-
[*Note
|
| 318 |
-
potentially shared memory location
|
| 319 |
-
the C++ program as defined in this document, since they
|
| 320 |
-
introduce a data race. However, they are typically valid in
|
| 321 |
-
of an optimizing compiler that targets a specific machine
|
| 322 |
-
well-defined semantics for data races. They would be invalid for a
|
| 323 |
hypothetical machine that is not tolerant of races or provides hardware
|
| 324 |
race detection. — *end note*]
|
| 325 |
|
| 326 |
#### Forward progress <a id="intro.progress">[[intro.progress]]</a>
|
| 327 |
|
| 328 |
The implementation may assume that any thread will eventually do one of
|
| 329 |
the following:
|
| 330 |
|
| 331 |
- terminate,
|
|
|
|
| 332 |
- make a call to a library I/O function,
|
| 333 |
-
- perform an access through a volatile glvalue,
|
| 334 |
-
- perform
|
|
|
|
|
|
|
| 335 |
|
| 336 |
[*Note 1*: This is intended to allow compiler transformations such as
|
| 337 |
-
removal of empty loops, even when termination
|
| 338 |
-
proven.
|
|
|
|
| 339 |
|
| 340 |
Executions of atomic functions that are either defined to be lock-free
|
| 341 |
[[atomics.flag]] or indicated as lock-free [[atomics.lockfree]] are
|
| 342 |
*lock-free executions*.
|
| 343 |
|
|
@@ -361,13 +301,14 @@ Executions of atomic functions that are either defined to be lock-free
|
|
| 361 |
|
| 362 |
During the execution of a thread of execution, each of the following is
|
| 363 |
termed an *execution step*:
|
| 364 |
|
| 365 |
- termination of the thread of execution,
|
| 366 |
-
- performing an access through a volatile glvalue,
|
| 367 |
-
- completion of a call to a library I/O function,
|
| 368 |
-
|
|
|
|
| 369 |
|
| 370 |
An invocation of a standard library function that blocks [[defns.block]]
|
| 371 |
is considered to continuously execute execution steps while waiting for
|
| 372 |
the condition that it blocks on to be satisfied.
|
| 373 |
|
|
@@ -389,12 +330,12 @@ concurrent threads that are not blocked in a standard library function
|
|
| 389 |
|
| 390 |
For a thread of execution providing *concurrent forward progress
|
| 391 |
guarantees*, the implementation ensures that the thread will eventually
|
| 392 |
make progress for as long as it has not terminated.
|
| 393 |
|
| 394 |
-
[*Note 5*: This
|
| 395 |
-
|
| 396 |
fulfill this requirement means that this will happen in an unspecified
|
| 397 |
but finite amount of time. — *end note*]
|
| 398 |
|
| 399 |
It is *implementation-defined* whether the implementation-created thread
|
| 400 |
of execution that executes `main` [[basic.start.main]] and the threads
|
|
|
|
| 9 |
|
| 10 |
[*Note 1*: When one thread creates another, the initial call to the
|
| 11 |
top-level function of the new thread is executed by the new thread, not
|
| 12 |
by the creating thread. — *end note*]
|
| 13 |
|
| 14 |
+
Every thread in a program can potentially use every object and function
|
| 15 |
+
in a program.[^23]
|
| 16 |
|
| 17 |
Under a hosted implementation, a C++ program can have more than one
|
| 18 |
thread running concurrently. The execution of each thread proceeds as
|
| 19 |
defined by the remainder of this document. The execution of the entire
|
| 20 |
program consists of an execution of all of its threads.
|
|
|
|
| 42 |
Much of this subclause is motivated by the desire to support atomic
|
| 43 |
operations with explicit and detailed visibility constraints. However,
|
| 44 |
it also implicitly supports a simpler view for more restricted
|
| 45 |
programs. — *end note*]
|
| 46 |
|
| 47 |
+
Two expression evaluations *conflict* if one of them
|
| 48 |
+
|
| 49 |
+
- modifies [[defns.access]] a memory location [[intro.memory]] or
|
| 50 |
+
- starts or ends the lifetime of an object in a memory location
|
| 51 |
+
|
| 52 |
+
and the other one
|
| 53 |
+
|
| 54 |
+
- reads or modifies the same memory location or
|
| 55 |
+
- starts or ends the lifetime of an object occupying storage that
|
| 56 |
+
overlaps with the memory location.
|
| 57 |
+
|
| 58 |
+
[*Note 2*: A modification can still conflict even if it does not alter
|
| 59 |
+
the value of any bits. — *end note*]
|
| 60 |
|
| 61 |
The library defines a number of atomic operations [[atomics]] and
|
| 62 |
operations on mutexes [[thread]] that are specially identified as
|
| 63 |
synchronization operations. These operations play a special role in
|
| 64 |
making assignments in one thread visible to another. A synchronization
|
| 65 |
+
operation on one or more memory locations is either an acquire
|
| 66 |
+
operation, a release operation, or both an acquire and release
|
| 67 |
+
operation. A synchronization operation without an associated memory
|
| 68 |
+
location is a fence and can be either an acquire fence, a release fence,
|
| 69 |
+
or both an acquire and release fence. In addition, there are relaxed
|
| 70 |
+
atomic operations, which are not synchronization operations, and atomic
|
| 71 |
+
read-modify-write operations, which have special characteristics.
|
| 72 |
|
| 73 |
+
[*Note 3*: For example, a call that acquires a mutex will perform an
|
| 74 |
acquire operation on the locations comprising the mutex.
|
| 75 |
Correspondingly, a call that releases the same mutex will perform a
|
| 76 |
release operation on those same locations. Informally, performing a
|
| 77 |
release operation on A forces prior side effects on other memory
|
| 78 |
locations to become visible to other threads that later perform a
|
|
|
|
| 81 |
operations, they cannot contribute to data races. — *end note*]
|
| 82 |
|
| 83 |
All modifications to a particular atomic object M occur in some
|
| 84 |
particular total order, called the *modification order* of M.
|
| 85 |
|
| 86 |
+
[*Note 4*: There is a separate order for each atomic object. There is
|
| 87 |
no requirement that these can be combined into a single total order for
|
| 88 |
all objects. In general this will be impossible since different threads
|
| 89 |
can observe modifications to different objects in inconsistent
|
| 90 |
orders. — *end note*]
|
| 91 |
|
|
|
|
| 97 |
Certain library calls *synchronize with* other library calls performed
|
| 98 |
by another thread. For example, an atomic store-release synchronizes
|
| 99 |
with a load-acquire that takes its value from the store
|
| 100 |
[[atomics.order]].
|
| 101 |
|
| 102 |
+
[*Note 5*: Except in the specified cases, reading a later value does
|
| 103 |
not necessarily ensure visibility as described below. Such a requirement
|
| 104 |
would sometimes interfere with efficient implementation. — *end note*]
|
| 105 |
|
| 106 |
+
[*Note 6*: The specifications of the synchronization operations define
|
| 107 |
when one reads the value written by another. For atomic objects, the
|
| 108 |
definition is clear. All operations on a given mutex occur in a single
|
| 109 |
total order. Each mutex acquisition “reads the value written” by the
|
| 110 |
last mutex release. — *end note*]
|
| 111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
An evaluation A *happens before* an evaluation B (or, equivalently, B
|
| 113 |
+
happens after A) if either
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
|
| 115 |
- A is sequenced before B, or
|
| 116 |
- A synchronizes with B, or
|
| 117 |
+
- A happens before X and X happens before B.
|
| 118 |
|
| 119 |
+
[*Note 7*: An evaluation does not happen before itself. — *end note*]
|
|
|
|
| 120 |
|
| 121 |
An evaluation A *strongly happens before* an evaluation D if, either
|
| 122 |
|
| 123 |
- A is sequenced before D, or
|
| 124 |
- A synchronizes with D, and both A and D are sequentially consistent
|
| 125 |
atomic operations [[atomics.order]], or
|
| 126 |
- there are evaluations B and C such that A is sequenced before B, B
|
| 127 |
+
happens before C, and C is sequenced before D, or
|
| 128 |
- there is an evaluation B such that A strongly happens before B, and B
|
| 129 |
strongly happens before D.
|
| 130 |
|
| 131 |
+
[*Note 8*: Informally, if A strongly happens before B, then A appears
|
| 132 |
+
to be evaluated before B in all contexts. — *end note*]
|
|
|
|
| 133 |
|
| 134 |
A *visible side effect* A on a scalar object or bit-field M with respect
|
| 135 |
to a value computation B of M satisfies the conditions:
|
| 136 |
|
| 137 |
- A happens before B and
|
| 138 |
- there is no other side effect X to M such that A happens before X and
|
| 139 |
X happens before B.
|
| 140 |
|
| 141 |
The value of a non-atomic scalar object or bit-field M, as determined by
|
| 142 |
+
evaluation B, is the value stored by the visible side effect A.
|
| 143 |
|
| 144 |
+
[*Note 9*: If there is ambiguity about which side effect to a
|
| 145 |
non-atomic object or bit-field is visible, then the behavior is either
|
| 146 |
unspecified or undefined. — *end note*]
|
| 147 |
|
| 148 |
+
[*Note 10*: This states that operations on ordinary objects are not
|
| 149 |
visibly reordered. This is not actually detectable without data races,
|
| 150 |
+
but is needed to ensure that data races, as defined below, and with
|
| 151 |
+
suitable restrictions on the use of atomics, correspond to data races in
|
| 152 |
+
a simple interleaved (sequentially consistent) execution. — *end note*]
|
|
|
|
| 153 |
|
| 154 |
+
The value of an atomic object M, as determined by evaluation B, is the
|
| 155 |
+
value stored by some unspecified side effect A that modifies M, where B
|
| 156 |
+
does not happen before A.
|
| 157 |
|
| 158 |
+
[*Note 11*: The set of such side effects is also restricted by the rest
|
| 159 |
of the rules described here, and in particular, by the coherence
|
| 160 |
requirements below. — *end note*]
|
| 161 |
|
| 162 |
If an operation A that modifies an atomic object M happens before an
|
| 163 |
+
operation B that modifies M, then A is earlier than B in the
|
| 164 |
modification order of M.
|
| 165 |
|
| 166 |
+
[*Note 12*: This requirement is known as write-write
|
| 167 |
coherence. — *end note*]
|
| 168 |
|
| 169 |
If a value computation A of an atomic object M happens before a value
|
| 170 |
computation B of M, and A takes its value from a side effect X on M,
|
| 171 |
+
then the value computed by B is either the value stored by X or the
|
| 172 |
+
value stored by a side effect Y on M, where Y follows X in the
|
| 173 |
modification order of M.
|
| 174 |
|
| 175 |
+
[*Note 13*: This requirement is known as read-read
|
| 176 |
coherence. — *end note*]
|
| 177 |
|
| 178 |
If a value computation A of an atomic object M happens before an
|
| 179 |
+
operation B that modifies M, then A takes its value from a side effect X
|
| 180 |
+
on M, where X precedes B in the modification order of M.
|
| 181 |
|
| 182 |
+
[*Note 14*: This requirement is known as read-write
|
| 183 |
coherence. — *end note*]
|
| 184 |
|
| 185 |
If a side effect X on an atomic object M happens before a value
|
| 186 |
+
computation B of M, then the evaluation B takes its value from X or from
|
| 187 |
+
a side effect Y that follows X in the modification order of M.
|
| 188 |
|
| 189 |
+
[*Note 15*: This requirement is known as write-read
|
| 190 |
coherence. — *end note*]
|
| 191 |
|
| 192 |
+
[*Note 16*: The four preceding coherence requirements effectively
|
| 193 |
disallow compiler reordering of atomic operations to a single object,
|
| 194 |
even if both operations are relaxed loads. This effectively makes the
|
| 195 |
cache coherence guarantee provided by most hardware available to C++
|
| 196 |
atomic operations. — *end note*]
|
| 197 |
|
| 198 |
+
[*Note 17*: The value observed by a load of an atomic depends on the
|
| 199 |
“happens before” relation, which depends on the values observed by loads
|
| 200 |
of atomics. The intended reading is that there must exist an association
|
| 201 |
of atomic loads with modifications they observe that, together with
|
| 202 |
suitably chosen modification orders and the “happens before” relation
|
| 203 |
derived as described above, satisfy the resulting constraints as imposed
|
|
|
|
| 213 |
potentially concurrent conflicting actions, at least one of which is not
|
| 214 |
atomic, and neither happens before the other, except for the special
|
| 215 |
case for signal handlers described below. Any such data race results in
|
| 216 |
undefined behavior.
|
| 217 |
|
| 218 |
+
[*Note 18*: It can be shown that programs that correctly use mutexes
|
| 219 |
and `memory_order::seq_cst` operations to prevent all data races and use
|
| 220 |
no other synchronization operations behave as if the operations executed
|
| 221 |
by their constituent threads were simply interleaved, with each value
|
| 222 |
computation of an object being taken from the last side effect on that
|
| 223 |
object in that interleaving. This is normally referred to as “sequential
|
| 224 |
consistency”. However, this applies only to data-race-free programs, and
|
| 225 |
data-race-free programs cannot observe most program transformations that
|
| 226 |
do not change single-threaded program semantics. In fact, most
|
| 227 |
+
single-threaded program transformations remain possible, since any
|
| 228 |
+
program that behaves differently as a result has undefined
|
| 229 |
behavior. — *end note*]
|
| 230 |
|
| 231 |
+
Two accesses to the same non-bit-field object of type
|
| 232 |
+
`volatile std::sig_atomic_t` do not result in a data race if both occur
|
| 233 |
+
in the same thread, even if one or more occurs in a signal handler. For
|
| 234 |
+
each signal handler invocation, evaluations performed by the thread
|
| 235 |
+
invoking a signal handler can be divided into two groups A and B, such
|
| 236 |
+
that no evaluations in B happen before evaluations in A, and the
|
| 237 |
+
evaluations of such `volatile std::sig_atomic_t` objects take values as
|
| 238 |
+
though all evaluations in A happened before the execution of the signal
|
| 239 |
+
handler and the execution of the signal handler happened before all
|
| 240 |
+
evaluations in B.
|
| 241 |
|
| 242 |
+
[*Note 19*: Compiler transformations that introduce assignments to a
|
| 243 |
potentially shared memory location that would not be modified by the
|
| 244 |
abstract machine are generally precluded by this document, since such an
|
| 245 |
assignment might overwrite another assignment by a different thread in
|
| 246 |
cases in which an abstract machine execution would not have encountered
|
| 247 |
a data race. This includes implementations of data member assignment
|
| 248 |
that overwrite adjacent members in separate memory locations. Reordering
|
| 249 |
of atomic loads in cases in which the atomics in question might alias is
|
| 250 |
also generally precluded, since this could violate the coherence
|
| 251 |
rules. — *end note*]
|
| 252 |
|
| 253 |
+
[*Note 20*: It is possible that transformations that introduce a
|
| 254 |
+
speculative read of a potentially shared memory location do not preserve
|
| 255 |
+
the semantics of the C++ program as defined in this document, since they
|
| 256 |
+
potentially introduce a data race. However, they are typically valid in
|
| 257 |
+
the context of an optimizing compiler that targets a specific machine
|
| 258 |
+
with well-defined semantics for data races. They would be invalid for a
|
| 259 |
hypothetical machine that is not tolerant of races or provides hardware
|
| 260 |
race detection. — *end note*]
|
| 261 |
|
| 262 |
#### Forward progress <a id="intro.progress">[[intro.progress]]</a>
|
| 263 |
|
| 264 |
The implementation may assume that any thread will eventually do one of
|
| 265 |
the following:
|
| 266 |
|
| 267 |
- terminate,
|
| 268 |
+
- invoke the function `std::this_thread::yield` [[thread.thread.this]],
|
| 269 |
- make a call to a library I/O function,
|
| 270 |
+
- perform an access through a volatile glvalue,
|
| 271 |
+
- perform an atomic or synchronization operation other than an atomic
|
| 272 |
+
modify-write operation [[atomics.order]], or
|
| 273 |
+
- continue execution of a trivial infinite loop [[stmt.iter.general]].
|
| 274 |
|
| 275 |
[*Note 1*: This is intended to allow compiler transformations such as
|
| 276 |
+
removal, merging, and reordering of empty loops, even when termination
|
| 277 |
+
cannot be proven. An affordance is made for trivial infinite loops,
|
| 278 |
+
which cannot be removed nor reordered. — *end note*]
|
| 279 |
|
| 280 |
Executions of atomic functions that are either defined to be lock-free
|
| 281 |
[[atomics.flag]] or indicated as lock-free [[atomics.lockfree]] are
|
| 282 |
*lock-free executions*.
|
| 283 |
|
|
|
|
| 301 |
|
| 302 |
During the execution of a thread of execution, each of the following is
|
| 303 |
termed an *execution step*:
|
| 304 |
|
| 305 |
- termination of the thread of execution,
|
| 306 |
+
- performing an access through a volatile glvalue,
|
| 307 |
+
- completion of a call to a library I/O function, or
|
| 308 |
+
- completion of an atomic or synchronization operation other than an
|
| 309 |
+
atomic modify-write operation [[atomics.order]].
|
| 310 |
|
| 311 |
An invocation of a standard library function that blocks [[defns.block]]
|
| 312 |
is considered to continuously execute execution steps while waiting for
|
| 313 |
the condition that it blocks on to be satisfied.
|
| 314 |
|
|
|
|
| 330 |
|
| 331 |
For a thread of execution providing *concurrent forward progress
|
| 332 |
guarantees*, the implementation ensures that the thread will eventually
|
| 333 |
make progress for as long as it has not terminated.
|
| 334 |
|
| 335 |
+
[*Note 5*: This applies regardless of whether or not other threads of
|
| 336 |
+
execution (if any) have been or are making progress. To eventually
|
| 337 |
fulfill this requirement means that this will happen in an unspecified
|
| 338 |
but finite amount of time. — *end note*]
|
| 339 |
|
| 340 |
It is *implementation-defined* whether the implementation-created thread
|
| 341 |
of execution that executes `main` [[basic.start.main]] and the threads
|