Remove atomic_compare_and_exchange_bool_rel.
authorTorvald Riegel <triegel@redhat.com>
Tue, 14 Jun 2016 13:12:00 +0000 (15:12 +0200)
committerTorvald Riegel <triegel@redhat.com>
Fri, 24 Jun 2016 20:04:40 +0000 (23:04 +0300)
atomic_compare_and_exchange_bool_rel and
catomic_compare_and_exchange_bool_rel are removed and replaced with the
new C11-like atomic_compare_exchange_weak_release.  The concurrent code
in nscd/cache.c has not been reviewed yet, so this patch does not add
detailed comments.

* nscd/cache.c (cache_add): Use new C11-like atomic operation instead
of atomic_compare_and_exchange_bool_rel.
* nptl/pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Likewise.
* include/atomic.h (atomic_compare_and_exchange_bool_rel,
catomic_compare_and_exchange_bool_rel): Remove.
* sysdeps/aarch64/atomic-machine.h
(atomic_compare_and_exchange_bool_rel): Likewise.
* sysdeps/alpha/atomic-machine.h
(atomic_compare_and_exchange_bool_rel): Likewise.
* sysdeps/arm/atomic-machine.h
(atomic_compare_and_exchange_bool_rel): Likewise.
* sysdeps/mips/atomic-machine.h
(atomic_compare_and_exchange_bool_rel): Likewise.
* sysdeps/tile/atomic-machine.h
(atomic_compare_and_exchange_bool_rel): Likewise.

13 files changed:
ChangeLog
include/atomic.h
nptl/pthread_mutex_unlock.c
nscd/cache.c
sysdeps/aarch64/atomic-machine.h
sysdeps/alpha/atomic-machine.h
sysdeps/arm/atomic-machine.h
sysdeps/microblaze/atomic-machine.h
sysdeps/mips/atomic-machine.h
sysdeps/powerpc/atomic-machine.h
sysdeps/powerpc/powerpc32/atomic-machine.h
sysdeps/powerpc/powerpc64/atomic-machine.h
sysdeps/tile/atomic-machine.h

index 3d6dad2..eaf8fed 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2016-06-24  Torvald Riegel  <triegel@redhat.com>
+
+       * nscd/cache.c (cache_add): Use new C11-like atomic operation instead
+       of atomic_compare_and_exchange_bool_rel.
+       * nptl/pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Likewise.
+       * include/atomic.h (atomic_compare_and_exchange_bool_rel,
+       catomic_compare_and_exchange_bool_rel): Remove.
+       * sysdeps/aarch64/atomic-machine.h
+       (atomic_compare_and_exchange_bool_rel): Likewise.
+       * sysdeps/alpha/atomic-machine.h
+       (atomic_compare_and_exchange_bool_rel): Likewise.
+       * sysdeps/arm/atomic-machine.h
+       (atomic_compare_and_exchange_bool_rel): Likewise.
+       * sysdeps/mips/atomic-machine.h
+       (atomic_compare_and_exchange_bool_rel): Likewise.
+       * sysdeps/microblaze/atomic-machine.h
+       ( __arch_compare_and_exchange_bool_8_rel,
+       __arch_compare_and_exchange_bool_16_rel): Likewise.
+       * sysdeps/powerpc/atomic-machine.h
+       ( __arch_compare_and_exchange_bool_8_rel,
+       __arch_compare_and_exchange_bool_16_rel): Likewise.
+       * sysdeps/powerpc/powerpc32/atomic-machine.h
+       ( __arch_compare_and_exchange_bool_32_rel,
+       __arch_compare_and_exchange_bool_64_rel): Likewise.
+       * sysdeps/powerpc/powerpc64/atomic-machine.h
+       ( __arch_compare_and_exchange_bool_32_rel,
+       __arch_compare_and_exchange_bool_64_rel): Likewise.
+       * sysdeps/tile/atomic-machine.h
+       (atomic_compare_and_exchange_bool_rel): Likewise.
+
 2016-06-23  Joseph Myers  <joseph@codesourcery.com>
 
        [BZ #20296]
index 5e8bfff..ad3db25 100644 (file)
 #endif
 
 
-#ifndef catomic_compare_and_exchange_bool_rel
-# ifndef atomic_compare_and_exchange_bool_rel
-#  define catomic_compare_and_exchange_bool_rel(mem, newval, oldval)         \
-  catomic_compare_and_exchange_bool_acq (mem, newval, oldval)
-# else
-#  define catomic_compare_and_exchange_bool_rel(mem, newval, oldval)         \
-  atomic_compare_and_exchange_bool_rel (mem, newval, oldval)
-# endif
-#endif
-
-
-#ifndef atomic_compare_and_exchange_bool_rel
-# define atomic_compare_and_exchange_bool_rel(mem, newval, oldval) \
-  atomic_compare_and_exchange_bool_acq (mem, newval, oldval)
-#endif
-
-
 /* Store NEWVALUE in *MEM and return the old value.  */
 #ifndef atomic_exchange_acq
 # define atomic_exchange_acq(mem, newvalue) \
index 334ce38..82aaa95 100644 (file)
@@ -237,15 +237,24 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
       int private = (robust
                     ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
                     : PTHREAD_MUTEX_PSHARED (mutex));
-      if ((mutex->__data.__lock & FUTEX_WAITERS) != 0
-         || atomic_compare_and_exchange_bool_rel (&mutex->__data.__lock, 0,
-                                                  THREAD_GETMEM (THREAD_SELF,
-                                                                 tid)))
+      /* Unlock the mutex using a CAS unless there are futex waiters or our
+        TID is not the value of __lock anymore, in which case we let the
+        kernel take care of the situation.  Use release MO in the CAS to
+        synchronize with acquire MO in lock acquisitions.  */
+      int l = atomic_load_relaxed (&mutex->__data.__lock);
+      do
        {
-         INTERNAL_SYSCALL_DECL (__err);
-         INTERNAL_SYSCALL (futex, __err, 2, &mutex->__data.__lock,
-                           __lll_private_flag (FUTEX_UNLOCK_PI, private));
+         if (((l & FUTEX_WAITERS) != 0)
+             || (l != THREAD_GETMEM (THREAD_SELF, tid)))
+           {
+             INTERNAL_SYSCALL_DECL (__err);
+             INTERNAL_SYSCALL (futex, __err, 2, &mutex->__data.__lock,
+                               __lll_private_flag (FUTEX_UNLOCK_PI, private));
+             break;
+           }
        }
+      while (!atomic_compare_exchange_weak_release (&mutex->__data.__lock,
+                                                   &l, 0));
 
       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
@@ -278,15 +287,16 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
        /* One less user.  */
        --mutex->__data.__nusers;
 
-      /* Unlock.  */
-      int newval, oldval;
+      /* Unlock.  Use release MO in the CAS to synchronize with acquire MO in
+        lock acquisitions.  */
+      int newval;
+      int oldval = atomic_load_relaxed (&mutex->__data.__lock);
       do
        {
-         oldval = mutex->__data.__lock;
          newval = oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK;
        }
-      while (atomic_compare_and_exchange_bool_rel (&mutex->__data.__lock,
-                                                  newval, oldval));
+      while (!atomic_compare_exchange_weak_release (&mutex->__data.__lock,
+                                                   &oldval, newval));
 
       if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1)
        lll_futex_wake (&mutex->__data.__lock, 1,
index 3021abd..daa0b2b 100644 (file)
@@ -178,12 +178,12 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
   assert ((newp->packet & BLOCK_ALIGN_M1) == 0);
 
   /* Put the new entry in the first position.  */
-  do
-    newp->next = table->head->array[hash];
-  while (atomic_compare_and_exchange_bool_rel (&table->head->array[hash],
-                                              (ref_t) ((char *) newp
-                                                       - table->data),
-                                              (ref_t) newp->next));
+  /* TODO Review concurrency.  Use atomic_exchange_release.  */
+  newp->next = atomic_load_relaxed (&table->head->array[hash]);
+  while (!atomic_compare_exchange_weak_release (&table->head->array[hash],
+                                               (ref_t *) &newp->next,
+                                               (ref_t) ((char *) newp
+                                                        - table->data)));
 
   /* Update the statistics.  */
   if (packet->notfound)
index 28c80dc..6708b9b 100644 (file)
@@ -115,10 +115,6 @@ typedef uintmax_t uatomic_max_t;
 
 /* Compare and exchange with "release" semantics, ie barrier before.  */
 
-# define atomic_compare_and_exchange_bool_rel(mem, new, old)   \
-  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
-                       mem, new, old, __ATOMIC_RELEASE)
-
 # define atomic_compare_and_exchange_val_rel(mem, new, old)     \
   __atomic_val_bysize (__arch_compare_and_exchange_val, int,    \
                        mem, new, old, __ATOMIC_RELEASE)
index d96cb7a..882d800 100644 (file)
@@ -210,10 +210,6 @@ typedef uintmax_t uatomic_max_t;
 
 /* Compare and exchange with "release" semantics, ie barrier before.  */
 
-#define atomic_compare_and_exchange_bool_rel(mem, new, old)    \
-  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
-                       mem, new, old, __MB, "")
-
 #define atomic_compare_and_exchange_val_rel(mem, new, old)     \
   __atomic_val_bysize (__arch_compare_and_exchange_val, int,   \
                       mem, new, old, __MB, "")
index dd5e714..916c09a 100644 (file)
@@ -87,10 +87,6 @@ void __arm_link_error (void);
 
 /* Compare and exchange with "release" semantics, ie barrier before.  */
 
-# define atomic_compare_and_exchange_bool_rel(mem, new, old)    \
-  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int,  \
-                        mem, new, old, __ATOMIC_RELEASE)
-
 # define atomic_compare_and_exchange_val_rel(mem, new, old)      \
   __atomic_val_bysize (__arch_compare_and_exchange_val, int,    \
                        mem, new, old, __ATOMIC_RELEASE)
index af7acac..229fd49 100644 (file)
@@ -47,12 +47,6 @@ typedef uintmax_t uatomic_max_t;
 #define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval)           \
   (abort (), 0)
 
-#define __arch_compare_and_exchange_bool_8_rel(mem, newval, oldval)            \
-  (abort (), 0)
-
-#define __arch_compare_and_exchange_bool_16_rel(mem, newval, oldval)           \
-  (abort (), 0)
-
 #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval)            \
   ({                                                                           \
       __typeof (*(mem)) __tmp;                                                 \
index a60e4fb..771166b 100644 (file)
@@ -149,10 +149,6 @@ typedef uintmax_t uatomic_max_t;
 
 /* Compare and exchange with "release" semantics, ie barrier before.  */
 
-# define atomic_compare_and_exchange_bool_rel(mem, new, old)   \
-  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
-                       mem, new, old, __ATOMIC_RELEASE)
-
 # define atomic_compare_and_exchange_val_rel(mem, new, old)     \
   __atomic_val_bysize (__arch_compare_and_exchange_val, int,    \
                        mem, new, old, __ATOMIC_RELEASE)
@@ -330,10 +326,6 @@ typedef uintmax_t uatomic_max_t;
 
 /* Compare and exchange with "release" semantics, ie barrier before.  */
 
-# define atomic_compare_and_exchange_bool_rel(mem, new, old)   \
-  __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
-                       mem, new, old, MIPS_SYNC_STR, "")
-
 # define atomic_compare_and_exchange_val_rel(mem, new, old)    \
   __atomic_val_bysize (__arch_compare_and_exchange_val, int,   \
                       mem, new, old, MIPS_SYNC_STR, "")
index 8b0e1e7..c6b9eea 100644 (file)
@@ -53,12 +53,6 @@ typedef uintmax_t uatomic_max_t;
 #define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \
   (abort (), 0)
 
-#define __arch_compare_and_exchange_bool_8_rel(mem, newval, oldval) \
-  (abort (), 0)
-
-#define __arch_compare_and_exchange_bool_16_rel(mem, newval, oldval) \
-  (abort (), 0)
-
 #ifdef UP
 # define __ARCH_ACQ_INSTR      ""
 # define __ARCH_REL_INSTR      ""
index 1d407b3..40a8b7b 100644 (file)
   __tmp != 0;                                                                \
 })
 
-#define __arch_compare_and_exchange_bool_32_rel(mem, newval, oldval)         \
-({                                                                           \
-  unsigned int __tmp;                                                        \
-  __asm __volatile (__ARCH_REL_INSTR "\n"                                    \
-                   "1: lwarx   %0,0,%1" MUTEX_HINT_REL "\n"                  \
-                   "   subf.   %0,%2,%0\n"                                   \
-                   "   bne     2f\n"                                         \
-                   "   stwcx.  %3,0,%1\n"                                    \
-                   "   bne-    1b\n"                                         \
-                   "2: "                                                     \
-                   : "=&r" (__tmp)                                           \
-                   : "b" (mem), "r" (oldval), "r" (newval)                   \
-                   : "cr0", "memory");                                       \
-  __tmp != 0;                                                                \
-})
-
 /* Powerpc32 processors don't implement the 64-bit (doubleword) forms of
    load and reserve (ldarx) and store conditional (stdcx.) instructions.
    So for powerpc32 we stub out the 64-bit forms.  */
@@ -83,9 +67,6 @@
 #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
   (abort (), (__typeof (*mem)) 0)
 
-#define __arch_compare_and_exchange_bool_64_rel(mem, newval, oldval) \
-  (abort (), 0)
-
 #define __arch_compare_and_exchange_val_64_rel(mem, newval, oldval) \
   (abort (), (__typeof (*mem)) 0)
 
index 751487a..7971318 100644 (file)
   __tmp != 0;                                                                \
 })
 
-#define __arch_compare_and_exchange_bool_32_rel(mem, newval, oldval) \
-({                                                                           \
-  unsigned int __tmp, __tmp2;                                                \
-  __asm __volatile (__ARCH_REL_INSTR "\n"                                    \
-                   "   clrldi  %1,%1,32\n"                                   \
-                   "1: lwarx   %0,0,%2" MUTEX_HINT_REL "\n"                  \
-                   "   subf.   %0,%1,%0\n"                                   \
-                   "   bne     2f\n"                                         \
-                   "   stwcx.  %4,0,%2\n"                                    \
-                   "   bne-    1b\n"                                         \
-                   "2: "                                                     \
-                   : "=&r" (__tmp), "=r" (__tmp2)                            \
-                   : "b" (mem), "1" (oldval), "r" (newval)                   \
-                   : "cr0", "memory");                                       \
-  __tmp != 0;                                                                \
-})
-
 /*
  * Only powerpc64 processors support Load doubleword and reserve index (ldarx)
  * and Store doubleword conditional indexed (stdcx) instructions.  So here
   __tmp != 0;                                                                \
 })
 
-#define __arch_compare_and_exchange_bool_64_rel(mem, newval, oldval) \
-({                                                                           \
-  unsigned long        __tmp;                                                        \
-  __asm __volatile (__ARCH_REL_INSTR "\n"                                    \
-                   "1: ldarx   %0,0,%1" MUTEX_HINT_REL "\n"                  \
-                   "   subf.   %0,%2,%0\n"                                   \
-                   "   bne     2f\n"                                         \
-                   "   stdcx.  %3,0,%1\n"                                    \
-                   "   bne-    1b\n"                                         \
-                   "2: "                                                     \
-                   : "=&r" (__tmp)                                           \
-                   : "b" (mem), "r" (oldval), "r" (newval)                   \
-                   : "cr0", "memory");                                       \
-  __tmp != 0;                                                                \
-})
-
 #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
   ({                                                                         \
       __typeof (*(mem)) __tmp;                                               \
index 651e0d9..336518c 100644 (file)
@@ -55,11 +55,6 @@ typedef uintmax_t uatomic_max_t;
     atomic_full_barrier ();                                     \
     atomic_compare_and_exchange_val_acq ((mem), (n), (o));      \
   })
-#define atomic_compare_and_exchange_bool_rel(mem, n, o)         \
-  ({                                                            \
-    atomic_full_barrier ();                                     \
-    atomic_compare_and_exchange_bool_acq ((mem), (n), (o));     \
-  })
 #define atomic_exchange_rel(mem, n)                             \
   ({                                                            \
     atomic_full_barrier ();                                     \