ia64: atomic.h: fix atomic_exchange_and_add 64bit handling
authorMike Frysinger <vapier@gentoo.org>
Tue, 28 Jul 2015 06:19:49 +0000 (02:19 -0400)
committerMike Frysinger <vapier@gentoo.org>
Tue, 28 Jul 2015 06:30:15 +0000 (02:30 -0400)
Way back in 2005 the atomic_exchange_and_add function was cleaned up to
avoid the explicit size checking and instead let gcc handle things itself.
Unfortunately that change ended up leaving beyond a cast to int, even when
the incoming value was a long.  This has flown under the radar for a long
time due to the function not being heavily used in the tree (especially as
a full 64bit field), but a recent change to semaphores made some nptl tests
fail reliably.  This is due to the code packing two 32bit values into one
64bit variable (where the high 32bits contained the number of waiters), and
then the whole variable being atomically updated between threads.  On ia64,
that meant we never atomically updated the count, so sometimes the sem_post
would not wake up the waiters.

ChangeLog
sysdeps/ia64/bits/atomic.h

index b177adc143b143ddda14131e8829460746891a43..cd2d8274c7d7ad1dd2ffe1ffceae6f98f3d6f4fc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-07-27  Mike Frysinger  <vapier@gentoo.org>
+
+       * sysdeps/ia64/bits/atomic.h (atomic_exchange_and_add): Define
+       directly in terms of __sync_fetch_and_add and delete (int) cast.
+
 2015-07-27  Mike Frysinger  <vapier@gentoo.org>
 
        * sysdeps/unix/sysv/linux/ia64/Makefile (CPPFLAGS): Delete
index 0e9dfc71746b6db4c44f984f303fc3279ab108fd..4c2b54094c1c9f69b4013db4e448351dfd172031 100644 (file)
@@ -82,9 +82,7 @@ typedef uintmax_t uatomic_max_t;
   (__sync_synchronize (), __sync_lock_test_and_set (mem, value))
 
 #define atomic_exchange_and_add(mem, value) \
-  ({ __typeof (*mem) __result;                                               \
-     __result = __sync_fetch_and_add ((mem), (int) (value));                 \
-     __result; })
+  __sync_fetch_and_add ((mem), (value))
 
 #define atomic_decrement_if_positive(mem) \
   ({ __typeof (*mem) __oldval, __val;                                        \