]> sourceware.org Git - glibc.git/commitdiff
Fix atomic_fetch_xor_release.
authorCarlos O'Donell <carlos@systemhalted.org>
Wed, 26 Oct 2016 04:00:13 +0000 (00:00 -0400)
committerCarlos O'Donell <carlos@systemhalted.org>
Wed, 26 Oct 2016 04:00:13 +0000 (00:00 -0400)
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.

ChangeLog
include/atomic.h

index 6b8763f95a2a49c3d9d229db7f0539dc860425db..9c4d06fdc3f3227aaa2cf46ec1fd0abea78f04b9 100644 (file)
--- 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.
index 5a8e7e7966d6cab78ef918e98cc5797df0a2dc2e..c8b46649c5285eb154f49768b29df0a4f8dde8c0 100644 (file)
@@ -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  */
This page took 0.16689 seconds and 5 git commands to generate.