This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[ping2][PATCH 2/2] Port of lock elision to System/z v2
- From: Dominik Vogt <vogt at linux dot vnet dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Cc: triegel at redhat dot com
- Date: Tue, 5 Nov 2013 06:52:04 +0100
- Subject: [ping2][PATCH 2/2] Port of lock elision to System/z v2
- Authentication-results: sourceware.org; auth=none
- References: <20130920105941 dot GB374 at linux dot vnet dot ibm dot com>
- Reply-to: libc-alpha at sourceware dot org
> Implementation of lock elision for pthread_mutexes. Similar to
> the Intel patches, but with significant modifications regarding
> performance of the patches.
>
> Ciao
>
> Dominik ^_^ ^_^
>
> --
>
> Dominik Vogt
> IBM Germany
>From 5015d7e930d7057f2af4f9df9e6ba86747b3c178 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@de.ibm.com>
Date: Wed, 10 Apr 2013 15:14:17 +0200
Subject: [PATCH 02/10] s390: Elided pthread_mutexes.
---
nptl/sysdeps/unix/sysv/linux/s390/Makefile | 2 +-
.../unix/sysv/linux/s390/bits/pthreadtypes.h | 12 +++-
nptl/sysdeps/unix/sysv/linux/s390/elision-common.c | 22 ------
nptl/sysdeps/unix/sysv/linux/s390/elision-common.h | 25 -------
nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c | 7 +-
nptl/sysdeps/unix/sysv/linux/s390/elision-conf.h | 3 +-
nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c | 78 ++++++++++++----------
.../sysdeps/unix/sysv/linux/s390/elision-trylock.c | 57 +++++++++-------
nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c | 16 +++--
nptl/sysdeps/unix/sysv/linux/s390/force-elision.h | 31 +++++++++
nptl/sysdeps/unix/sysv/linux/s390/htm.h | 8 ++-
.../unix/sysv/linux/s390/pthread_mutex_cond_lock.c | 22 ++++++
.../unix/sysv/linux/s390/pthread_mutex_lock.c | 22 ++++++
.../unix/sysv/linux/s390/pthread_mutex_timedlock.c | 22 ++++++
.../unix/sysv/linux/s390/pthread_mutex_trylock.c | 22 ++++++
.../unix/sysv/linux/s390/pthread_mutex_unlock.c | 19 ++++++
16 files changed, 246 insertions(+), 122 deletions(-)
delete mode 100644 nptl/sysdeps/unix/sysv/linux/s390/elision-common.c
delete mode 100644 nptl/sysdeps/unix/sysv/linux/s390/elision-common.h
create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/force-elision.h
create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c
create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_lock.c
create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_timedlock.c
create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_trylock.c
create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_unlock.c
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/Makefile b/nptl/sysdeps/unix/sysv/linux/s390/Makefile
index 6a6b455..01a4004 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/Makefile
+++ b/nptl/sysdeps/unix/sysv/linux/s390/Makefile
@@ -1,2 +1,2 @@
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
- elision-trylock elision-common
+ elision-trylock
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
index 75785d9..2a7c998 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
@@ -89,13 +89,23 @@ typedef union
binary compatibility. */
int __kind;
#if __WORDSIZE == 64
- int __spins;
+ short __spins;
+ short __elision;
__pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV 1
+# define __PTHREAD_MUTEX_HAVE_ELISION 1
#else
unsigned int __nusers;
__extension__ union
{
+ struct
+ {
+ short __espins;
+ short __elision;
+# define __spins d.__espins
+# define __elision d.__elision
+# define __PTHREAD_MUTEX_HAVE_ELISION 2
+ } d;
int __spins;
__pthread_slist_t __list;
};
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-common.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-common.c
deleted file mode 100644
index e44e4ed..0000000
--- a/nptl/sysdeps/unix/sysv/linux/s390/elision-common.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* elision-common.c: Code shared by specific elision function implementations.
- Copyright (C) 2011, 2012, 2013 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-common.h>
-
-__thread uint64_t __attribute__ ((aligned(8))) __rtm_explicit_abort_rc = 0;
-libc_hidden_def (__rtm_explicit_abort_rc);
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-common.h b/nptl/sysdeps/unix/sysv/linux/s390/elision-common.h
deleted file mode 100644
index 182d4a3..0000000
--- a/nptl/sysdeps/unix/sysv/linux/s390/elision-common.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* elision-common.h: Code shared by specific elision function implementations.
- Copyright (C) 2011, 2012, 2013 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/>. */
-#ifndef _ELISION_COMMON_H
-#define _ELISION_COMMON_H 1
-
-#include <tls.h>
-
-extern __thread uint64_t __rtm_explicit_abort_rc;
-
-#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c
index 76df37f..df6f516 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c
@@ -35,10 +35,13 @@ struct elision_config __elision_aconf =
to reasons other than other threads' memory accesses. Expressed in
number of lock acquisition attempts. */
.skip_lock_internal_abort = 3,
- /* How often we retry using elision if there is chance for the transaction
+ /* 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_xbegin_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. */
- .retry_try_xbegin = 3,
+ .try_xbegin = 3,
/* Same as SKIP_LOCK_INTERNAL_ABORT but for trylock. */
.skip_trylock_internal_abort = 3,
};
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.h b/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.h
index c62b723..c4695d1 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.h
@@ -27,7 +27,8 @@ struct elision_config
{
int skip_lock_busy;
int skip_lock_internal_abort;
- int retry_try_xbegin;
+ int skip_lock_out_of_xbegin_retries;
+ int try_xbegin;
int skip_trylock_internal_abort;
};
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c
index ec0db56..b9ff8fd 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c
@@ -1,5 +1,5 @@
/* elision-lock.c: Elided pthread mutex lock.
- Copyright (C) 2011-2013 Free Software Foundation, Inc.
+ Copyright (C) 2013 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
@@ -21,7 +21,6 @@
#include <lowlevellock.h>
#include "htm.h"
#include <elision-conf.h>
-#include "elision-common.h"
#if !defined(LLL_LOCK) && !defined(EXTRAARG)
/* Make sure the configuration code is always linked in for static
@@ -47,59 +46,68 @@ __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private)
{
if (*adapt_count <= 0)
{
- unsigned status;
int try_xbegin;
- uint64_t explicit_abort_rc;
- for (try_xbegin = aconf.retry_try_xbegin;
+ for (try_xbegin = aconf.try_xbegin;
try_xbegin > 0;
try_xbegin--)
{
+ unsigned status;
+
if (__builtin_expect
((status = __builtin_tbegin((void *)0)) == _TBEGIN_OK, 1))
{
if (*futex == 0)
return 0;
-
- /* Lock was busy. Fall back to normal locking. We cannot use
- _tend here because this might not be the outermost
- transaction. */
- __builtin_non_tx_store (&__rtm_explicit_abort_rc,
- _ABORT_LOCK_BUSY);
- __builtin_tabort (_ABORT_LOCK_BUSY);
+ /* 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 */
+ {
+ if (aconf.skip_lock_busy > 0)
+ __builtin_non_tx_store (*adapt_count, aconf.skip_lock_busy);
+ /* 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. */
+ __builtin_tabort (_ABORT_USER_TEMPORARY);
+ }
}
-
- asm volatile (
- "" ::: "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",
- "f10", "f11", "f12", "f13", "f14", "f15", "cc", "memory");
- explicit_abort_rc = __rtm_explicit_abort_rc;
- __rtm_explicit_abort_rc = 0;
-
- if (status != _TABORT_RETRY)
+ else
{
- if (explicit_abort_rc == _ABORT_LOCK_BUSY)
- {
- /* Right now we skip here. Better would be to wait a bit
- and retry. This likely needs some spinning. */
- if (*adapt_count != aconf.skip_lock_busy)
- *adapt_count = aconf.skip_lock_busy;
+ asm volatile ("" ::: "f0", "f1", "f2", "f3", "f4", "f5", "f6",
+ "f7", "f8", "f9", "f10", "f11", "f12", "f13",
+ "f14", "f15", "cc", "memory");
+ if (status != _TABORT_RETRY)
+ {
+ /* 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;
}
- /* The condition code indicates that a retry is probably futile.
- Use the normal locking and next time use lock.
- Be careful to avoid writing to the lock. */
- else if (*adapt_count != aconf.skip_lock_internal_abort)
- *adapt_count = aconf.skip_lock_internal_abort;
- break;
}
}
+ /* Same logic as above, but for for a number of tepmorary failures in a
+ row. */
+ if (aconf.skip_lock_out_of_xbegin_retries > 0 && aconf.try_xbegin > 0)
+ *adapt_count = aconf.skip_lock_out_of_xbegin_retries;
}
else
{
- /* Use a normal lock until the threshold counter runs out.
- Lost updates possible. */
+ /* Lost updates are possible, but harmless. Due to races this might lead
+ to *adapt_count becoming less than zero. */
(*adapt_count)--;
}
- /* Use a normal lock here. */
+ use_lock:
return LLL_LOCK ((*futex), private);
}
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c
index 9eed967..ee28a1e 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c
@@ -1,4 +1,4 @@
-/* elision-trylock.c: Lock eliding trylock for pthreads.
+/* elision-trylock.c: Elided pthread mutex trylock.
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -21,7 +21,6 @@
#include <lowlevellock.h>
#include "htm.h"
#include <elision-conf.h>
-#include "elision-common.h"
#define aconf __elision_aconf
@@ -31,14 +30,15 @@
int
__lll_trylock_elision (int *futex, short *adapt_count)
{
- /* Implement POSIX semantics by forbiding nesting
- trylock. Sorry. After the abort the code is re-executed
+ /* 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)
{
- __builtin_non_tx_store (&__rtm_explicit_abort_rc, _ABORT_NESTED_TRYLOCK);
- __builtin_tabort (_ABORT_NESTED_TRYLOCK);
+ /* Note that this abort may terminate an outermost transaction that
+ was created outside glibc. */
+ __builtin_tabort (_ABORT_USER_PERSISTENT);
}
/* Only try a transaction if it's worth it. */
@@ -51,30 +51,37 @@ __lll_trylock_elision (int *futex, short *adapt_count)
{
if (*futex == 0)
return 0;
-
- /* Lock was busy. Fall back to normal locking. We cannot use
- _tend here because this might not be the outermost
- transaction. */
- __builtin_non_tx_store (&__rtm_explicit_abort_rc, _ABORT_LOCK_BUSY);
- __builtin_tabort (_ABORT_LOCK_BUSY);
+ /* 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
+ {
+ asm volatile ("" ::: "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "cc", "memory");
+ if (status != _TABORT_RETRY)
+ {
+ /* 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;
+ }
}
-
- asm volatile (
- "" ::: "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",
- "f10", "f11", "f12", "f13", "f14", "f15", "cc", "memory");
- __rtm_explicit_abort_rc = 0;
- if (status != _TABORT_RETRY)
- {
- /* The condition code indicates that a retry is probably futile.
- For future locks don't try speculation for some time. */
- if (*adapt_count != aconf.skip_trylock_internal_abort)
- *adapt_count = aconf.skip_trylock_internal_abort;
- }
/* Could do some retries here. */
}
else
{
- /* Lost updates are possible, but harmless. */
+ /* Lost updates are possible, but harmless. Due to races this might lead
+ to *adapt_count becoming less than zero. */
(*adapt_count)--;
}
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c
index ac42d24..d7e27fe 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c
@@ -23,16 +23,18 @@
int
__lll_unlock_elision(int *lock, int private)
{
- /* When the lock was free we're in a transaction.
- When you crash here you unlocked a free lock. */
+ /* 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. Although the program might then fail, the
+ unlock function needs to handle this situation without crashing. */
if (*lock == 0)
{
- /* The instruction ETND is slower than TEND, so the latter is used to
- check whether there was an active transaction. */
- if (__builtin_expect (__builtin_tend() != 0, 0))
+ /* Although on zEC12 the instruction ETND is slower than TEND, we cannot
+ use TEND here because if no elided lock is pending, TEND could close a
+ transaction that was started outside glibc. */
+ if (__builtin_tx_nesting_depth () > 0)
{
- /* Lock released outside a transaction. */
- abort ();
+ __builtin_tend();
}
}
else
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 0000000..9789905
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/force-elision.h
@@ -0,0 +1,31 @@
+/* force-elision.h: Automatic enabling of elision for mutexes
+ Copyright (C) 2013 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/>. */
+
+/* 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; \
+ }
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/htm.h b/nptl/sysdeps/unix/sysv/linux/s390/htm.h
index 3e0fbd1..49f76a5 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/htm.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/htm.h
@@ -38,11 +38,13 @@
#define _TBEGIN_OK (0u)
#define _TABORT_RETRY (2u)
+#define _TABORT_NO_RETRY (3u)
#define _TABORT_CODE(x) (((x) >> 24) & 0xff)
-#define _ABORT_LOCK_BUSY 0x1ff
-#define _ABORT_LOCK_IS_LOCKED 0x1fe
-#define _ABORT_NESTED_TRYLOCK 0x1fd
+/* Odd abort codes are persistent failures (cc 3), even abort codes are
+ temporary failures (cc 2). */
+#define _ABORT_USER_TEMPORARY 0x100
+#define _ABORT_USER_PERSISTENT 0x101
#endif
#ifndef __ASSEMBLER__
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 0000000..fe64e02
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c
@@ -0,0 +1,22 @@
+/* Copyright (C) 2013 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 "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 0000000..37b122f
--- /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) 2011, 2012, 2013 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 0000000..ddc6d92
--- /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) 2011, 2012, 2013 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 0000000..0148aca
--- /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) 2011, 2012, 2013 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"
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_unlock.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_unlock.c
new file mode 100644
index 0000000..5af5c59
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_unlock.c
@@ -0,0 +1,19 @@
+/* Elided version of pthread_mutex_trylock.
+ Copyright (C) 2011, 2012, 2013 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 "nptl/pthread_mutex_unlock.c"
--
1.7.11.4