On 26/02/21 07:59 -0800, Thiago Macieira via Libstdc++ wrote:
Our thread's ID does not change so we don't have to get it every time
and hash it every time.

This looks good for GCC 11.

(This one wouldn't be an ABI break to change later, but we might as
well do it now, as we have the patch now).


libstdc++-v3/include/std/barrier | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier
index ae058bd3dc3..eb31a89b175 100644
--- a/libstdc++-v3/include/std/barrier
+++ b/libstdc++-v3/include/std/barrier
@@ -101,12 +101,10 @@ It looks different from literature pseudocode for two 
main reasons:
      }

      bool
-      _M_arrive(__barrier_phase_t __old_phase)
+      _M_arrive(__barrier_phase_t __old_phase, size_t __current)
      {
        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);
+        __current %= ((__current_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);
@@ -167,11 +165,13 @@ It looks different from literature pseudocode for two 
main reasons:
      [[nodiscard]] arrival_token
      arrive(ptrdiff_t __update)
      {
+       std::hash<std::thread::id> __hasher;
+       size_t __current = __hasher(std::this_thread::get_id());
        __atomic_phase_ref_t __phase(_M_phase);
        const auto __old_phase = __phase.load(memory_order_relaxed);
        for(; __update; --__update)
          {
-           if(_M_arrive(__old_phase))
+           if(_M_arrive(__old_phase, __current))
              {
                _M_completion();
                _M_expected += 
_M_expected_adjustment.load(memory_order_relaxed);
--
2.30.1


Reply via email to