From Jason Turner

[thread.coord]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpdhoornq7/{from.md → to.md} +325 -0
tmp/tmpdhoornq7/{from.md → to.md} RENAMED
@@ -0,0 +1,325 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Coordination types <a id="thread.coord">[[thread.coord]]</a>
2
+
3
+ This subclause describes various concepts related to thread
4
+ coordination, and defines the coordination types `latch` and `barrier`.
5
+ These types facilitate concurrent computation performed by a number of
6
+ threads.
7
+
8
+ ### Latches <a id="thread.latch">[[thread.latch]]</a>
9
+
10
+ A latch is a thread coordination mechanism that allows any number of
11
+ threads to block until an expected number of threads arrive at the latch
12
+ (via the `count_down` function). The expected count is set when the
13
+ latch is created. An individual latch is a single-use object; once the
14
+ expected count has been reached, the latch cannot be reused.
15
+
16
+ #### Header `<latch>` synopsis <a id="latch.syn">[[latch.syn]]</a>
17
+
18
+ ``` cpp
19
+ namespace std {
20
+ class latch;
21
+ }
22
+ ```
23
+
24
+ #### Class `latch` <a id="thread.latch.class">[[thread.latch.class]]</a>
25
+
26
+ ``` cpp
27
+ namespace std {
28
+ class latch {
29
+ public:
30
+ static constexpr ptrdiff_t max() noexcept;
31
+
32
+ constexpr explicit latch(ptrdiff_t expected);
33
+ ~latch();
34
+
35
+ latch(const latch&) = delete;
36
+ latch& operator=(const latch&) = delete;
37
+
38
+ void count_down(ptrdiff_t update = 1);
39
+ bool try_wait() const noexcept;
40
+ void wait() const;
41
+ void arrive_and_wait(ptrdiff_t update = 1);
42
+
43
+ private:
44
+ ptrdiff_t counter; // exposition only
45
+ };
46
+ }
47
+ ```
48
+
49
+ A `latch` maintains an internal counter that is initialized when the
50
+ latch is created. Threads can block on the latch object, waiting for
51
+ counter to be decremented to zero.
52
+
53
+ Concurrent invocations of the member functions of `latch`, other than
54
+ its destructor, do not introduce data races.
55
+
56
+ ``` cpp
57
+ static constexpr ptrdiff_t max() noexcept;
58
+ ```
59
+
60
+ *Returns:* The maximum value of `counter` that the implementation
61
+ supports.
62
+
63
+ ``` cpp
64
+ constexpr explicit latch(ptrdiff_t expected);
65
+ ```
66
+
67
+ *Preconditions:* `expected >= 0` is `true` and `expected <= max()` is
68
+ `true`.
69
+
70
+ *Effects:* Initializes `counter` with `expected`.
71
+
72
+ *Throws:* Nothing.
73
+
74
+ ``` cpp
75
+ void count_down(ptrdiff_t update = 1);
76
+ ```
77
+
78
+ *Preconditions:* `update >= 0` is `true`, and `update <= counter` is
79
+ `true`.
80
+
81
+ *Effects:* Atomically decrements `counter` by `update`. If `counter` is
82
+ equal to zero, unblocks all threads blocked on `*this`.
83
+
84
+ *Synchronization:* Strongly happens before the returns from all calls
85
+ that are unblocked.
86
+
87
+ *Throws:* `system_error` when an exception is
88
+ required [[thread.req.exception]].
89
+
90
+ *Error conditions:* Any of the error conditions allowed for mutex
91
+ types [[thread.mutex.requirements.mutex]].
92
+
93
+ ``` cpp
94
+ bool try_wait() const noexcept;
95
+ ```
96
+
97
+ *Returns:* With very low probability `false`. Otherwise `counter == 0`.
98
+
99
+ ``` cpp
100
+ void wait() const;
101
+ ```
102
+
103
+ *Effects:* If `counter` equals zero, returns immediately. Otherwise,
104
+ blocks on `*this` until a call to `count_down` that decrements `counter`
105
+ to zero.
106
+
107
+ *Throws:* `system_error` when an exception is
108
+ required [[thread.req.exception]].
109
+
110
+ *Error conditions:* Any of the error conditions allowed for mutex
111
+ types [[thread.mutex.requirements.mutex]].
112
+
113
+ ``` cpp
114
+ void arrive_and_wait(ptrdiff_t update = 1);
115
+ ```
116
+
117
+ *Effects:* Equivalent to:
118
+
119
+ ``` cpp
120
+ count_down(update);
121
+ wait();
122
+ ```
123
+
124
+ ### Barriers <a id="thread.barrier">[[thread.barrier]]</a>
125
+
126
+ A barrier is a thread coordination mechanism whose lifetime consists of
127
+ a sequence of barrier phases, where each phase allows at most an
128
+ expected number of threads to block until the expected number of threads
129
+ arrive at the barrier.
130
+
131
+ [*Note 1*: A barrier is useful for managing repeated tasks that are
132
+ handled by multiple threads. — *end note*]
133
+
134
+ #### Header `<barrier>` synopsis <a id="barrier.syn">[[barrier.syn]]</a>
135
+
136
+ ``` cpp
137
+ namespace std {
138
+ template<class CompletionFunction = see below>
139
+ class barrier;
140
+ }
141
+ ```
142
+
143
+ #### Class template `barrier` <a id="thread.barrier.class">[[thread.barrier.class]]</a>
144
+
145
+ ``` cpp
146
+ namespace std {
147
+ template<class CompletionFunction = see below>
148
+ class barrier {
149
+ public:
150
+ using arrival_token = see below;
151
+
152
+ static constexpr ptrdiff_t max() noexcept;
153
+
154
+ constexpr explicit barrier(ptrdiff_t expected,
155
+ CompletionFunction f = CompletionFunction());
156
+ ~barrier();
157
+
158
+ barrier(const barrier&) = delete;
159
+ barrier& operator=(const barrier&) = delete;
160
+
161
+ [[nodiscard]] arrival_token arrive(ptrdiff_t update = 1);
162
+ void wait(arrival_token&& arrival) const;
163
+
164
+ void arrive_and_wait();
165
+ void arrive_and_drop();
166
+
167
+ private:
168
+ CompletionFunction completion; // exposition only
169
+ };
170
+ }
171
+ ```
172
+
173
+ Each *barrier phase* consists of the following steps:
174
+
175
+ - The expected count is decremented by each call to `arrive` or
176
+ `arrive_and_drop`.
177
+ - When the expected count reaches zero, the phase completion step is
178
+ run. For the specialization with the default value of the
179
+ `CompletionFunction` template parameter, the completion step is run as
180
+ part of the call to `arrive` or `arrive_and_drop` that caused the
181
+ expected count to reach zero. For other specializations, the
182
+ completion step is run on one of the threads that arrived at the
183
+ barrier during the phase.
184
+ - When the completion step finishes, the expected count is reset to what
185
+ was specified by the `expected` argument to the constructor, possibly
186
+ adjusted by calls to `arrive_and_drop`, and the next phase starts.
187
+
188
+ Each phase defines a *phase synchronization point*. Threads that arrive
189
+ at the barrier during the phase can block on the phase synchronization
190
+ point by calling `wait`, and will remain blocked until the phase
191
+ completion step is run.
192
+
193
+ The *phase completion step* that is executed at the end of each phase
194
+ has the following effects:
195
+
196
+ - Invokes the completion function, equivalent to `completion()`.
197
+ - Unblocks all threads that are blocked on the phase synchronization
198
+ point.
199
+
200
+ The end of the completion step strongly happens before the returns from
201
+ all calls that were unblocked by the completion step. For
202
+ specializations that do not have the default value of the
203
+ `CompletionFunction` template parameter, the behavior is undefined if
204
+ any of the barrier object’s member functions other than `wait` are
205
+ called while the completion step is in progress.
206
+
207
+ Concurrent invocations of the member functions of `barrier`, other than
208
+ its destructor, do not introduce data races. The member functions
209
+ `arrive` and `arrive_and_drop` execute atomically.
210
+
211
+ `CompletionFunction` shall meet the *Cpp17MoveConstructible* (
212
+ [[cpp17.moveconstructible]]) and *Cpp17Destructible* (
213
+ [[cpp17.destructible]]) requirements.
214
+ `is_nothrow_invocable_v<CompletionFunction&>` shall be `true`.
215
+
216
+ The default value of the `CompletionFunction` template parameter is an
217
+ unspecified type, such that, in addition to satisfying the requirements
218
+ of `CompletionFunction`, it meets the *Cpp17DefaultConstructible*
219
+ requirements ([[cpp17.defaultconstructible]]) and `completion()` has no
220
+ effects.
221
+
222
+ `barrier::arrival_token` is an unspecified type, such that it meets the
223
+ *Cpp17MoveConstructible* ([[cpp17.moveconstructible]]),
224
+ *Cpp17MoveAssignable* ([[cpp17.moveassignable]]), and
225
+ *Cpp17Destructible* ([[cpp17.destructible]]) requirements.
226
+
227
+ ``` cpp
228
+ static constexpr ptrdiff_t max() noexcept;
229
+ ```
230
+
231
+ *Returns:* The maximum expected count that the implementation supports.
232
+
233
+ ``` cpp
234
+ constexpr explicit barrier(ptrdiff_t expected,
235
+ CompletionFunction f = CompletionFunction());
236
+ ```
237
+
238
+ *Preconditions:* `expected >= 0` is `true` and `expected <= max()` is
239
+ `true`.
240
+
241
+ *Effects:* Sets both the initial expected count for each barrier phase
242
+ and the current expected count for the first phase to `expected`.
243
+ Initializes `completion` with `std::move(f)`. Starts the first phase.
244
+
245
+ [*Note 1*: If `expected` is 0 this object can only be
246
+ destroyed. — *end note*]
247
+
248
+ *Throws:* Any exception thrown by `CompletionFunction`’s move
249
+ constructor.
250
+
251
+ ``` cpp
252
+ [[nodiscard]] arrival_token arrive(ptrdiff_t update = 1);
253
+ ```
254
+
255
+ *Preconditions:* `update > 0` is `true`, and `update` is less than or
256
+ equal to the expected count for the current barrier phase.
257
+
258
+ *Effects:* Constructs an object of type `arrival_token` that is
259
+ associated with the phase synchronization point for the current phase.
260
+ Then, decrements the expected count by `update`.
261
+
262
+ *Synchronization:* The call to `arrive` strongly happens before the
263
+ start of the phase completion step for the current phase.
264
+
265
+ *Returns:* The constructed `arrival_token` object.
266
+
267
+ *Throws:* `system_error` when an exception is
268
+ required [[thread.req.exception]].
269
+
270
+ *Error conditions:* Any of the error conditions allowed for mutex
271
+ types [[thread.mutex.requirements.mutex]].
272
+
273
+ [*Note 2*: This call can cause the completion step for the current
274
+ phase to start. — *end note*]
275
+
276
+ ``` cpp
277
+ void wait(arrival_token&& arrival) const;
278
+ ```
279
+
280
+ *Preconditions:* `arrival` is associated with the phase synchronization
281
+ point for the current phase or the immediately preceding phase of the
282
+ same barrier object.
283
+
284
+ *Effects:* Blocks at the synchronization point associated with
285
+ `std::move(arrival)` until the phase completion step of the
286
+ synchronization point’s phase is run.
287
+
288
+ [*Note 3*: If `arrival` is associated with the synchronization point
289
+ for a previous phase, the call returns immediately. — *end note*]
290
+
291
+ *Throws:* `system_error` when an exception is
292
+ required [[thread.req.exception]].
293
+
294
+ *Error conditions:* Any of the error conditions allowed for mutex
295
+ types [[thread.mutex.requirements.mutex]].
296
+
297
+ ``` cpp
298
+ void arrive_and_wait();
299
+ ```
300
+
301
+ *Effects:* Equivalent to: `wait(arrive())`.
302
+
303
+ ``` cpp
304
+ void arrive_and_drop();
305
+ ```
306
+
307
+ *Preconditions:* The expected count for the current barrier phase is
308
+ greater than zero.
309
+
310
+ *Effects:* Decrements the initial expected count for all subsequent
311
+ phases by one. Then decrements the expected count for the current phase
312
+ by one.
313
+
314
+ *Synchronization:* The call to `arrive_and_drop` strongly happens before
315
+ the start of the phase completion step for the current phase.
316
+
317
+ *Throws:* `system_error` when an exception is
318
+ required [[thread.req.exception]].
319
+
320
+ *Error conditions:* Any of the error conditions allowed for mutex
321
+ types [[thread.mutex.requirements.mutex]].
322
+
323
+ [*Note 4*: This call can cause the completion step for the current
324
+ phase to start. — *end note*]
325
+