1#ifndef NEFORCE_CORE_ASYNC_BARRIER_HPP__
2#define NEFORCE_CORE_ASYNC_BARRIER_HPP__
15NEFORCE_BEGIN_NAMESPACE__
36 NEFORCE_ALWAYS_INLINE
void operator()()
noexcept {}
48template <
typename CmplFunc>
53 static constexpr auto phase_alignment = phase_ref_t::required_alignment;
61 struct alignas(64) state_data {
68 CmplFunc completion_function_;
69 alignas(phase_alignment)
byte_t current_phase_{0};
79 bool do_arrive(
const byte_t old_phase,
size_t current_index) {
80 const auto old_phase_value = old_phase;
81 const auto half_step =
static_cast<byte_t>(old_phase_value + 1);
82 const auto full_step =
static_cast<byte_t>(old_phase_value + 2);
84 size_t current_expected = expected_count_;
85 current_index %= ((expected_count_ + 1) >> 1);
88 if (current_expected <= 1) {
92 size_t const end_node = ((current_expected + 1) >> 1), last_node = end_node - 1;
94 for (;; ++current_index) {
95 if (current_index == end_node) {
99 auto expected_phase = old_phase;
100 phase_ref_t phase_ref(state_array_[current_index].tickets[
round]);
103 if (current_index == last_node && ((current_expected & 1) != 0U)) {
107 }
else if (phase_ref.compare_exchange_strong(expected_phase, half_step,
memory_order_acq_rel)) {
109 }
else if (expected_phase == half_step) {
116 current_expected = last_node + 1;
136 expected_count_(expected),
137 completion_function_(_NEFORCE
move(completion)) {
138 size_t const count = (expected_count_ + 1) >> 1;
152 const size_t current_index = hasher(this_thread::id());
153 phase_ref_t phase_ref(current_phase_);
155 const auto current_phase_value =
static_cast<byte_t>(old_phase);
157 for (; update != 0; --update) {
158 if (do_arrive(old_phase, current_index)) {
159 completion_function_();
162 const auto new_phase =
static_cast<byte_t>(current_phase_value + 2);
164 phase_ref.notify_all();
177 phase_cref_t phase_ref(current_phase_);
202template <
typename CmplFunc = empty_completion>
205 algorithm_type barrier_impl_;
222 friend class barrier;
226 internal_token token_;
241 barrier_impl_(
count, _NEFORCE
move(completion)) {}
278NEFORCE_END_NAMESPACE__
arrival_token & operator=(arrival_token &&)=default
移动赋值运算符
~arrival_token()=default
析构函数
arrival_token(arrival_token &&)=default
移动构造函数
void wait(arrival_token &&phase) const
等待屏障
void arrive_and_drop()
到达并退出
void arrive_and_wait()
到达并等待
arrival_token arrive(ptrdiff_t update=1)
到达屏障点
static constexpr ptrdiff_t max() noexcept
获取最大线程数
barrier(ptrdiff_t count, CmplFunc completion=CmplFunc())
构造函数
static constexpr T max() noexcept
获取类型的最大值
void wait(arrival_token &&old_phase) const
等待屏障
arrival_token arrive(ptrdiff_t update)
到达屏障点
static constexpr ptrdiff_t max() noexcept
获取最大线程数
tree_barrier(const ptrdiff_t expected, CmplFunc completion)
构造函数
void arrive_and_drop()
到达并退出
byte_t arrival_token
到达令牌类型
void atomic_wait_address(const T *addr, Pred pred) noexcept
基于谓词的原子等待
unsigned char byte_t
字节类型,定义为无符号字符
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
constexpr decimal_t round(const decimal_t x) noexcept
四舍五入
constexpr auto memory_order_release
释放内存顺序常量
constexpr auto memory_order_relaxed
宽松内存顺序常量
constexpr auto memory_order_acquire
获取内存顺序常量
constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr