diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | include/atomic.h | 19 |
2 files changed, 17 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog index 6b8763f95a..9c4d06fdc3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-10-26 Carlos O'Donell <carlos@redhat.com> + + * include/atomic.h + [USE_COMPILER_ATOMIC_BUILTINS && !atomic_fetch_xor_release] + (atomic_fetch_xor_release): Use atomic_compare_exchange_weak_release. + 2016-10-25 Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com> * stdlib/Makefile (tests): Add tst-strfrom and tst-strfrom-locale. diff --git a/include/atomic.h b/include/atomic.h index 5a8e7e7966..c8b46649c5 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 */ |