]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
powerpc: Spinlock optimization and cleanup
authorPaul Murphy <murphyp@linux.vnet.ibm.com>
Thu, 29 Oct 2015 20:48:47 +0000 (15:48 -0500)
committerTulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
Thu, 19 Nov 2015 20:04:30 +0000 (18:04 -0200)
This patch optimizes powerpc spinlock implementation by:

* Use the correct EH hint bit on the larx for supported ISA.  For lock
  acquisition, the thread that acquired the lock with a successful stcx
  does not want to give away the write ownership on the cacheline.  The
  idea is to make the load reservation "sticky" about retaining write
  authority to the line.  That way, the store that must inevitably come
  to release the lock can succeed quickly and not contend with other
  threads issuing lwarx.  If another thread does a store to the line
  (false sharing), the winning thread must give up write authority to
  the proper value of EH for the larx for a lock acquisition is 1.

* Increase contented lock performance by up to 40%, and no measurable
  impact on uncontended locks on P8.

Thanks to Adhemerval Zanella who did most of the work.  I've run some
tests, and addressed some minor feedback.

* sysdeps/powerpc/nptl/pthread_spin_lock.c (pthread_spin_lock):
Add lwarx hint, and use macro for acquire instruction.
* sysdeps/powerpc/nptl/pthread_spin_trylock.c (pthread_spin_trylock):
Likewise.
* sysdep/unix/sysv/linux/powerpc/pthread_spin_unlock.c: Move to ...
* sysdeps/powerpc/nptl/pthread_spin_unlock.c: ... here, and
update to use new atomic macros.

ChangeLog
sysdeps/powerpc/nptl/pthread_spin_lock.c
sysdeps/powerpc/nptl/pthread_spin_trylock.c
sysdeps/powerpc/nptl/pthread_spin_unlock.c [moved from sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c with 93% similarity]

index a5440e2a74df3fae5ee15ae2ca5f77c4d5769708..d822095ed5af47dcb5957d6e2c9d0e82b01c2275 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2015-11-19  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+           Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
+
+       * sysdeps/powerpc/nptl/pthread_spin_lock.c (pthread_spin_lock):
+       Add lwarx hint, and use macro for acquire instruction.
+       * sysdeps/powerpc/nptl/pthread_spin_trylock.c (pthread_spin_trylock):
+       Likewise.
+       * sysdep/unix/sysv/linux/powerpc/pthread_spin_unlock.c: Move to ...
+       * sysdeps/powerpc/nptl/pthread_spin_unlock.c: ... here, and
+       update to use new atomic macros.
+
 2015-11-19  Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
 
        * sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
index d7d4cae6fa6e977f3689e99629a16f51adeaed85..fae7f7e0b94b6b7e9a9d677aa69163fb5c658512 100644 (file)
@@ -24,12 +24,12 @@ pthread_spin_lock (pthread_spinlock_t *lock)
   unsigned int __tmp;
 
   asm volatile (
-       "1:     lwarx   %0,0,%1\n"
+       "1:     lwarx   %0,0,%1" MUTEX_HINT_ACQ "\n"
        "       cmpwi   0,%0,0\n"
        "       bne-    2f\n"
        "       stwcx.  %2,0,%1\n"
        "       bne-    2f\n"
-       "       isync\n"
+                __ARCH_ACQ_INSTR "\n"
        "       .subsection 1\n"
        "2:     lwzx    %0,0,%1\n"
        "       cmpwi   0,%0,0\n"
index c485aa4bf93d885939ed79d2e1548843ca667187..09791c36a8e1f6c1119014618c61da6d4c9c5a35 100644 (file)
@@ -25,13 +25,13 @@ pthread_spin_trylock (pthread_spinlock_t *lock)
   unsigned int old;
   int err = EBUSY;
 
-  asm ("1:     lwarx   %0,0,%2\n"
+  asm ("1:     lwarx   %0,0,%2" MUTEX_HINT_ACQ "\n"
        "       cmpwi   0,%0,0\n"
        "       bne     2f\n"
        "       stwcx.  %3,0,%2\n"
        "       bne-    1b\n"
        "       li      %1,0\n"
-       "       isync\n"
+                __ARCH_ACQ_INSTR "\n"
        "2:     "
        : "=&r" (old), "=&r" (err)
        : "r" (lock), "r" (1), "1" (err)
similarity index 93%
rename from sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c
rename to sysdeps/powerpc/nptl/pthread_spin_unlock.c
index 7af694f4ab4327dbc62abfe4e765fc8d19c4c34a..f830ad2880a641644577feb8c97ab78f5f6e4d97 100644 (file)
@@ -22,7 +22,6 @@
 int
 pthread_spin_unlock (pthread_spinlock_t *lock)
 {
-  __asm __volatile (__ARCH_REL_INSTR ::: "memory");
-  *lock = 0;
+  atomic_store_release (lock, 0);
   return 0;
 }