ce426f
commit e8c659d74e011346785355eeef03b7fb6f533c61
ce426f
Author: Andi Kleen <ak@linux.intel.com>
ce426f
Date:   Sat Dec 22 01:03:04 2012 -0800
ce426f
ce426f
    Add elision to pthread_mutex_{try,timed,un}lock
ce426f
    
ce426f
    Add elision paths to the basic mutex locks.
ce426f
    
ce426f
    The normal path has a check for RTM and upgrades the lock
ce426f
    to RTM when available. Trylocks cannot automatically upgrade,
ce426f
    so they check for elision every time.
ce426f
    
ce426f
    We use a 4 byte value in the mutex to store the lock
ce426f
    elision adaptation state. This is separate from the adaptive
ce426f
    spin state and uses a separate field.
ce426f
    
ce426f
    Condition variables currently do not support elision.
ce426f
    
ce426f
    Recursive mutexes and condition variables may be supported at some point,
ce426f
    but are not in the current implementation. Also "trylock" will
ce426f
    not automatically enable elision unless some other lock call
ce426f
    has been already called on the lock.
ce426f
    
ce426f
    This version does not use IFUNC, so it means every lock has one
ce426f
    additional check for elision. Benchmarking showed the overhead
ce426f
    to be negligible.
ce426f
Index: glibc-2.17-c758a686/nptl/pthreadP.h
ce426f
===================================================================
ce426f
--- glibc-2.17-c758a686.orig/nptl/pthreadP.h
ce426f
+++ glibc-2.17-c758a686/nptl/pthreadP.h
ce426f
@@ -110,8 +110,10 @@ enum
ce426f
 
ce426f
 #define PTHREAD_MUTEX_TYPE(m) \
ce426f
   ((m)->__data.__kind & 127)
ce426f
+/* Don't include NO_ELISION, as that type is always the same
ce426f
+   as the underlying lock type.  */
ce426f
 #define PTHREAD_MUTEX_TYPE_ELISION(m) \
ce426f
-  ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_FLAGS_NP))
ce426f
+  ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_NP))
ce426f
 
ce426f
 #if LLL_PRIVATE == 0 && LLL_SHARED == 128
ce426f
 # define PTHREAD_MUTEX_PSHARED(m) \
ce426f
Index: glibc-2.17-c758a686/nptl/pthread_mutex_lock.c
ce426f
===================================================================
ce426f
--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_lock.c
ce426f
+++ glibc-2.17-c758a686/nptl/pthread_mutex_lock.c
ce426f
@@ -25,6 +25,14 @@
ce426f
 #include <lowlevellock.h>
ce426f
 #include <stap-probe.h>
ce426f
 
ce426f
+#ifndef lll_lock_elision
ce426f
+#define lll_lock_elision(lock, try_lock, private)	({ \
ce426f
+      lll_lock (lock, private); 0; })
ce426f
+#endif
ce426f
+
ce426f
+#ifndef lll_trylock_elision
ce426f
+#define lll_trylock_elision(a,t) lll_trylock(a)
ce426f
+#endif
ce426f
 
ce426f
 #ifndef LLL_MUTEX_LOCK
ce426f
 # define LLL_MUTEX_LOCK(mutex) \
ce426f
@@ -34,39 +42,60 @@
ce426f
 # define LLL_ROBUST_MUTEX_LOCK(mutex, id) \
ce426f
   lll_robust_lock ((mutex)->__data.__lock, id, \
ce426f
 		   PTHREAD_ROBUST_MUTEX_PSHARED (mutex))
ce426f
+# define LLL_MUTEX_LOCK_ELISION(mutex) \
ce426f
+  lll_lock_elision ((mutex)->__data.__lock, (mutex)->__data.__elision, \
ce426f
+		   PTHREAD_MUTEX_PSHARED (mutex))
ce426f
+# define LLL_MUTEX_TRYLOCK_ELISION(mutex) \
ce426f
+  lll_trylock_elision((mutex)->__data.__lock, (mutex)->__data.__elision, \
ce426f
+		   PTHREAD_MUTEX_PSHARED (mutex))
ce426f
 #endif
ce426f
 
ce426f
+#ifndef FORCE_ELISION
ce426f
+#define FORCE_ELISION(m, s)
ce426f
+#endif
ce426f
 
ce426f
 static int __pthread_mutex_lock_full (pthread_mutex_t *mutex)
ce426f
      __attribute_noinline__;
ce426f
 
ce426f
-
ce426f
 int
ce426f
 __pthread_mutex_lock (mutex)
ce426f
      pthread_mutex_t *mutex;
ce426f
 {
ce426f
   assert (sizeof (mutex->__size) >= sizeof (mutex->__data));
ce426f
 
ce426f
-  unsigned int type = PTHREAD_MUTEX_TYPE (mutex);
ce426f
+  unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
ce426f
 
ce426f
   LIBC_PROBE (mutex_entry, 1, mutex);
ce426f
 
ce426f
-  if (__builtin_expect (type & ~PTHREAD_MUTEX_KIND_MASK_NP, 0))
ce426f
+  if (__builtin_expect (type & ~(PTHREAD_MUTEX_KIND_MASK_NP
ce426f
+				 | PTHREAD_MUTEX_ELISION_FLAGS_NP), 0))
ce426f
     return __pthread_mutex_lock_full (mutex);
ce426f
 
ce426f
-  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
ce426f
-
ce426f
-  if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP)
ce426f
-      == PTHREAD_MUTEX_TIMED_NP)
ce426f
+  if (__builtin_expect (type == PTHREAD_MUTEX_TIMED_NP, 1))
ce426f
     {
ce426f
+      FORCE_ELISION (mutex, goto elision);
ce426f
     simple:
ce426f
       /* Normal mutex.  */
ce426f
       LLL_MUTEX_LOCK (mutex);
ce426f
       assert (mutex->__data.__owner == 0);
ce426f
     }
ce426f
-  else if (__builtin_expect (type == PTHREAD_MUTEX_RECURSIVE_NP, 1))
ce426f
+#ifdef HAVE_ELISION
ce426f
+  else if (__builtin_expect (type == PTHREAD_MUTEX_TIMED_ELISION_NP, 1))
ce426f
+    {
ce426f
+  elision: __attribute__((unused))
ce426f
+      /* This case can never happen on a system without elision,
ce426f
+         as the mutex type initialization functions will not
ce426f
+	 allow to set the elision flags.  */
ce426f
+      /* Don't record owner or users for elision case. This is a
ce426f
+         tail call.  */
ce426f
+      return LLL_MUTEX_LOCK_ELISION (mutex);
ce426f
+    }
ce426f
+#endif
ce426f
+  else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex)
ce426f
+			     == PTHREAD_MUTEX_RECURSIVE_NP, 1))
ce426f
     {
ce426f
       /* Recursive mutex.  */
ce426f
+      pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
ce426f
 
ce426f
       /* Check whether we already hold the mutex.  */
ce426f
       if (mutex->__data.__owner == id)
ce426f
@@ -87,7 +116,8 @@ __pthread_mutex_lock (mutex)
ce426f
       assert (mutex->__data.__owner == 0);
ce426f
       mutex->__data.__count = 1;
ce426f
     }
ce426f
-  else if (__builtin_expect (type == PTHREAD_MUTEX_ADAPTIVE_NP, 1))
ce426f
+  else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex)
ce426f
+			  == PTHREAD_MUTEX_ADAPTIVE_NP, 1))
ce426f
     {
ce426f
       if (! __is_smp)
ce426f
 	goto simple;
ce426f
@@ -117,13 +147,16 @@ __pthread_mutex_lock (mutex)
ce426f
     }
ce426f
   else
ce426f
     {
ce426f
-      assert (type == PTHREAD_MUTEX_ERRORCHECK_NP);
ce426f
+      pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
ce426f
+      assert (PTHREAD_MUTEX_TYPE (mutex) == PTHREAD_MUTEX_ERRORCHECK_NP);
ce426f
       /* Check whether we already hold the mutex.  */
ce426f
       if (__builtin_expect (mutex->__data.__owner == id, 0))
ce426f
 	return EDEADLK;
ce426f
       goto simple;
ce426f
     }
ce426f
 
ce426f
+  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
ce426f
+
ce426f
   /* Record the ownership.  */
ce426f
   mutex->__data.__owner = id;
ce426f
 #ifndef NO_INCR
ce426f
Index: glibc-2.17-c758a686/nptl/pthread_mutex_timedlock.c
ce426f
===================================================================
ce426f
--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_timedlock.c
ce426f
+++ glibc-2.17-c758a686/nptl/pthread_mutex_timedlock.c
ce426f
@@ -25,6 +25,17 @@
ce426f
 
ce426f
 #include <stap-probe.h>
ce426f
 
ce426f
+#ifndef lll_timedlock_elision
ce426f
+#define lll_timedlock_elision(a,dummy,b,c) lll_timedlock(a, b, c)
ce426f
+#endif
ce426f
+
ce426f
+#ifndef lll_trylock_elision
ce426f
+#define lll_trylock_elision(a,t) lll_trylock(a)
ce426f
+#endif
ce426f
+
ce426f
+#ifndef FORCE_ELISION
ce426f
+#define FORCE_ELISION(m, s)
ce426f
+#endif
ce426f
 
ce426f
 int
ce426f
 pthread_mutex_timedlock (mutex, abstime)
ce426f
@@ -40,10 +51,11 @@ pthread_mutex_timedlock (mutex, abstime)
ce426f
   /* We must not check ABSTIME here.  If the thread does not block
ce426f
      abstime must not be checked for a valid value.  */
ce426f
 
ce426f
-  switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex),
ce426f
+  switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex),
ce426f
 			    PTHREAD_MUTEX_TIMED_NP))
ce426f
     {
ce426f
       /* Recursive mutex.  */
ce426f
+    case PTHREAD_MUTEX_RECURSIVE_NP|PTHREAD_MUTEX_ELISION_NP:
ce426f
     case PTHREAD_MUTEX_RECURSIVE_NP:
ce426f
       /* Check whether we already hold the mutex.  */
ce426f
       if (mutex->__data.__owner == id)
ce426f
@@ -78,12 +90,22 @@ pthread_mutex_timedlock (mutex, abstime)
ce426f
       /* FALLTHROUGH */
ce426f
 
ce426f
     case PTHREAD_MUTEX_TIMED_NP:
ce426f
+      FORCE_ELISION (mutex, goto elision);
ce426f
     simple:
ce426f
       /* Normal mutex.  */
ce426f
       result = lll_timedlock (mutex->__data.__lock, abstime,
ce426f
 			      PTHREAD_MUTEX_PSHARED (mutex));
ce426f
       break;
ce426f
 
ce426f
+    case PTHREAD_MUTEX_TIMED_ELISION_NP:
ce426f
+    elision: __attribute__((unused))
ce426f
+      /* Don't record ownership */
ce426f
+      return lll_timedlock_elision (mutex->__data.__lock,
ce426f
+				    mutex->__data.__spins,
ce426f
+				    abstime,
ce426f
+				    PTHREAD_MUTEX_PSHARED (mutex));
ce426f
+
ce426f
+
ce426f
     case PTHREAD_MUTEX_ADAPTIVE_NP:
ce426f
       if (! __is_smp)
ce426f
 	goto simple;
ce426f
Index: glibc-2.17-c758a686/nptl/pthread_mutex_trylock.c
ce426f
===================================================================
ce426f
--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_trylock.c
ce426f
+++ glibc-2.17-c758a686/nptl/pthread_mutex_trylock.c
ce426f
@@ -22,6 +22,16 @@
ce426f
 #include "pthreadP.h"
ce426f
 #include <lowlevellock.h>
ce426f
 
ce426f
+#ifndef lll_trylock_elision
ce426f
+#define lll_trylock_elision(a,t) lll_trylock(a)
ce426f
+#endif
ce426f
+
ce426f
+#ifndef DO_ELISION
ce426f
+#define DO_ELISION(m) 0
ce426f
+#endif
ce426f
+
ce426f
+/* We don't force elision in trylock, because this can lead to inconsistent
ce426f
+   lock state if the lock was actually busy. */
ce426f
 
ce426f
 int
ce426f
 __pthread_mutex_trylock (mutex)
ce426f
@@ -30,10 +40,11 @@ __pthread_mutex_trylock (mutex)
ce426f
   int oldval;
ce426f
   pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
ce426f
 
ce426f
-  switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex),
ce426f
+  switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex),
ce426f
 			    PTHREAD_MUTEX_TIMED_NP))
ce426f
     {
ce426f
       /* Recursive mutex.  */
ce426f
+    case PTHREAD_MUTEX_RECURSIVE_NP|PTHREAD_MUTEX_ELISION_NP:
ce426f
     case PTHREAD_MUTEX_RECURSIVE_NP:
ce426f
       /* Check whether we already hold the mutex.  */
ce426f
       if (mutex->__data.__owner == id)
ce426f
@@ -57,10 +68,20 @@ __pthread_mutex_trylock (mutex)
ce426f
 	}
ce426f
       break;
ce426f
 
ce426f
-    case PTHREAD_MUTEX_ERRORCHECK_NP:
ce426f
+    case PTHREAD_MUTEX_TIMED_ELISION_NP:
ce426f
+    elision:
ce426f
+      if (lll_trylock_elision (mutex->__data.__lock,
ce426f
+			       mutex->__data.__elision) != 0)
ce426f
+        break;
ce426f
+      /* Don't record the ownership. */
ce426f
+      return 0;
ce426f
+
ce426f
     case PTHREAD_MUTEX_TIMED_NP:
ce426f
+      if (DO_ELISION (mutex))
ce426f
+	goto elision;
ce426f
+      /*FALL THROUGH*/
ce426f
     case PTHREAD_MUTEX_ADAPTIVE_NP:
ce426f
-      /* Normal mutex.  */
ce426f
+    case PTHREAD_MUTEX_ERRORCHECK_NP:
ce426f
       if (lll_trylock (mutex->__data.__lock) != 0)
ce426f
 	break;
ce426f
 
ce426f
@@ -378,4 +399,9 @@ __pthread_mutex_trylock (mutex)
ce426f
 
ce426f
   return EBUSY;
ce426f
 }
ce426f
+
ce426f
+#ifndef __pthread_mutex_trylock
ce426f
+#ifndef pthread_mutex_trylock
ce426f
 strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)
ce426f
+#endif
ce426f
+#endif
ce426f
Index: glibc-2.17-c758a686/nptl/pthread_mutex_unlock.c
ce426f
===================================================================
ce426f
--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_unlock.c
ce426f
+++ glibc-2.17-c758a686/nptl/pthread_mutex_unlock.c
ce426f
@@ -23,6 +23,10 @@
ce426f
 #include <lowlevellock.h>
ce426f
 #include <stap-probe.h>
ce426f
 
ce426f
+#ifndef lll_unlock_elision
ce426f
+#define lll_unlock_elision(a,b) ({ lll_unlock (a,b); 0; })
ce426f
+#endif
ce426f
+
ce426f
 static int
ce426f
 internal_function
ce426f
 __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
ce426f
@@ -34,8 +38,9 @@ __pthread_mutex_unlock_usercnt (mutex, d
ce426f
      pthread_mutex_t *mutex;
ce426f
      int decr;
ce426f
 {
ce426f
-  int type = PTHREAD_MUTEX_TYPE (mutex);
ce426f
-  if (__builtin_expect (type & ~PTHREAD_MUTEX_KIND_MASK_NP, 0))
ce426f
+  int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
ce426f
+  if (__builtin_expect (type &
ce426f
+		~(PTHREAD_MUTEX_KIND_MASK_NP|PTHREAD_MUTEX_ELISION_FLAGS_NP), 0))
ce426f
     return __pthread_mutex_unlock_full (mutex, decr);
ce426f
 
ce426f
   if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP)
ce426f
@@ -55,7 +60,14 @@ __pthread_mutex_unlock_usercnt (mutex, d
ce426f
 
ce426f
       return 0;
ce426f
     }
ce426f
-  else if (__builtin_expect (type == PTHREAD_MUTEX_RECURSIVE_NP, 1))
ce426f
+  else if (__builtin_expect (type == PTHREAD_MUTEX_TIMED_ELISION_NP, 1))
ce426f
+    {
ce426f
+      /* Don't reset the owner/users fields for elision.  */
ce426f
+      return lll_unlock_elision (mutex->__data.__lock,
ce426f
+				      PTHREAD_MUTEX_PSHARED (mutex));
ce426f
+    }
ce426f
+  else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex)
ce426f
+			      == PTHREAD_MUTEX_RECURSIVE_NP, 1))
ce426f
     {
ce426f
       /* Recursive mutex.  */
ce426f
       if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
ce426f
@@ -66,7 +78,8 @@ __pthread_mutex_unlock_usercnt (mutex, d
ce426f
 	return 0;
ce426f
       goto normal;
ce426f
     }
ce426f
-  else if (__builtin_expect (type == PTHREAD_MUTEX_ADAPTIVE_NP, 1))
ce426f
+  else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex)
ce426f
+			      == PTHREAD_MUTEX_ADAPTIVE_NP, 1))
ce426f
     goto normal;
ce426f
   else
ce426f
     {
ce426f
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
ce426f
===================================================================
ce426f
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
ce426f
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
ce426f
@@ -2,8 +2,15 @@
ce426f
 
ce426f
 #define LLL_MUTEX_LOCK(mutex) \
ce426f
   lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex))
ce426f
+
ce426f
+/* Not actually elided so far. Needed? */
ce426f
+#define LLL_MUTEX_LOCK_ELISION(mutex)  \
ce426f
+  ({ lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)); 0; })
ce426f
+
ce426f
 #define LLL_MUTEX_TRYLOCK(mutex) \
ce426f
   lll_cond_trylock ((mutex)->__data.__lock)
ce426f
+#define LLL_MUTEX_TRYLOCK_ELISION(mutex) LLL_MUTEX_TRYLOCK(mutex)
ce426f
+
ce426f
 #define LLL_ROBUST_MUTEX_LOCK(mutex, id) \
ce426f
   lll_robust_cond_lock ((mutex)->__data.__lock, id, \
ce426f
 			PTHREAD_ROBUST_MUTEX_PSHARED (mutex))
ce426f
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h
ce426f
===================================================================
ce426f
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h
ce426f
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h
ce426f
@@ -101,14 +101,23 @@ typedef union
ce426f
        binary compatibility.  */
ce426f
     int __kind;
ce426f
 #ifdef __x86_64__
ce426f
-    int __spins;
ce426f
+    short __spins;
ce426f
+    short __elision;
ce426f
     __pthread_list_t __list;
ce426f
 # define __PTHREAD_MUTEX_HAVE_PREV	1
ce426f
+# define __PTHREAD_MUTEX_HAVE_ELISION   1
ce426f
 #else
ce426f
     unsigned int __nusers;
ce426f
     __extension__ union
ce426f
     {
ce426f
-      int __spins;
ce426f
+      struct
ce426f
+      {
ce426f
+        short __espins;
ce426f
+	short __elision;
ce426f
+# define __spins d.__espins
ce426f
+# define __elision d.__elision
ce426f
+# define __PTHREAD_MUTEX_HAVE_ELISION   2
ce426f
+      } d;
ce426f
       __pthread_slist_t __list;
ce426f
     };
ce426f
 #endif
ce426f
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c
ce426f
===================================================================
ce426f
--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c
ce426f
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c
ce426f
@@ -24,9 +24,8 @@
ce426f
 
ce426f
 #define aconf __elision_aconf
ce426f
 
ce426f
-/* Try to elide a futex trylock. FUTEX is the futex variable. TRY_LOCK is the
ce426f
-   adaptation counter in the mutex. UPGRADED is != 0 when this is for an
ce426f
-   automatically upgraded lock.  */
ce426f
+/* Try to elide a futex trylock. FUTEX is the futex variable. ADAPT_COUNT is the
ce426f
+   adaptation counter in the mutex.  */
ce426f
 
ce426f
 int
ce426f
 __lll_trylock_elision (int *futex, short *adapt_count)
ce426f
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h
ce426f
===================================================================
ce426f
--- /dev/null
ce426f
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h
ce426f
@@ -0,0 +1,31 @@
ce426f
+/* force-elision.h: Automatic enabling of elision for mutexes
ce426f
+   Copyright (C) 2013 Free Software Foundation, Inc.
ce426f
+   This file is part of the GNU C Library.
ce426f
+
ce426f
+   The GNU C Library is free software; you can redistribute it and/or
ce426f
+   modify it under the terms of the GNU Lesser General Public
ce426f
+   License as published by the Free Software Foundation; either
ce426f
+   version 2.1 of the License, or (at your option) any later version.
ce426f
+
ce426f
+   The GNU C Library is distributed in the hope that it will be useful,
ce426f
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
ce426f
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
ce426f
+   Lesser General Public License for more details.
ce426f
+
ce426f
+   You should have received a copy of the GNU Lesser General Public
ce426f
+   License along with the GNU C Library; if not, see
ce426f
+   <http://www.gnu.org/licenses/>. */
ce426f
+
ce426f
+/* Check for elision on this lock without upgrading.  */
ce426f
+#define DO_ELISION(m)							\
ce426f
+  (__pthread_force_elision						\
ce426f
+   && (m->__data.__kind & PTHREAD_MUTEX_NO_ELISION_NP) == 0)		\
ce426f
+
ce426f
+/* Automatically enable elision for existing user lock kinds.  */
ce426f
+#define FORCE_ELISION(m, s)						\
ce426f
+  if (__pthread_force_elision						\
ce426f
+      && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0)	\
ce426f
+    {									\
ce426f
+      mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP;			\
ce426f
+      s;								\
ce426f
+    }
ce426f
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c
ce426f
===================================================================
ce426f
--- /dev/null
ce426f
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c
ce426f
@@ -0,0 +1,21 @@
ce426f
+/* Copyright (C) 2013 Free Software Foundation, Inc.
ce426f
+   This file is part of the GNU C Library.
ce426f
+
ce426f
+   The GNU C Library is free software; you can redistribute it and/or
ce426f
+   modify it under the terms of the GNU Lesser General Public
ce426f
+   License as published by the Free Software Foundation; either
ce426f
+   version 2.1 of the License, or (at your option) any later version.
ce426f
+
ce426f
+   The GNU C Library is distributed in the hope that it will be useful,
ce426f
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
ce426f
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
ce426f
+   Lesser General Public License for more details.
ce426f
+
ce426f
+   You should have received a copy of the GNU Lesser General Public
ce426f
+   License along with the GNU C Library; if not, see
ce426f
+   <http://www.gnu.org/licenses/>. */
ce426f
+
ce426f
+/* The cond lock is not actually elided yet, but we still need to handle
ce426f
+   already elided locks.  */
ce426f
+#include <elision-conf.h>
ce426f
+#include "sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c"
ce426f
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c
ce426f
===================================================================
ce426f
--- /dev/null
ce426f
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c
ce426f
@@ -0,0 +1,21 @@
ce426f
+/* Elided version of pthread_mutex_lock.
ce426f
+   Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc.
ce426f
+   This file is part of the GNU C Library.
ce426f
+
ce426f
+   The GNU C Library is free software; you can redistribute it and/or
ce426f
+   modify it under the terms of the GNU Lesser General Public
ce426f
+   License as published by the Free Software Foundation; either
ce426f
+   version 2.1 of the License, or (at your option) any later version.
ce426f
+
ce426f
+   The GNU C Library is distributed in the hope that it will be useful,
ce426f
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
ce426f
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
ce426f
+   Lesser General Public License for more details.
ce426f
+
ce426f
+   You should have received a copy of the GNU Lesser General Public
ce426f
+   License along with the GNU C Library; if not, see
ce426f
+   <http://www.gnu.org/licenses/>. */
ce426f
+#include <elision-conf.h>
ce426f
+#include "force-elision.h"
ce426f
+
ce426f
+#include "nptl/pthread_mutex_lock.c"
ce426f
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c
ce426f
===================================================================
ce426f
--- /dev/null
ce426f
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c
ce426f
@@ -0,0 +1,20 @@
ce426f
+/* Elided version of pthread_mutex_timedlock.
ce426f
+   Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc.
ce426f
+   This file is part of the GNU C Library.
ce426f
+
ce426f
+   The GNU C Library is free software; you can redistribute it and/or
ce426f
+   modify it under the terms of the GNU Lesser General Public
ce426f
+   License as published by the Free Software Foundation; either
ce426f
+   version 2.1 of the License, or (at your option) any later version.
ce426f
+
ce426f
+   The GNU C Library is distributed in the hope that it will be useful,
ce426f
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
ce426f
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
ce426f
+   Lesser General Public License for more details.
ce426f
+
ce426f
+   You should have received a copy of the GNU Lesser General Public
ce426f
+   License along with the GNU C Library; if not, see
ce426f
+   <http://www.gnu.org/licenses/>. */
ce426f
+#include <elision-conf.h>
ce426f
+#include "force-elision.h"
ce426f
+#include "nptl/pthread_mutex_timedlock.c"
ce426f
Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c
ce426f
===================================================================
ce426f
--- /dev/null
ce426f
+++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c
ce426f
@@ -0,0 +1,21 @@
ce426f
+/* Elided version of pthread_mutex_trylock.
ce426f
+   Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc.
ce426f
+   This file is part of the GNU C Library.
ce426f
+
ce426f
+   The GNU C Library is free software; you can redistribute it and/or
ce426f
+   modify it under the terms of the GNU Lesser General Public
ce426f
+   License as published by the Free Software Foundation; either
ce426f
+   version 2.1 of the License, or (at your option) any later version.
ce426f
+
ce426f
+   The GNU C Library is distributed in the hope that it will be useful,
ce426f
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
ce426f
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
ce426f
+   Lesser General Public License for more details.
ce426f
+
ce426f
+   You should have received a copy of the GNU Lesser General Public
ce426f
+   License along with the GNU C Library; if not, see
ce426f
+   <http://www.gnu.org/licenses/>. */
ce426f
+#include <elision-conf.h>
ce426f
+#include "force-elision.h"
ce426f
+
ce426f
+#include "nptl/pthread_mutex_trylock.c"