ints can be used in futexes. chars can't. --- libstdc++-v3/include/std/barrier | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier index e09212dfcb9..ae058bd3dc3 100644 --- a/libstdc++-v3/include/std/barrier +++ b/libstdc++-v3/include/std/barrier @@ -70,7 +70,7 @@ It looks different from literature pseudocode for two main reasons: */ - enum class __barrier_phase_t : unsigned char { }; + enum class __barrier_phase_t : int { }; template<typename _CompletionF> class __tree_barrier @@ -93,20 +93,24 @@ It looks different from literature pseudocode for two main reasons: alignas(__phase_alignment) __barrier_phase_t _M_phase; + static __barrier_phase_t + _S_add_to_phase(__barrier_phase_t __phase, unsigned char __n) + { + __n += static_cast<unsigned char>(__phase); + return static_cast<__barrier_phase_t>(__n); + } + bool _M_arrive(__barrier_phase_t __old_phase) { - const auto __old_phase_val = static_cast<unsigned char>(__old_phase); - const auto __half_step = - static_cast<__barrier_phase_t>(__old_phase_val + 1); - const auto __full_step = - static_cast<__barrier_phase_t>(__old_phase_val + 2); - size_t __current_expected = _M_expected; std::hash<std::thread::id> __hasher; size_t __current = __hasher(std::this_thread::get_id()) % ((_M_expected + 1) >> 1); + const auto __half_step = _S_add_to_phase(__old_phase, 1); + const auto __full_step = _S_add_to_phase(__old_phase, 2); + for (int __round = 0; ; ++__round) { if (__current_expected <= 1) @@ -165,7 +169,6 @@ It looks different from literature pseudocode for two main reasons: { __atomic_phase_ref_t __phase(_M_phase); const auto __old_phase = __phase.load(memory_order_relaxed); - const auto __cur = static_cast<unsigned char>(__old_phase); for(; __update; --__update) { if(_M_arrive(__old_phase)) @@ -173,7 +176,7 @@ It looks different from literature pseudocode for two main reasons: _M_completion(); _M_expected += _M_expected_adjustment.load(memory_order_relaxed); _M_expected_adjustment.store(0, memory_order_relaxed); - auto __new_phase = static_cast<__barrier_phase_t>(__cur + 2); + auto __new_phase = _S_add_to_phase(__old_phase, 2); __phase.store(__new_phase, memory_order_release); __phase.notify_all(); } -- 2.30.1