Skip to content

Commit fa436e6

Browse files
committed
P2588R3 barrier's phase completion guarantees
1 parent 9ce105b commit fa436e6

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

source/compatibility.tex

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,40 @@
277277
};
278278
\end{codeblock}
279279

280+
\rSec2[diff.cpp20.thread]{\ref{thread}: threads library}
281+
282+
\diffref{thread.barrier}
283+
\change
284+
In this revision of \Cpp{},
285+
it is implementation-defined whether a barrier's phase completion step runs
286+
if no thread calls \tcode{wait}.
287+
Previously the phase completion step was guaranteed to run on the last thread that calls \tcode{arrive} or \tcode{arrive_and_drop} during the phase.
288+
In this revision of \Cpp{},
289+
it can run on any of the threads that arrived or waited at the barrier
290+
during the phase.
291+
\rationale
292+
Correct contradictory wording and
293+
improve implementation flexibility for performance.
294+
\effect
295+
Valid \CppXX{} code using a barrier might have
296+
different semantics in this revision of \Cpp{}
297+
if it depends on a completion function's side effects occurring exactly once,
298+
on a specific thread running the phase completion step, or
299+
on a completion function's side effects occurring
300+
without \tcode{wait} having been called.
301+
For example:
302+
\begin{codeblock}
303+
auto b0 = std::barrier(1);
304+
b0.arrive();
305+
b0.arrive(); // implementation-defined; previously well-defined
306+
307+
int data = 0;
308+
auto b1 = std::barrier(1, [&] { data++; });
309+
b1.arrive();
310+
assert(data == 1); // implementation-defined; previously well-defined
311+
b1.arrive(); // implementation-defined; previously well-defined
312+
\end{codeblock}
313+
280314
\rSec1[diff.cpp17]{\Cpp{} and ISO \CppXVII{}}
281315

282316
\rSec2[diff.cpp17.general]{General}

source/support.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@
574574
#define @\defnlibxname{cpp_lib_atomic_shared_ptr}@ 201711L // also in \libheader{memory}
575575
#define @\defnlibxname{cpp_lib_atomic_value_initialization}@ 201911L // also in \libheader{atomic}, \libheader{memory}
576576
#define @\defnlibxname{cpp_lib_atomic_wait}@ 201907L // also in \libheader{atomic}
577-
#define @\defnlibxname{cpp_lib_barrier}@ 201907L // also in \libheader{barrier}
577+
#define @\defnlibxname{cpp_lib_barrier}@ 202302L // also in \libheader{barrier}
578578
#define @\defnlibxname{cpp_lib_bind_back}@ 202202L // also in \libheader{functional}
579579
#define @\defnlibxname{cpp_lib_bind_front}@ 201907L // also in \libheader{functional}
580580
#define @\defnlibxname{cpp_lib_bit_cast}@ 201806L // also in \libheader{bit}

source/threads.tex

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9604,15 +9604,11 @@
96049604
The expected count is decremented
96059605
by each call to \tcode{arrive} or \tcode{arrive_and_drop}.
96069606
\item
9607-
When the expected count reaches zero, the phase completion step is run.
9608-
For the specialization
9609-
with the default value of the \tcode{CompletionFunction} template parameter,
9610-
the completion step is run
9611-
as part of the call to \tcode{arrive} or \tcode{arrive_and_drop}
9612-
that caused the expected count to reach zero.
9613-
For other specializations,
9614-
the completion step is run on one of the threads
9615-
that arrived at the barrier during the phase.
9607+
Exactly once after the expected count reaches zero, a thread
9608+
executes the completion step during its call
9609+
to \tcode{arrive}, \tcode{arrive_and_drop}, or \tcode{wait},
9610+
except that it is \impldef{barrier phrase completion without \tcode{wait}}
9611+
whether the step executes if no thread calls \tcode{wait}.
96169612
\item
96179613
When the completion step finishes,
96189614
the expected count is reset

0 commit comments

Comments
 (0)