diff options
author | Kemi Wang <kemi.wang@intel.com> | 2018-12-01 07:03:33 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2018-12-01 08:19:20 -0800 |
commit | 6310e6be9b7c322d56a45729b3ebcd22e26dd0c2 (patch) | |
tree | 577b9815c0ab096a7d120ddf8ae7ca44ea166c1b /nptl | |
parent | 8e67b39eb4a3abb6f3e35de3ad6e5d06ed0e8498 (diff) | |
download | glibc-6310e6be9b7c322d56a45729b3ebcd22e26dd0c2.tar glibc-6310e6be9b7c322d56a45729b3ebcd22e26dd0c2.tar.gz glibc-6310e6be9b7c322d56a45729b3ebcd22e26dd0c2.tar.bz2 glibc-6310e6be9b7c322d56a45729b3ebcd22e26dd0c2.zip |
Mutex: Add pthread mutex tunables
This patch does not have any functionality change, we only provide a spin
count tunes for pthread adaptive spin mutex. The tunable
glibc.pthread.mutex_spin_count tunes can be used by system administrator to
squeeze system performance according to different hardware capabilities and
workload characteristics.
The maximum value of spin count is limited to 32767 to avoid the overflow
of mutex->__data.__spins variable with the possible type of short in
pthread_mutex_lock ().
The default value of spin count is set to 100 with the reference to the
previous number of times of spinning via trylock. This value would be
architecture-specific and can be tuned with kinds of benchmarks to fit most
cases in future.
I would extend my appreciation sincerely to H.J.Lu for his help to refine
this patch series.
* manual/tunables.texi (POSIX Thread Tunables): New node.
* nptl/Makefile (libpthread-routines): Add pthread_mutex_conf.
* nptl/nptl-init.c: Include pthread_mutex_conf.h
(__pthread_initialize_minimal_internal) [HAVE_TUNABLES]: Call
__pthread_tunables_init.
* nptl/pthreadP.h (MAX_ADAPTIVE_COUNT): Remove.
(max_adaptive_count): Define.
* nptl/pthread_mutex_conf.c: New file.
* nptl/pthread_mutex_conf.h: New file.
* sysdeps/generic/adaptive_spin_count.h: New file.
* sysdeps/nptl/dl-tunables.list: New file.
* nptl/pthread_mutex_lock.c (__pthread_mutex_lock): Use
max_adaptive_count () not MAX_ADAPTIVE_COUNT.
* nptl/pthread_mutex_timedlock.c (__pthrad_mutex_timedlock):
Likewise.
Suggested-by: Andi Kleen <andi.kleen@intel.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Signed-off-by: Kemi.wang <kemi.wang@intel.com>
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/Makefile | 2 | ||||
-rw-r--r-- | nptl/nptl-init.c | 5 | ||||
-rw-r--r-- | nptl/pthreadP.h | 11 | ||||
-rw-r--r-- | nptl/pthread_mutex_conf.c | 46 | ||||
-rw-r--r-- | nptl/pthread_mutex_conf.h | 34 | ||||
-rw-r--r-- | nptl/pthread_mutex_lock.c | 2 | ||||
-rw-r--r-- | nptl/pthread_mutex_timedlock.c | 2 |
7 files changed, 96 insertions, 6 deletions
diff --git a/nptl/Makefile b/nptl/Makefile index 98b0aa01c7..34ae830276 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -145,7 +145,7 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \ mtx_destroy mtx_init mtx_lock mtx_timedlock \ mtx_trylock mtx_unlock call_once cnd_broadcast \ cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait \ - tss_create tss_delete tss_get tss_set + tss_create tss_delete tss_get tss_set pthread_mutex_conf # pthread_setuid pthread_seteuid pthread_setreuid \ # pthread_setresuid \ # pthread_setgid pthread_setegid pthread_setregid \ diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c index 907411d5bc..20ff3fd559 100644 --- a/nptl/nptl-init.c +++ b/nptl/nptl-init.c @@ -38,6 +38,7 @@ #include <kernel-features.h> #include <libc-pointer-arith.h> #include <pthread-pids.h> +#include <pthread_mutex_conf.h> #ifndef TLS_MULTIPLE_THREADS_IN_TCB /* Pointer to the corresponding variable in libc. */ @@ -431,6 +432,10 @@ __pthread_initialize_minimal_internal (void) /* Determine whether the machine is SMP or not. */ __is_smp = is_smp_system (); + +#if HAVE_TUNABLES + __pthread_tunables_init (); +#endif } strong_alias (__pthread_initialize_minimal_internal, __pthread_initialize_minimal) diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 19efe1e35f..7f16ba9800 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -33,6 +33,7 @@ #include <kernel-features.h> #include <errno.h> #include <internal-signals.h> +#include "pthread_mutex_conf.h" /* Atomic operations on TLS memory. */ @@ -47,10 +48,14 @@ #endif -/* Adaptive mutex definitions. */ -#ifndef MAX_ADAPTIVE_COUNT -# define MAX_ADAPTIVE_COUNT 100 +static inline short max_adaptive_count (void) +{ +#if HAVE_TUNABLES + return __mutex_aconf.spin_count; +#else + return DEFAULT_ADAPTIVE_COUNT; #endif +} /* Magic cookie representing robust mutex with dead owner. */ diff --git a/nptl/pthread_mutex_conf.c b/nptl/pthread_mutex_conf.c new file mode 100644 index 0000000000..545e05b360 --- /dev/null +++ b/nptl/pthread_mutex_conf.c @@ -0,0 +1,46 @@ +/* Pthread mutex tunable parameters. + Copyright (C) 2018 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/>. */ + +#if HAVE_TUNABLES +# define TUNABLE_NAMESPACE pthread +#include <pthread_mutex_conf.h> +#include <stdint.h> +#include <stdbool.h> +#include <unistd.h> /* Get STDOUT_FILENO for _dl_printf. */ +#include <elf/dl-tunables.h> + +struct mutex_config __mutex_aconf = +{ + /* The maximum number of times a thread should spin on the lock before + calling into kernel to block. */ + .spin_count = DEFAULT_ADAPTIVE_COUNT, +}; + +static void +TUNABLE_CALLBACK (set_mutex_spin_count) (tunable_val_t *valp) +{ + __mutex_aconf.spin_count = (int32_t) (valp)->numval; +} + +void +__pthread_tunables_init (void) +{ + TUNABLE_GET (mutex_spin_count, int32_t, + TUNABLE_CALLBACK (set_mutex_spin_count)); +} +#endif diff --git a/nptl/pthread_mutex_conf.h b/nptl/pthread_mutex_conf.h new file mode 100644 index 0000000000..514d1052c0 --- /dev/null +++ b/nptl/pthread_mutex_conf.h @@ -0,0 +1,34 @@ +/* Pthread mutex tunable parameters. + Copyright (C) 2018 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 _PTHREAD_MUTEX_CONF_H +#define _PTHREAD_MUTEX_CONF_H 1 + +#include <adaptive_spin_count.h> + +#if HAVE_TUNABLES +struct mutex_config +{ + int spin_count; +}; + +extern struct mutex_config __mutex_aconf attribute_hidden; + +extern void __pthread_tunables_init (void) attribute_hidden; +#endif + +#endif diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c index 29cc143e6c..474b4df765 100644 --- a/nptl/pthread_mutex_lock.c +++ b/nptl/pthread_mutex_lock.c @@ -126,7 +126,7 @@ __pthread_mutex_lock (pthread_mutex_t *mutex) if (LLL_MUTEX_TRYLOCK (mutex) != 0) { int cnt = 0; - int max_cnt = MIN (MAX_ADAPTIVE_COUNT, + int max_cnt = MIN (max_adaptive_count (), mutex->__data.__spins * 2 + 10); do { diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c index 888c12fe28..453b824030 100644 --- a/nptl/pthread_mutex_timedlock.c +++ b/nptl/pthread_mutex_timedlock.c @@ -118,7 +118,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex, if (lll_trylock (mutex->__data.__lock) != 0) { int cnt = 0; - int max_cnt = MIN (MAX_ADAPTIVE_COUNT, + int max_cnt = MIN (max_adaptive_count (), mutex->__data.__spins * 2 + 10); do { |