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