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_;
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]);
102 if (current_index == last_node && (current_expected & 1)) {
106 }
else if (phase_ref.compare_exchange_strong(expected_phase, half_step,
memory_order_acq_rel)) {
108 }
else if (expected_phase == half_step) {
115 current_expected = last_node + 1;
135 expected_count_(expected),
136 expected_adjustment_(0),
137 completion_function_(_NEFORCE
move(completion)),
138 current_phase_(static_cast<
byte_t>(0)) {
139 size_t const count = (expected_count_ + 1) >> 1;
153 const size_t current_index = hasher(this_thread::id());
154 phase_ref_t phase_ref(current_phase_);
156 const auto current_phase_value =
static_cast<byte_t>(old_phase);
158 for (; update; --update) {
159 if (do_arrive(old_phase, current_index)) {
160 completion_function_();
163 const auto new_phase =
static_cast<byte_t>(current_phase_value + 2);
165 phase_ref.notify_all();
178 phase_cref_t phase_ref(current_phase_);
203template <
typename CmplFunc = empty_completion>
206 algorithm_type barrier_impl_;
223 friend class barrier;
227 internal_token token_;
242 barrier_impl_(
count, _NEFORCE
move(completion)) {}
279NEFORCE_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()
到达并等待
static constexpr ptrdiff_t max() noexcept
获取最大线程数
NEFORCE_NODISCARD arrival_token arrive(ptrdiff_t update=1)
到达屏障点
barrier(ptrdiff_t count, CmplFunc completion=CmplFunc())
构造函数
static NEFORCE_NODISCARD constexpr T max() noexcept
获取类型的最大值
void wait(arrival_token &&old_phase) const
等待屏障
static constexpr ptrdiff_t max() noexcept
获取最大线程数
tree_barrier(const ptrdiff_t expected, CmplFunc completion)
构造函数
void arrive_and_drop()
到达并退出
byte_t arrival_token
到达令牌类型
NEFORCE_NODISCARD arrival_token arrive(ptrdiff_t update)
到达屏障点
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)
统计范围内等于指定值的元素数量
NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 decimal_t round(const decimal_t x) noexcept
四舍五入
NEFORCE_INLINE17 constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_release
释放内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_relaxed
宽松内存顺序常量
NEFORCE_INLINE17 constexpr auto memory_order_acquire
获取内存顺序常量
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
NEFORCE_CONSTEXPR20 unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr