aboutsummaryrefslogtreecommitdiff
path: root/nptl/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/Makefile10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h25
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c82
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/elision-conf.h44
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c119
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/elision-timed.c26
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c94
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c38
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/force-elision.h33
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h27
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c22
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_lock.c22
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_timedlock.c22
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_trylock.c22
14 files changed, 584 insertions, 2 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/Makefile b/nptl/sysdeps/unix/sysv/linux/s390/Makefile
new file mode 100644
index 0000000000..269832f999
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/Makefile
@@ -0,0 +1,10 @@
+ifeq ($(enable-lock-elision),yes)
+libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
+ elision-trylock
+
+elision-CFLAGS = -mhtm
+CFLAGS-elision-lock.c = $(elision-CFLAGS)
+CFLAGS-elision-timed.c = $(elision-CFLAGS)
+CFLAGS-elision-trylock.c = $(elision-CFLAGS)
+CFLAGS-elision-unlock.c = $(elision-CFLAGS)
+endif
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
index 8264de0591..d70f8b35b1 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
@@ -89,14 +89,37 @@ typedef union
binary compatibility. */
int __kind;
#if __WORDSIZE == 64
+# ifdef ENABLE_LOCK_ELISION
+ short __spins;
+ short __elision;
+ /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
+# define __PTHREAD_SPINS 0, 0
+# else
int __spins;
+ /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
+# define __PTHREAD_SPINS 0
+# endif
__pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV 1
#else
unsigned int __nusers;
__extension__ union
{
+# ifdef ENABLE_LOCK_ELISION
+ struct
+ {
+ short __espins;
+ short __elision;
+ } _d;
+# define __spins _d.__espins
+# define __elision _d.__elision
+ /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
+# define __PTHREAD_SPINS { 0, 0 }
+# else
int __spins;
+ /* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
+# define __PTHREAD_SPINS 0
+# endif
__pthread_slist_t __list;
};
#endif
@@ -105,8 +128,6 @@ typedef union
long int __align;
} pthread_mutex_t;
-/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
-#define __PTHREAD_SPINS 0
typedef union
{
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c
new file mode 100644
index 0000000000..69c04836ed
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c
@@ -0,0 +1,82 @@
+/* Lock elision tunable parameters.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <pthreadP.h>
+#include <elision-conf.h>
+#include <unistd.h>
+#include <dl-procinfo.h>
+
+/* Reasonable initial tuning values, may be revised in the future.
+ This is a conservative initial value. */
+
+struct elision_config __elision_aconf =
+ {
+ /* How often to not attempt to use elision if a transaction aborted
+ because the lock is already acquired. Expressed in number of lock
+ acquisition attempts. */
+ .skip_lock_busy = 3,
+ /* How often to not attempt to use elision if a transaction aborted due
+ to reasons other than other threads' memory accesses. Expressed in
+ number of lock acquisition attempts. */
+ .skip_lock_internal_abort = 3,
+ /* How often to not attempt to use elision if a lock used up all retries
+ without success. Expressed in number of lock acquisition attempts. */
+ .skip_lock_out_of_tbegin_retries = 3,
+ /* How often we try using elision if there is chance for the transaction
+ to finish execution (e.g., it wasn't aborted due to the lock being
+ already acquired. */
+ .try_tbegin = 3,
+ /* Same as SKIP_LOCK_INTERNAL_ABORT but for trylock. */
+ .skip_trylock_internal_abort = 3,
+ };
+
+/* Force elision for all new locks. This is used to decide whether existing
+ DEFAULT locks should be automatically upgraded to elision in
+ pthread_mutex_lock(). Disabled for suid programs. Only used when elision
+ is available. */
+
+int __pthread_force_elision attribute_hidden = 0;
+
+/* Initialize elison. */
+
+static void
+elision_init (int argc __attribute__ ((unused)),
+ char **argv __attribute__ ((unused)),
+ char **environ)
+{
+ /* Set when the CPU and the kernel supports transactional execution.
+ When false elision is never attempted. */
+ int elision_available = (GLRO (dl_hwcap) & HWCAP_S390_TE) ? 1 : 0;
+
+ __pthread_force_elision = __libc_enable_secure ? 0 : elision_available;
+}
+
+#ifdef SHARED
+# define INIT_SECTION ".init_array"
+# define MAYBE_CONST
+#else
+# define INIT_SECTION ".preinit_array"
+# define MAYBE_CONST const
+#endif
+
+void (*MAYBE_CONST __pthread_init_array []) (int, char **, char **)
+ __attribute__ ((section (INIT_SECTION), aligned (sizeof (void *)))) =
+{
+ &elision_init
+};
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.h b/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.h
new file mode 100644
index 0000000000..d9e97947a0
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.h
@@ -0,0 +1,44 @@
+/* Lock elision tunable parameters.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+#ifdef ENABLE_LOCK_ELISION
+#ifndef _ELISION_CONF_H
+#define _ELISION_CONF_H 1
+
+#include <pthread.h>
+#include <time.h>
+
+/* Should make sure there is no false sharing on this. */
+
+struct elision_config
+{
+ int skip_lock_busy;
+ int skip_lock_internal_abort;
+ int skip_lock_out_of_tbegin_retries;
+ int try_tbegin;
+ int skip_trylock_internal_abort;
+};
+
+extern struct elision_config __elision_aconf attribute_hidden;
+
+extern int __pthread_force_elision attribute_hidden;
+
+/* Tell the test suite to test elision for this architecture. */
+#define HAVE_ELISION 1
+
+#endif
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c
new file mode 100644
index 0000000000..ba5338fbb9
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c
@@ -0,0 +1,119 @@
+/* Elided pthread mutex lock.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <pthreadP.h>
+#include <lowlevellock.h>
+#include <htmintrin.h>
+#include <elision-conf.h>
+#include <stdint.h>
+
+#if !defined(LLL_LOCK) && !defined(EXTRAARG)
+/* Make sure the configuration code is always linked in for static
+ libraries. */
+#include "elision-conf.c"
+#endif
+
+#ifndef EXTRAARG
+#define EXTRAARG
+#endif
+#ifndef LLL_LOCK
+#define LLL_LOCK(a,b) lll_lock(a,b), 0
+#endif
+
+#define aconf __elision_aconf
+
+/* Adaptive lock using transactions.
+ By default the lock region is run as a transaction, and when it
+ aborts or the lock is busy the lock adapts itself. */
+
+int
+__lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private)
+{
+ if (*adapt_count > 0)
+ {
+ /* Lost updates are possible, but harmless. Due to races this might lead
+ to *adapt_count becoming less than zero. */
+ (*adapt_count)--;
+ goto use_lock;
+ }
+
+ __asm__ volatile (".machinemode \"zarch_nohighgprs\"\n\t"
+ ".machine \"all\""
+ : : : "memory");
+
+ int try_tbegin;
+ for (try_tbegin = aconf.try_tbegin;
+ try_tbegin > 0;
+ try_tbegin--)
+ {
+ unsigned status;
+ if (__builtin_expect
+ ((status = __builtin_tbegin((void *)0)) == _HTM_TBEGIN_STARTED, 1))
+ {
+ if (*futex == 0)
+ return 0;
+ /* Lock was busy. Fall back to normal locking. */
+ if (__builtin_expect (__builtin_tx_nesting_depth (), 1))
+ {
+ /* In a non-nested transaction there is no need to abort,
+ which is expensive. */
+ __builtin_tend ();
+ if (aconf.skip_lock_busy > 0)
+ *adapt_count = aconf.skip_lock_busy;
+ goto use_lock;
+ }
+ else /* nesting depth is > 1 */
+ {
+ /* A nested transaction will abort eventually because it
+ cannot make any progress before *futex changes back to 0.
+ So we may as well abort immediately.
+ This persistently aborts the outer transaction to force
+ the outer mutex use the default lock instead of retrying
+ with transactions until the try_tbegin of the outer mutex
+ is zero.
+ The adapt_count of this inner mutex is not changed,
+ because using the default lock with the inner mutex
+ would abort the outer transaction.
+ */
+ __builtin_tabort (_HTM_FIRST_USER_ABORT_CODE | 1);
+ }
+ }
+ else
+ {
+ if (status != _HTM_TBEGIN_TRANSIENT)
+ {
+ /* A persistent abort (cc 1 or 3) indicates that a retry is
+ probably futile. Use the normal locking now and for the
+ next couple of calls.
+ Be careful to avoid writing to the lock. */
+ if (aconf.skip_lock_internal_abort > 0)
+ *adapt_count = aconf.skip_lock_internal_abort;
+ goto use_lock;
+ }
+ }
+ }
+
+ /* Same logic as above, but for for a number of temporary failures in a
+ row. */
+ if (aconf.skip_lock_out_of_tbegin_retries > 0 && aconf.try_tbegin > 0)
+ *adapt_count = aconf.skip_lock_out_of_tbegin_retries;
+
+ use_lock:
+ return LLL_LOCK ((*futex), private);
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-timed.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-timed.c
new file mode 100644
index 0000000000..a8d8b2a348
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-timed.c
@@ -0,0 +1,26 @@
+/* Lock elision timed lock.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+#include <elision-conf.h>
+#include <lowlevellock.h>
+#define __lll_lock_elision __lll_timedlock_elision
+#define EXTRAARG const struct timespec *t,
+#undef LLL_LOCK
+#define LLL_LOCK(a, b) lll_timedlock(a, t, b)
+#include "elision-lock.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c
new file mode 100644
index 0000000000..61447d6bf4
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c
@@ -0,0 +1,94 @@
+/* Elided pthread mutex trylock.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <pthreadP.h>
+#include <lowlevellock.h>
+#include <htmintrin.h>
+#include <elision-conf.h>
+
+#define aconf __elision_aconf
+
+/* Try to elide a futex trylock. FUTEX is the futex variable. ADAPT_COUNT is
+ the adaptation counter in the mutex. */
+
+int
+__lll_trylock_elision (int *futex, short *adapt_count)
+{
+ __asm__ volatile (".machinemode \"zarch_nohighgprs\"\n\t"
+ ".machine \"all\""
+ : : : "memory");
+
+ /* Implement POSIX semantics by forbiding nesting elided trylocks.
+ Sorry. After the abort the code is re-executed
+ non transactional and if the lock was already locked
+ return an error. */
+ if (__builtin_tx_nesting_depth () > 0)
+ {
+ /* Note that this abort may terminate an outermost transaction that
+ was created outside glibc.
+ This persistently aborts the current transactions to force
+ them to use the default lock instead of retrying transactions
+ until their try_tbegin is zero.
+ */
+ __builtin_tabort (_HTM_FIRST_USER_ABORT_CODE | 1);
+ }
+
+ /* Only try a transaction if it's worth it. */
+ if (*adapt_count <= 0)
+ {
+ unsigned status;
+
+ if (__builtin_expect
+ ((status = __builtin_tbegin ((void *)0)) == _HTM_TBEGIN_STARTED, 1))
+ {
+ if (*futex == 0)
+ return 0;
+ /* Lock was busy. Fall back to normal locking. */
+ /* Since we are in a non-nested transaction there is no need to abort,
+ which is expensive. */
+ __builtin_tend ();
+ /* Note: Changing the adapt_count here might abort a transaction on a
+ different cpu, but that could happen anyway when the futex is
+ acquired, so there's no need to check the nesting depth here. */
+ if (aconf.skip_lock_busy > 0)
+ *adapt_count = aconf.skip_lock_busy;
+ }
+ else
+ {
+ if (status != _HTM_TBEGIN_TRANSIENT)
+ {
+ /* A persistent abort (cc 1 or 3) indicates that a retry is
+ probably futile. Use the normal locking now and for the
+ next couple of calls.
+ Be careful to avoid writing to the lock. */
+ if (aconf.skip_trylock_internal_abort > 0)
+ *adapt_count = aconf.skip_trylock_internal_abort;
+ }
+ }
+ /* Could do some retries here. */
+ }
+ else
+ {
+ /* Lost updates are possible, but harmless. Due to races this might lead
+ to *adapt_count becoming less than zero. */
+ (*adapt_count)--;
+ }
+
+ return lll_trylock (*futex);
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c
new file mode 100644
index 0000000000..9ceae3ee1e
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c
@@ -0,0 +1,38 @@
+/* Commit an elided pthread lock.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pthreadP.h>
+#include <lowlevellock.h>
+
+int
+__lll_unlock_elision(int *futex, int private)
+{
+ /* If the lock is free, we elided the lock earlier. This does not
+ necessarily mean that we are in a transaction, because the user code may
+ have closed the transaction, but that is impossible to detect reliably. */
+ if (*futex == 0)
+ {
+ __asm__ volatile (".machinemode \"zarch_nohighgprs\"\n\t"
+ ".machine \"all\""
+ : : : "memory");
+ __builtin_tend();
+ }
+ else
+ lll_unlock ((*futex), private);
+ return 0;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/force-elision.h b/nptl/sysdeps/unix/sysv/linux/s390/force-elision.h
new file mode 100644
index 0000000000..8fd7684d9a
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/force-elision.h
@@ -0,0 +1,33 @@
+/* Automatic enabling of elision for mutexes
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef ENABLE_LOCK_ELISION
+/* Check for elision on this lock without upgrading. */
+#define DO_ELISION(m) \
+ (__pthread_force_elision \
+ && (m->__data.__kind & PTHREAD_MUTEX_NO_ELISION_NP) == 0) \
+
+/* Automatically enable elision for existing user lock kinds. */
+#define FORCE_ELISION(m, s) \
+ if (__pthread_force_elision \
+ && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ { \
+ mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
+ s; \
+ }
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
index 864dcbccc0..cabff30be9 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
@@ -285,6 +285,15 @@ __lll_timedlock (int *futex, const struct timespec *abstime, int private)
#define lll_timedlock(futex, abstime, private) \
__lll_timedlock (&(futex), abstime, private)
+#ifdef ENABLE_LOCK_ELISION
+extern int __lll_timedlock_elision
+ (int *futex, short *adapt_count, const struct timespec *timeout, int private)
+ attribute_hidden;
+
+# define lll_timedlock_elision(futex, adapt_count, timeout, private) \
+ __lll_timedlock_elision(&(futex), &(adapt_count), timeout, private)
+#endif
+
static inline int
__attribute__ ((always_inline))
__lll_robust_timedlock (int *futex, const struct timespec *abstime,
@@ -360,4 +369,22 @@ extern int __lll_timedwait_tid (int *, const struct timespec *)
__res; \
})
+#ifdef ENABLE_LOCK_ELISION
+extern int __lll_lock_elision (int *futex, short *adapt_count, int private)
+ attribute_hidden;
+
+extern int __lll_unlock_elision(int *futex, int private)
+ attribute_hidden;
+
+extern int __lll_trylock_elision(int *futex, short *adapt_count)
+ attribute_hidden;
+
+# define lll_lock_elision(futex, adapt_count, private) \
+ __lll_lock_elision (&(futex), &(adapt_count), private)
+# define lll_unlock_elision(futex, private) \
+ __lll_unlock_elision (&(futex), private)
+# define lll_trylock_elision(futex, adapt_count) \
+ __lll_trylock_elision(&(futex), &(adapt_count))
+#endif
+
#endif /* lowlevellock.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c
new file mode 100644
index 0000000000..6fc0f969ef
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c
@@ -0,0 +1,22 @@
+/* Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* The cond lock is not actually elided yet, but we still need to handle
+ already elided locks. */
+#include <elision-conf.h>
+
+#include <nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c>
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_lock.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_lock.c
new file mode 100644
index 0000000000..6fd6a9866f
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_lock.c
@@ -0,0 +1,22 @@
+/* Elided version of pthread_mutex_lock.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <elision-conf.h>
+#include <force-elision.h>
+
+#include <nptl/pthread_mutex_lock.c>
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_timedlock.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_timedlock.c
new file mode 100644
index 0000000000..d0e6537ecc
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_timedlock.c
@@ -0,0 +1,22 @@
+/* Elided version of pthread_mutex_timedlock.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <elision-conf.h>
+#include <force-elision.h>
+
+#include <nptl/pthread_mutex_timedlock.c>
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_trylock.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_trylock.c
new file mode 100644
index 0000000000..ea8a8fff93
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_trylock.c
@@ -0,0 +1,22 @@
+/* Elided version of pthread_mutex_trylock.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <elision-conf.h>
+#include <force-elision.h>
+
+#include <nptl/pthread_mutex_trylock.c>