tmp/tmp7e9lab8v/{from.md → to.md}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
-
### Forward progress <a id="intro.progress">[[intro.progress]]</a>
|
| 2 |
|
| 3 |
The implementation may assume that any thread will eventually do one of
|
| 4 |
the following:
|
| 5 |
|
| 6 |
- terminate,
|
|
@@ -10,17 +10,17 @@ the following:
|
|
| 10 |
|
| 11 |
[*Note 1*: This is intended to allow compiler transformations such as
|
| 12 |
removal of empty loops, even when termination cannot be
|
| 13 |
proven. — *end note*]
|
| 14 |
|
| 15 |
-
Executions of atomic functions that are either defined to be lock-free
|
| 16 |
-
[[atomics.flag]]
|
| 17 |
*lock-free executions*.
|
| 18 |
|
| 19 |
-
- If there is only one thread that is not blocked
|
| 20 |
-
|
| 21 |
-
|
| 22 |
progress of a lock-free execution. For example, this situation can
|
| 23 |
occur with load-locked store-conditional implementations. This
|
| 24 |
property is sometimes termed obstruction-free. — *end note*]
|
| 25 |
- When one or more lock-free executions run concurrently, at least one
|
| 26 |
should complete. \[*Note 3*: It is difficult for some implementations
|
|
@@ -40,13 +40,13 @@ termed an *execution step*:
|
|
| 40 |
- termination of the thread of execution,
|
| 41 |
- performing an access through a volatile glvalue, or
|
| 42 |
- completion of a call to a library I/O function, a synchronization
|
| 43 |
operation, or an atomic operation.
|
| 44 |
|
| 45 |
-
An invocation of a standard library function that blocks
|
| 46 |
-
|
| 47 |
-
|
| 48 |
|
| 49 |
[*Example 1*: A library I/O function that blocks until the I/O
|
| 50 |
operation is complete can be considered to continuously check whether
|
| 51 |
the operation is complete. Each such check might consist of one or more
|
| 52 |
execution steps, for example using observable behavior of the abstract
|
|
@@ -70,16 +70,17 @@ make progress for as long as it has not terminated.
|
|
| 70 |
of executions (if any) have been or are making progress. To eventually
|
| 71 |
fulfill this requirement means that this will happen in an unspecified
|
| 72 |
but finite amount of time. — *end note*]
|
| 73 |
|
| 74 |
It is *implementation-defined* whether the implementation-created thread
|
| 75 |
-
of execution that executes `main`
|
| 76 |
-
|
| 77 |
-
provide concurrent forward
|
|
|
|
| 78 |
|
| 79 |
-
[*Note 6*: General-purpose implementations
|
| 80 |
-
|
| 81 |
|
| 82 |
For a thread of execution providing *parallel forward progress
|
| 83 |
guarantees*, the implementation is not required to ensure that the
|
| 84 |
thread will eventually make progress if it has not yet executed any
|
| 85 |
execution step; once this thread has executed a step, it provides
|
|
@@ -111,38 +112,38 @@ parallel forward progress guarantees.
|
|
| 111 |
[*Note 9*: For example, some kinds of synchronization between threads
|
| 112 |
of execution may only make progress if the respective threads of
|
| 113 |
execution provide parallel forward progress guarantees, but will fail to
|
| 114 |
make progress under weakly parallel guarantees. — *end note*]
|
| 115 |
|
| 116 |
-
When a thread of execution
|
| 117 |
-
progress guarantee delegation* on the completion of a set
|
| 118 |
-
of execution, then throughout the whole time of
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
|
| 123 |
-
[*Note 10*: It is unspecified which thread or threads of execution in
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
of the
|
| 127 |
-
|
| 128 |
-
|
| 129 |
|
| 130 |
-
Once a thread of execution in
|
| 131 |
-
|
| 132 |
|
| 133 |
-
[*Note 11*: A thread of execution
|
| 134 |
effectively stronger forward progress guarantee for a certain amount of
|
| 135 |
-
time, due to a second thread of execution
|
| 136 |
-
forward progress guarantee delegation. In turn, if
|
| 137 |
-
forward progress guarantee delegation on
|
| 138 |
-
provide a stronger forward progress guarantee to
|
| 139 |
|
| 140 |
-
[*Note 12*: If all threads of execution in
|
| 141 |
they terminate and do not use blocking synchronization incorrectly),
|
| 142 |
-
then
|
| 143 |
-
guarantee delegation will not result in
|
| 144 |
effectively weakened. — *end note*]
|
| 145 |
|
| 146 |
[*Note 13*: This does not remove any constraints regarding blocking
|
| 147 |
synchronization for threads of execution providing parallel or weakly
|
| 148 |
parallel forward progress guarantees because the implementation is not
|
|
|
|
| 1 |
+
#### Forward progress <a id="intro.progress">[[intro.progress]]</a>
|
| 2 |
|
| 3 |
The implementation may assume that any thread will eventually do one of
|
| 4 |
the following:
|
| 5 |
|
| 6 |
- terminate,
|
|
|
|
| 10 |
|
| 11 |
[*Note 1*: This is intended to allow compiler transformations such as
|
| 12 |
removal of empty loops, even when termination cannot be
|
| 13 |
proven. — *end note*]
|
| 14 |
|
| 15 |
+
Executions of atomic functions that are either defined to be lock-free
|
| 16 |
+
[[atomics.flag]] or indicated as lock-free [[atomics.lockfree]] are
|
| 17 |
*lock-free executions*.
|
| 18 |
|
| 19 |
+
- If there is only one thread that is not blocked [[defns.block]] in a
|
| 20 |
+
standard library function, a lock-free execution in that thread shall
|
| 21 |
+
complete. \[*Note 2*: Concurrently executing threads may prevent
|
| 22 |
progress of a lock-free execution. For example, this situation can
|
| 23 |
occur with load-locked store-conditional implementations. This
|
| 24 |
property is sometimes termed obstruction-free. — *end note*]
|
| 25 |
- When one or more lock-free executions run concurrently, at least one
|
| 26 |
should complete. \[*Note 3*: It is difficult for some implementations
|
|
|
|
| 40 |
- termination of the thread of execution,
|
| 41 |
- performing an access through a volatile glvalue, or
|
| 42 |
- completion of a call to a library I/O function, a synchronization
|
| 43 |
operation, or an atomic operation.
|
| 44 |
|
| 45 |
+
An invocation of a standard library function that blocks [[defns.block]]
|
| 46 |
+
is considered to continuously execute execution steps while waiting for
|
| 47 |
+
the condition that it blocks on to be satisfied.
|
| 48 |
|
| 49 |
[*Example 1*: A library I/O function that blocks until the I/O
|
| 50 |
operation is complete can be considered to continuously check whether
|
| 51 |
the operation is complete. Each such check might consist of one or more
|
| 52 |
execution steps, for example using observable behavior of the abstract
|
|
|
|
| 70 |
of executions (if any) have been or are making progress. To eventually
|
| 71 |
fulfill this requirement means that this will happen in an unspecified
|
| 72 |
but finite amount of time. — *end note*]
|
| 73 |
|
| 74 |
It is *implementation-defined* whether the implementation-created thread
|
| 75 |
+
of execution that executes `main` [[basic.start.main]] and the threads
|
| 76 |
+
of execution created by `std::thread` [[thread.thread.class]] or
|
| 77 |
+
`std::jthread` [[thread.jthread.class]] provide concurrent forward
|
| 78 |
+
progress guarantees.
|
| 79 |
|
| 80 |
+
[*Note 6*: General-purpose implementations should provide these
|
| 81 |
+
guarantees. — *end note*]
|
| 82 |
|
| 83 |
For a thread of execution providing *parallel forward progress
|
| 84 |
guarantees*, the implementation is not required to ensure that the
|
| 85 |
thread will eventually make progress if it has not yet executed any
|
| 86 |
execution step; once this thread has executed a step, it provides
|
|
|
|
| 112 |
[*Note 9*: For example, some kinds of synchronization between threads
|
| 113 |
of execution may only make progress if the respective threads of
|
| 114 |
execution provide parallel forward progress guarantees, but will fail to
|
| 115 |
make progress under weakly parallel guarantees. — *end note*]
|
| 116 |
|
| 117 |
+
When a thread of execution P is specified to *block with forward
|
| 118 |
+
progress guarantee delegation* on the completion of a set S of threads
|
| 119 |
+
of execution, then throughout the whole time of P being blocked on S,
|
| 120 |
+
the implementation shall ensure that the forward progress guarantees
|
| 121 |
+
provided by at least one thread of execution in S is at least as strong
|
| 122 |
+
as P’s forward progress guarantees.
|
| 123 |
|
| 124 |
+
[*Note 10*: It is unspecified which thread or threads of execution in S
|
| 125 |
+
are chosen and for which number of execution steps. The strengthening is
|
| 126 |
+
not permanent and not necessarily in place for the rest of the lifetime
|
| 127 |
+
of the affected thread of execution. As long as P is blocked, the
|
| 128 |
+
implementation has to eventually select and potentially strengthen a
|
| 129 |
+
thread of execution in S. — *end note*]
|
| 130 |
|
| 131 |
+
Once a thread of execution in S terminates, it is removed from S. Once S
|
| 132 |
+
is empty, P is unblocked.
|
| 133 |
|
| 134 |
+
[*Note 11*: A thread of execution B thus can temporarily provide an
|
| 135 |
effectively stronger forward progress guarantee for a certain amount of
|
| 136 |
+
time, due to a second thread of execution A being blocked on it with
|
| 137 |
+
forward progress guarantee delegation. In turn, if B then blocks with
|
| 138 |
+
forward progress guarantee delegation on C, this may also temporarily
|
| 139 |
+
provide a stronger forward progress guarantee to C. — *end note*]
|
| 140 |
|
| 141 |
+
[*Note 12*: If all threads of execution in S finish executing (e.g.,
|
| 142 |
they terminate and do not use blocking synchronization incorrectly),
|
| 143 |
+
then P’s execution of the operation that blocks with forward progress
|
| 144 |
+
guarantee delegation will not result in P’s progress guarantee being
|
| 145 |
effectively weakened. — *end note*]
|
| 146 |
|
| 147 |
[*Note 13*: This does not remove any constraints regarding blocking
|
| 148 |
synchronization for threads of execution providing parallel or weakly
|
| 149 |
parallel forward progress guarantees because the implementation is not
|