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