[PATCH] S/390: Port of lock elision to System/z
Adhemerval Zanella
azanella@linux.vnet.ibm.com
Thu Apr 24 20:54:00 GMT 2014
Hi Stefan
I think the patch adds to much code duplication based on x86 version, it calls for
some refactoring. Just comments below:
On 24-04-2014 11:42, Stefan Liebler wrote:
> Hi,
>
> this is a port of the lock elision implementation of Intel to System/z.
> This is the continuation of Dominik Vogts patch
> (https://sourceware.org/ml/libc-alpha/2013-11/msg00546.html).
> The lock elision code is only built with --enable-lock-elision=yes.
> Then default mutexes are elided via __builtin_tbegin, if the cpu
> supports transactions. By default lock elision is not enabled and the
> elision code is not built (Intel always builds the elision code).
> This is necessary in order to compile glibc on S/390 with an gcc
> without transactions-support. The requirements on gcc are
> checked by configure-script. Binutils are needed in version 2.24,
> which is already checked by configure-script.
> The patch is tested on S390 / S390x with lock-elision enabled /disabled.
>
> This implementation breaks pthread_mutex_destroy in the same way as described in Bug 16657.
>
> Ok?
>
> Bye
>
> ---
> 2014-04-24 Stefan Liebler <stli@linux.vnet.ibm.com>
>
> * config.make.in (enable-lock-elision): New Makefile variable.
> * configure.ac: Likewise.
> * configure: Regenerate.
> * sysdeps/s390/configure.ac:
> Add check for gcc transactions support.
> * sysdeps/s390/configure: Regenerate.
> * nptl/sysdeps/unix/sysv/linux/s390/Makefile: New file.
> Build elision files if enabled.
> * nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c: New file.
> Add lock elision support for s390.
> * nptl/sysdeps/unix/sysv/linux/s390/elision-conf.h: Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c: Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/elision-timed.c: Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c: Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c: Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/force-elision.h: Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c:
> Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_lock.c:
> Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_timedlock.c:
> Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_trylock.c:
> Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_unlock.c:
> Likewise.
> * nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h:
> (__lll_timedlock_elision, __lll_lock_elision)
> (__lll_unlock_elision, __lll_trylock_elision)
> (lll_timedlock_elision, lll_lock_elision)
> (lll_unlock_elision, lll_trylock_elision): Add.
> * nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
> (pthread_mutex_t): Add lock elision support for s390.
> ---
>
> 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 0000000..b92e0ea
> --- /dev/null
> +++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-conf.c
> @@ -0,0 +1,81 @@
> +/* 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 supports elision. 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
> +};
Although correct, this code shared a lot of logic with x86 version. I wonder if we could
use a common base to avoid code duplication.
> 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 0000000..89b647c
> --- /dev/null
> +++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c
> @@ -0,0 +1,123 @@
> +/* 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)
> + {
> + __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
> + {
> + asm volatile ("" ::: "f0", "f1", "f2", "f3", "f4", "f5", "f6",
> + "f7", "f8", "f9", "f10", "f11", "f12", "f13",
> + "f14", "f15", "cc", "memory");
Just curious: why do you need this asm assembly? Some arch specific memory barrier?
> +
> + 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 tepmorary 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;
> + }
> + else
> + {
> + /* Lost updates are possible, but harmless. Due to races this might lead
> + to *adapt_count becoming less than zero. */
> + (*adapt_count)--;
> + }
> +
> + 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 0000000..a8d8b2a
> --- /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 0000000..8ec8c71
> --- /dev/null
> +++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c
> @@ -0,0 +1,97 @@
> +/* 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
> + {
> + asm volatile ("" ::: "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
> + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
> + "cc", "memory");
> + 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 0000000..44d05cb
> --- /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 *lock, 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 (*lock == 0)
> + {
> + __asm__ volatile (".machinemode \"zarch_nohighgprs\"\n\t"
> + ".machine \"all\""
> + : : : "memory");
> + __builtin_tend();
> + }
> + else
> + lll_unlock ((*lock), 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 0000000..8fd7684
> --- /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
Again a lot of duplicated code from x86. I don't think it is a good move to maintainability.
> diff --git a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
> index 864dcbc..3b6bc6e 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 *lock, int private)
> + attribute_hidden;
> +
> +extern int __lll_trylock_elision(int *lock, 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 0000000..6fc0f96
> --- /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>
Although the path to include differs, this is pretty much a copy of x86 version. I think we
should consolidate both.
> 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..6fd6a98
> --- /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>
Ditto.
> 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..d0e6537
> --- /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>
Ditto.
> 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..ea8a8ff
> --- /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>
Ditto.
> 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..d244dca
> --- /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) 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 <nptl/pthread_mutex_unlock.c>
This file is not really doing anything, let sysdep dir build select the default one.
> diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure
> index c2d05f7..6948cc2 100644
> --- a/sysdeps/s390/configure
> +++ b/sysdeps/s390/configure
> @@ -68,5 +68,41 @@ if test $ac_verc_fail = yes; then
> fi
>
>
> +
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_tbegin" >&5
> +$as_echo_n "checking for __builtin_tbegin... " >&6; }
> +if ${libc_cv_gcc_builtin_tbegin+:} false; then :
> + $as_echo_n "(cached) " >&6
> +else
> + cat > conftest.c <<\EOF
> +#include <htmintrin.h>
> +void testtransaction ()
> +{
> + if (__builtin_tbegin (0) == _HTM_TBEGIN_STARTED)
> + {
> + __builtin_tend ();
> + }
> +}
> +EOF
> +if { ac_try='${CC-cc} -mhtm -O2 -S conftest.c -o - | grep -w tbegin > /dev/null'
> + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> + (eval $ac_try) 2>&5
> + ac_status=$?
> + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> + test $ac_status = 0; }; } ;
> +then
> + libc_cv_gcc_builtin_tbegin=yes
> +else
> + libc_cv_gcc_builtin_tbegin=no
> +fi
> +rm -f conftest*
> +fi
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_builtin_tbegin" >&5
> +$as_echo "$libc_cv_gcc_builtin_tbegin" >&6; }
> +
> +if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no ; then
> + critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390."
> +fi
> +
> test -n "$critic_missing" && as_fn_error $? "
> *** $critic_missing" "$LINENO" 5
> diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac
> index 59cfdd1..493e9a4 100644
> --- a/sysdeps/s390/configure.ac
> +++ b/sysdeps/s390/configure.ac
> @@ -10,5 +10,31 @@ AC_CHECK_PROG_VER(AS, $AS, --version,
> [GNU assembler.* \([0-9]*\.[0-9.]*\)],
> [2.2[4-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*], critic_missing="$critic_missing The program AS is required in version >= 2.24 for target S390.")
>
> +
> +AC_CACHE_CHECK(for __builtin_tbegin, libc_cv_gcc_builtin_tbegin, [dnl
> +cat > conftest.c <<\EOF
> +#include <htmintrin.h>
> +void testtransaction ()
> +{
> + if (__builtin_tbegin (0) == _HTM_TBEGIN_STARTED)
> + {
> + __builtin_tend ();
> + }
> +}
> +EOF
> +dnl
> +dnl test, if the tbegin instruction is used by __builtin_tbegin
> +if AC_TRY_COMMAND([${CC-cc} -mhtm -O2 -S conftest.c -o - | grep -w tbegin > /dev/null]) ;
> +then
> + libc_cv_gcc_builtin_tbegin=yes
> +else
> + libc_cv_gcc_builtin_tbegin=no
> +fi
> +rm -f conftest* ])
> +
> +if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no ; then
> + critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390."
> +fi
> +
> test -n "$critic_missing" && AC_MSG_ERROR([
> *** $critic_missing])
More information about the Libc-alpha
mailing list