From b671f20cc160238b62894d032a55baf85867106e Mon Sep 17 00:00:00 2001 From: Catalin Enache Date: Fri, 30 Jun 2017 19:12:43 +0300 Subject: [PATCH 6/6] Fix atomic_fetch_xor_release. No code uses atomic_fetch_xor_release except for the upcoming conditional variable rewrite. Therefore there is no user visible bug here. The use of atomic_compare_and_exchange_bool_rel is removed (since it doesn't exist anymore), and is replaced by atomic_compare_exchange_weak_release. We use weak_release because it provides better performance in the loop (the weak semantic) and because the xor is release MO (the release semantic). We don't reload expected in the loop because atomic_compare_and_exchange_weak_release does this for us as part of the CAS failure. It is otherwise a fairly plain conversion that fixes building the new condvar for 32-bit x86. Passes all regression tests for x86. Upstream-Status: Backport Author: Carlos O'Donell Signed-off-by: Catalin Enache --- ChangeLog | 6 ++++++ include/atomic.h | 19 +++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 44c518b..893262d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-10-26 Carlos O'Donell + + * include/atomic.h + [USE_COMPILER_ATOMIC_BUILTINS && !atomic_fetch_xor_release] + (atomic_fetch_xor_release): Use atomic_compare_exchange_weak_release. + 2017-04-04 Adhemerval Zanella * nptl/pthreadP.h (USE_REQUEUE_PI): Remove ununsed macro. diff --git a/include/atomic.h b/include/atomic.h index 5a8e7e7..c8b4664 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -777,18 +777,21 @@ void __atomic_link_error (void); # endif # ifndef atomic_fetch_xor_release +/* Failing the atomic_compare_exchange_weak_release reloads the value in + __atg104_expected, so we need only do the XOR again and retry. */ # define atomic_fetch_xor_release(mem, operand) \ - ({ __typeof (*(mem)) __atg104_old; \ - __typeof (mem) __atg104_memp = (mem); \ + ({ __typeof (mem) __atg104_memp = (mem); \ + __typeof (*(mem)) __atg104_expected = (*__atg104_memp); \ + __typeof (*(mem)) __atg104_desired; \ __typeof (*(mem)) __atg104_op = (operand); \ \ do \ - __atg104_old = (*__atg104_memp); \ - while (__builtin_expect \ - (atomic_compare_and_exchange_bool_rel ( \ - __atg104_memp, __atg104_old ^ __atg104_op, __atg104_old), 0));\ - \ - __atg104_old; }) + __atg104_desired = __atg104_expected ^ __atg104_op; \ + while (__glibc_unlikely \ + (atomic_compare_exchange_weak_release ( \ + __atg104_memp, &__atg104_expected, __atg104_desired) \ + == 0)); \ + __atg104_expected; }) #endif #endif /* !USE_ATOMIC_COMPILER_BUILTINS */ -- 2.10.2