]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
powerpc: Optimize lock elision for pthread_mutex_t
authorPaul Murphy <murphyp@linux.vnet.ibm.com>
Tue, 12 Apr 2016 21:58:54 +0000 (16:58 -0500)
committerPaul E. Murphy <murphyp@linux.vnet.ibm.com>
Tue, 12 Apr 2016 21:59:09 +0000 (16:59 -0500)
With TLE enabled, the adapt count variable update incurs
an 8% overhead before entering the critical section of an
elided mutex.

Instead, if it is done right after leaving the critical
section, this serialization can be avoided.

This alters the existing behavior of __lll_trylock_elision
as it will only decrement the adapt_count if it successfully
acquires the lock.

* sysdeps/unix/sysv/linux/powerpc/elision-lock.c
(__lll_lock_elision): Remove adapt_count decrement...
* sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
(__lll_trylock_elision): Likewise.
* sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
(__lll_unlock_elision): ... to here. And utilize
new adapt_count parameter.
* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
(__lll_unlock_elision): Update to include adapt_count
parameter.
(lll_unlock_elision): Pass pointer to adapt_count
variable.

(cherry picked from commit fadd2ad9cc36115440d50b0eae9299e65988917d)

ChangeLog
sysdeps/unix/sysv/linux/powerpc/elision-lock.c
sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
sysdeps/unix/sysv/linux/powerpc/lowlevellock.h

index c9b99741ae7b8ee511ded16f8fd3b059b7f71a15..93a5ed6da52e1c95fb460e22d61953dd4db94545 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2016-04-12  Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/elision-lock.c
+       (__lll_lock_elision): Remove adapt_count decrement...
+       * sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
+       (__lll_trylock_elision): Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
+       (__lll_unlock_elision): ... to here. And utilize
+       new adapt_count parameter.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+       (__lll_unlock_elision): Update to include adapt_count
+       parameter.
+       (lll_unlock_elision): Pass pointer to adapt_count
+       variable.
+
 2016-04-12  Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
 
        * nptl/pthread_mutex_unlock.c (lll_unlock_elision):
index 82399de49a897f8a4e3d65bfad7f9970828d4fa2..2a0e5407dd2d2f42f575b64ffe15884b75e44abf 100644 (file)
@@ -47,7 +47,6 @@ __lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared)
 {
   if (*adapt_count > 0)
     {
-      (*adapt_count)--;
       goto use_lock;
     }
 
index 5995e77ad6cad8706a543d59019f7fcadc96cf7d..b391116b64c38e762adda99241764f28dc01d9d6 100644 (file)
@@ -36,7 +36,6 @@ __lll_trylock_elision (int *futex, short *adapt_count)
   /* Only try a transaction if it's worth it.  */
   if (*adapt_count > 0)
     {
-      (*adapt_count)--;
       goto use_lock;
     }
 
index 7234db6e2d36fe83873ecea63d5c6ed1294c75ac..4b4ae62d9fd6f32a4f055eb3b5d241242dc5bfa6 100644 (file)
 #include "htm.h"
 
 int
-__lll_unlock_elision(int *lock, int pshared)
+__lll_unlock_elision (int *lock, short *adapt_count, int pshared)
 {
   /* When the lock was free we're in a transaction.  */
   if (*lock == 0)
     __libc_tend (0);
   else
-    lll_unlock ((*lock), pshared);
+    {
+      lll_unlock ((*lock), pshared);
+
+      /* Update the adapt count AFTER completing the critical section.
+         Doing this here prevents unneeded stalling when entering
+         a critical section.  Saving about 8% runtime on P8.  */
+      if (*adapt_count > 0)
+       (*adapt_count)--;
+    }
   return 0;
 }
index 16479e77530f3a3de03ca44df68e619822b6d06e..6769c253ceebbd3342d02573f2d1a05b9af65210 100644 (file)
@@ -32,7 +32,7 @@ extern int __lll_timedlock_elision
 extern int __lll_lock_elision (int *futex, short *adapt_count, int private)
   attribute_hidden;
 
-extern int __lll_unlock_elision(int *lock, int private)
+extern int __lll_unlock_elision (int *lock, short *adapt_count, int private)
   attribute_hidden;
 
 extern int __lll_trylock_elision(int *lock, short *adapt_count)
@@ -41,7 +41,7 @@ extern int __lll_trylock_elision(int *lock, short *adapt_count)
 #define lll_lock_elision(futex, adapt_count, private) \
   __lll_lock_elision (&(futex), &(adapt_count), private)
 #define lll_unlock_elision(futex, adapt_count, private) \
-  __lll_unlock_elision (&(futex), private)
+  __lll_unlock_elision (&(futex), &(adapt_count), private)
 #define lll_trylock_elision(futex, adapt_count) \
   __lll_trylock_elision (&(futex), &(adapt_count))