hppa: fix pthread spinlock
authorJohn David Anglin <dave.anglin@bell.net>
Sun, 4 May 2014 18:02:30 +0000 (14:02 -0400)
committerMike Frysinger <vapier@gentoo.org>
Wed, 6 Jan 2016 22:26:04 +0000 (17:26 -0500)
URL: https://bugs.debian.org/725508

ChangeLog
sysdeps/hppa/nptl/pthread_spin_init.c
sysdeps/hppa/nptl/pthread_spin_unlock.c

index 72614fe..acaf7a8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2016-01-06  John David Anglin  <dave.anglin@bell.net>
+
+       * sysdeps/hppa/nptl/pthread_spin_init.c (pthread_spin_init): Replace
+       asm stw with atomic_exchange_rel.  Add explanatory comment.
+       * sysdeps/hppa/nptl/pthread_spin_unlock.c (pthread_spin_unlock):
+       Likewise.
+
 2016-01-05  H.J. Lu  <hongjiu.lu@intel.com>
 
        [BZ #19122]
index 729d53f..2df0376 100644 (file)
 int
 pthread_spin_init (pthread_spinlock_t *lock, int pshared)
 {
-  int tmp = 0;
-  /* This should be a memory barrier to newer compilers */
-  __asm__ __volatile__ ("stw,ma %1,0(%0)"
-                        : : "r" (lock), "r" (tmp) : "memory");
+  /* CONCURRENCTY NOTES:
+
+     The atomic_exchange_rel synchronizes-with the atomic_exhange_acq in
+     pthread_spin_lock.
+
+     On hppa we must not use a plain `stw` to reset the guard lock.  This
+     has to do with the kernel compare-and-swap helper that is used to
+     implement all of the atomic operations.
+
+     The kernel CAS helper uses its own internal locks and that means that
+     to create a true happens-before relationship between any two threads,
+     the second thread must observe the internal lock having a value of 0
+     (it must attempt to take the lock with ldcw).  This creates the
+     ordering required for a second thread to observe the effects of the
+     RMW of the kernel CAS helper in any other thread.
+
+     Therefore if a variable is used in an atomic macro it must always be
+     manipulated with atomic macros in order for memory ordering rules to
+     be preserved.  */
+  atomic_exchange_rel (lock, 0);
   return 0;
 }
index 31162a7..6e4d71e 100644 (file)
 int
 pthread_spin_unlock (pthread_spinlock_t *lock)
 {
-  int tmp = 0;
-  /* This should be a memory barrier to newer compilers */
-  __asm__ __volatile__ ("stw,ma %1,0(%0)"
-                        : : "r" (lock), "r" (tmp) : "memory");
+  /* CONCURRENCTY NOTES:
+
+     The atomic_exchange_rel synchronizes-with the atomic_exhange_acq in
+     pthread_spin_lock.
+
+     On hppa we must not use a plain `stw` to reset the guard lock.  This
+     has to do with the kernel compare-and-swap helper that is used to
+     implement all of the atomic operations.
+
+     The kernel CAS helper uses its own internal locks and that means that
+     to create a true happens-before relationship between any two threads,
+     the second thread must observe the internal lock having a value of 0
+     (it must attempt to take the lock with ldcw).  This creates the
+     ordering required for a second thread to observe the effects of the
+     RMW of the kernel CAS helper in any other thread.
+
+     Therefore if a variable is used in an atomic macro it must always be
+     manipulated with atomic macros in order for memory ordering rules to
+     be preserved.  */
+  atomic_exchange_rel (lock, 0);
   return 0;
 }