summaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/powerpc/elision-conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc/elision-conf.c')
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/elision-conf.c77
1 files changed, 70 insertions, 7 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c
index 21c3afdd86..906882a65e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c
+++ b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c
@@ -1,5 +1,5 @@
/* elision-conf.c: Lock elision tunable parameters.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-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
@@ -22,6 +22,11 @@
#include <unistd.h>
#include <dl-procinfo.h>
+#if HAVE_TUNABLES
+# define TUNABLE_NAMESPACE elision
+#endif
+#include <elf/dl-tunables.h>
+
/* Reasonable initial tuning values, may be revised in the future.
This is a conservative initial value. */
@@ -50,7 +55,52 @@ struct elision_config __elision_aconf =
DEFAULT locks should be automatically use elision in pthread_mutex_lock().
Disabled for suid programs. Only used when elision is available. */
-int __pthread_force_elision attribute_hidden;
+int __pthread_force_elision attribute_hidden = 0;
+
+#if HAVE_TUNABLES
+static inline void
+__always_inline
+do_set_elision_enable (int32_t elision_enable)
+{
+ /* Enable elision if it's avaliable in hardware. It's not necessary to check
+ if __libc_enable_secure isn't enabled since elision_enable will be set
+ according to the default, which is disabled. */
+ if (elision_enable == 1)
+ __pthread_force_elision = (GLRO (dl_hwcap2)
+ & PPC_FEATURE2_HAS_HTM) ? 1 : 0;
+}
+
+/* The pthread->elision_enable tunable is 0 or 1 indicating that elision
+ should be disabled or enabled respectively. The feature will only be used
+ if it's supported by the hardware. */
+
+void
+TUNABLE_CALLBACK (set_elision_enable) (tunable_val_t *valp)
+{
+ int32_t elision_enable = (int32_t) valp->numval;
+ do_set_elision_enable (elision_enable);
+}
+
+#define TUNABLE_CALLBACK_FNDECL(__name, __type) \
+static inline void \
+__always_inline \
+do_set_elision_ ## __name (__type value) \
+{ \
+ __elision_aconf.__name = value; \
+} \
+void \
+TUNABLE_CALLBACK (set_elision_ ## __name) (tunable_val_t *valp) \
+{ \
+ __type value = (__type) (valp)->numval; \
+ do_set_elision_ ## __name (value); \
+}
+
+TUNABLE_CALLBACK_FNDECL (skip_lock_busy, int32_t);
+TUNABLE_CALLBACK_FNDECL (skip_lock_internal_abort, int32_t);
+TUNABLE_CALLBACK_FNDECL (skip_lock_out_of_tbegin_retries, int32_t);
+TUNABLE_CALLBACK_FNDECL (try_tbegin, int32_t);
+TUNABLE_CALLBACK_FNDECL (skip_trylock_internal_abort, int32_t);
+#endif
/* Initialize elision. */
@@ -59,13 +109,26 @@ elision_init (int argc __attribute__ ((unused)),
char **argv __attribute__ ((unused)),
char **environ)
{
-#ifdef ENABLE_LOCK_ELISION
- int elision_available = (GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_HTM) ? 1 : 0;
- __pthread_force_elision = __libc_enable_secure ? 0 : elision_available;
+#if HAVE_TUNABLES
+ /* Elision depends on tunables and must be explicitly turned on by setting
+ the appropriate tunable on a supported platform. */
+
+ TUNABLE_GET (enable, int32_t,
+ TUNABLE_CALLBACK (set_elision_enable));
+ TUNABLE_GET (skip_lock_busy, int32_t,
+ TUNABLE_CALLBACK (set_elision_skip_lock_busy));
+ TUNABLE_GET (skip_lock_internal_abort, int32_t,
+ TUNABLE_CALLBACK (set_elision_skip_lock_internal_abort));
+ TUNABLE_GET (skip_lock_after_retries, int32_t,
+ TUNABLE_CALLBACK (set_elision_skip_lock_out_of_tbegin_retries));
+ TUNABLE_GET (tries, int32_t,
+ TUNABLE_CALLBACK (set_elision_try_tbegin));
+ TUNABLE_GET (skip_trylock_internal_abort, int32_t,
+ TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort));
#endif
+
if (!__pthread_force_elision)
- /* Disable elision on rwlocks. */
- __elision_aconf.try_tbegin = 0;
+ __elision_aconf.try_tbegin = 0; /* Disable elision on rwlocks. */
}
#ifdef SHARED