5#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SYNCHRONIZATION_BARRIER_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SYNCHRONIZATION_BARRIER_HPP_
17#include "arene/base/compiler_support/attributes.hpp"
18#include "arene/base/compiler_support/expect.hpp"
19#include "arene/base/constraints.hpp"
20#include "arene/base/contracts.hpp"
21#include "arene/base/synchronization/manual_reset_event.hpp"
29namespace barrier_detail {
31class default_completion_function {
35 constexpr void operator()()
const noexcept {}
45template <
typename CompletionFunction = barrier_detail::default_completion_function>
50 "The completion function must be move-constructible"
55 "The completion function must be nothrow-invocable with no arguments"
60 class private_construction_tag {
63 explicit private_construction_tag()
noexcept =
default;
69 static constexpr auto max()
noexcept ->
std::
ptrdiff_t {
return std::numeric_limits<std::ptrdiff_t>::max(); }
108 constexpr barrier(std::ptrdiff_t count, CompletionFunction func)
noexcept(
115 ARENE_PRECONDITION(count >= 0);
161 ARENE_PRECONDITION(initial_count_.load(std::memory_order_relaxed) > 0);
162 std::ignore = initial_count_.fetch_sub(1, std::memory_order_relaxed);
163 std::ignore = arrive();
174 auto const remaining_count = count_.load(std::memory_order_relaxed);
175 ARENE_PRECONDITION((arrivals > 0) && (arrivals <= remaining_count));
176 auto phase = phase_.load(std::memory_order_relaxed);
177 if (count_.fetch_sub(arrivals, std::memory_order_acq_rel) == arrivals) {
178 run_completion_step(phase);
180 return {private_construction_tag{}, phase};
194 auto const current_phase = phase_.load(std::memory_order_relaxed);
195 ARENE_PRECONDITION((token.get_phase() == current_phase) || (token.get_phase() == current_phase - 1U));
196 completed_event(token.get_phase()).wait();
202 void run_completion_step(std::uint64_t completed_phase) {
203 completion_function_();
204 auto new_phase = phase_.fetch_add(1U, std::memory_order_relaxed) + 1U;
205 count_ = initial_count_.load(std::memory_order_relaxed);
206 completed_event(new_phase).reset();
207 completed_event(completed_phase).signal();
213 auto completed_event(std::uint64_t event_phase) -> manual_reset_event& {
214 constexpr std::uint64_t two{2U};
215 return (event_phase % two) == 0U ? completed_even_ : completed_odd_;
219 CompletionFunction completion_function_;
221 std::atomic<std::uint64_t> phase_;
223 std::atomic<std::ptrdiff_t> initial_count_;
225 std::atomic<std::ptrdiff_t> count_;
227 manual_reset_event completed_odd_;
229 manual_reset_event completed_even_;
A class holding the result of a call to arrive, which can then be passed to wait to wait for the end ...
Definition barrier.hpp:74
auto get_phase() const noexcept -> std::uint64_t
Get the phase this token is associated with.
Definition barrier.hpp:100
arrival_token(arrival_token &&other) noexcept=default
Default move constructor.
auto operator=(arrival_token &&other) noexcept -> arrival_token &=default
Default move assignment.
arrival_token(arrival_token const &other)=delete
not copyable
auto operator=(arrival_token const &other) -> arrival_token &=delete
not copyable
arrival_token(private_construction_tag, std::uint64_t phase) noexcept
Construct a new arrival token for the phase.
Definition barrier.hpp:82
~arrival_token()=default
Default destructor.
A backport of std::barrier from C++20.
Definition barrier.hpp:46
ARENE_NODISCARD auto arrive() -> arrival_token
Arrive at the barrier, and obtain a token that can be used to wait for the end of the completion step...
Definition barrier.hpp:186
static constexpr auto max() noexcept -> std::ptrdiff_t
Get the maximum supported count.
Definition barrier.hpp:69
ARENE_NODISCARD auto arrive(std::ptrdiff_t arrivals) -> arrival_token
Arrive at the barrier with the specified number of arrivals, and obtain a token that can be used to w...
Definition barrier.hpp:173
barrier(barrier &&)=delete
Not movable.
auto operator=(barrier const &) -> barrier &=delete
Not copyable.
constexpr barrier(std::ptrdiff_t count, CompletionFunction func) noexcept(std::is_nothrow_move_constructible< CompletionFunction >::value)
Construct a barrier with a specified count and completion function.
Definition barrier.hpp:108
void arrive_and_wait()
Arrive at the barrier and wait for the completion step to end. May trigger the completion step.
Definition barrier.hpp:153
auto operator=(barrier &&) -> barrier &=delete
Not movable.
void arrive_and_drop()
Decrease the number of arrivals required for the subsequent phases to end, and arrive at the barrier....
Definition barrier.hpp:160
void wait(arrival_token token)
Wait for the completion step associated with the phase identified by token to end.
Definition barrier.hpp:193
barrier(barrier const &)=delete
Not copyable.
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10