about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--manual/tunables.texi27
-rw-r--r--nptl/Makefile2
-rw-r--r--nptl/nptl-init.c5
-rw-r--r--nptl/pthreadP.h11
-rw-r--r--nptl/pthread_mutex_conf.c46
-rw-r--r--nptl/pthread_mutex_conf.h34
-rw-r--r--nptl/pthread_mutex_lock.c2
-rw-r--r--nptl/pthread_mutex_timedlock.c2
-rw-r--r--sysdeps/generic/adaptive_spin_count.h22
-rw-r--r--sysdeps/nptl/dl-tunables.list27
11 files changed, 190 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index e6bbc57039..411116acbe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2018-12-01  Kemi Wang  <kemi.wang@intel.com>
+
+	* 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.
+
 2018-12-01  Paul Pluzhnikov  <ppluzhnikov@google.com>
 
 	[BZ #20544]
diff --git a/manual/tunables.texi b/manual/tunables.texi
index 3345a23969..09a25655ae 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -32,6 +32,7 @@ their own namespace.
 * Tunable names::  The structure of a tunable name
 * Memory Allocation Tunables::  Tunables in the memory allocation subsystem
 * Elision Tunables::  Tunables in elision subsystem
+* POSIX Thread Tunables:: Tunables in the POSIX thread subsystem
 * Hardware Capability Tunables::  Tunables that modify the hardware
 				  capabilities seen by @theglibc{}
 @end menu
@@ -281,6 +282,32 @@ of try lock attempts.
 The default value of this tunable is @samp{3}.
 @end deftp
 
+@node POSIX Thread Tunables
+@section POSIX Thread Tunables
+@cindex pthread mutex tunables
+@cindex thread mutex tunables
+@cindex mutex tunables
+@cindex tunables thread mutex
+
+@deftp {Tunable namespace} glibc.pthread
+The behavior of POSIX threads can be tuned to gain performance improvements
+according to specific hardware capabilities and workload characteristics by
+setting the following tunables in the @code{pthread} namespace:
+@end deftp
+
+@deftp Tunable glibc.pthread.mutex_spin_count
+The @code{glibc.pthread.mutex_spin_count} tunable sets the maximum number of times
+a thread should spin on the lock before calling into the kernel to block.
+Adaptive spin is used for mutexes initialized with the
+@code{PTHREAD_MUTEX_ADAPTIVE_NP} GNU extension.  It affects both
+@code{pthread_mutex_lock} and @code{pthread_mutex_timedlock}.
+
+The thread spins until either the maximum spin count is reached or the lock
+is acquired.
+
+The default value of this tunable is @samp{100}.
+@end deftp
+
 @node Hardware Capability Tunables
 @section Hardware Capability Tunables
 @cindex hardware capability tunables
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
 	    {
diff --git a/sysdeps/generic/adaptive_spin_count.h b/sysdeps/generic/adaptive_spin_count.h
new file mode 100644
index 0000000000..6b30a2af81
--- /dev/null
+++ b/sysdeps/generic/adaptive_spin_count.h
@@ -0,0 +1,22 @@
+/* Maximum adaptive spin count by default
+   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/>.  */
+
+/* The choice of 100 spins for the default spin count for an adaptive spin
+   is a completely arbitrary choice that has not been evaluated thoroughly
+   using modern hardware.  */
+#define DEFAULT_ADAPTIVE_COUNT 100
diff --git a/sysdeps/nptl/dl-tunables.list b/sysdeps/nptl/dl-tunables.list
new file mode 100644
index 0000000000..beebd5a9a4
--- /dev/null
+++ b/sysdeps/nptl/dl-tunables.list
@@ -0,0 +1,27 @@
+# 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/>.
+
+glibc {
+  pthread {
+    mutex_spin_count {
+      type: INT_32
+      minval: 0
+      maxval: 32767
+      default: 100
+    }
+  }
+}