|
|
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"
|