mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Add elision tunables
This patch adds several new tunables to control the behavior of elision on supported platforms[1]. Since elision now depends on tunables, we should always *compile* with elision enabled, and leave the code disabled, but available for runtime selection. This gives us *much* better compile-time testing of the existing code to avoid bit-rot[2]. Tested on ppc, ppc64, ppc64le, s390x and x86_64. [1] This part of the patch was initially proposed by Paul Murphy but was "staled" because the framework have changed since the patch was originally proposed: https://patchwork.sourceware.org/patch/10342/ [2] This part of the patch was inititally proposed as a RFC by Carlos O'Donnell. Make sense to me integrate this on the patch: https://sourceware.org/ml/libc-alpha/2017-05/msg00335.html * elf/dl-tunables.list: Add elision parameters. * manual/tunables.texi: Add entries about elision tunable. * sysdeps/unix/sysv/linux/powerpc/elision-conf.c: Add callback functions to dynamically enable/disable elision. Add multiple callbacks functions to set elision parameters. Deleted __libc_enable_secure check. * sysdeps/unix/sysv/linux/s390/elision-conf.c: Likewise. * sysdeps/unix/sysv/linux/x86/elision-conf.c: Likewise. * configure: Regenerated. * configure.ac: Option enable_lock_elision was deleted. * config.h.in: ENABLE_LOCK_ELISION flag was deleted. * config.make.in: Remove references to enable_lock_elision. * manual/install.texi: Elision configure option was removed. * INSTALL: Regenerated to remove enable_lock_elision. * nptl/Makefile: Disable elision so it can verify error case for destroying a mutex. * sysdeps/powerpc/nptl/elide.h: Cleanup ENABLE_LOCK_ELISION check. Deleted macros for the case when ENABLE_LOCK_ELISION was not defined. * sysdeps/s390/configure: Regenerated. * sysdeps/s390/configure.ac: Remove references to enable_lock_elision.. * nptl/tst-mutex8.c: Deleted all #ifndef ENABLE_LOCK_ELISION from the test. * sysdeps/powerpc/powerpc32/sysdep.h: Deleted all ENABLE_LOCK_ELISION checks. * sysdeps/powerpc/powerpc64/sysdep.h: Likewise. * sysdeps/powerpc/sysdep.h: Likewise. * sysdeps/s390/nptl/bits/pthreadtypes-arch.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/force-elision.h: Likewise. * sysdeps/unix/sysv/linux/s390/elision-conf.h: Likewise. * sysdeps/unix/sysv/linux/s390/force-elision.h: Likewise. * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/s390/Makefile: Remove references to enable-lock-elision. Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
This commit is contained in:
committed by
Tulio Magno Quites Machado Filho
parent
a5a2a76bb7
commit
07ed18d26a
39
ChangeLog
39
ChangeLog
@ -1,3 +1,42 @@
|
|||||||
|
2017-12-05 Rogerio A. Cardoso <rcardoso@linux.vnet.ibm.com>,
|
||||||
|
Paul E. Murphy <murphyp@linux.vnet.ibm.com>,
|
||||||
|
Carlos O'Donnell <carlos@redhat.com>
|
||||||
|
|
||||||
|
* elf/dl-tunables.list: Add elision parameters.
|
||||||
|
* manual/tunables.texi: Add entries about elision tunable.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/elision-conf.c:
|
||||||
|
Add callback functions to dynamically enable/disable elision.
|
||||||
|
Add multiple callbacks functions to set elision parameters.
|
||||||
|
Deleted __libc_enable_secure check.
|
||||||
|
* sysdeps/unix/sysv/linux/s390/elision-conf.c: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/x86/elision-conf.c: Likewise.
|
||||||
|
* configure: Regenerated.
|
||||||
|
* configure.ac: Option enable_lock_elision was deleted.
|
||||||
|
* config.h.in: ENABLE_LOCK_ELISION flag was deleted.
|
||||||
|
* config.make.in: Remove references to enable_lock_elision.
|
||||||
|
* manual/install.texi: Elision configure option was removed.
|
||||||
|
* INSTALL: Regenerated to remove enable_lock_elision.
|
||||||
|
* nptl/Makefile:
|
||||||
|
Disable elision so it can verify error case for destroying a mutex.
|
||||||
|
* sysdeps/powerpc/nptl/elide.h:
|
||||||
|
Cleanup ENABLE_LOCK_ELISION check.
|
||||||
|
Deleted macros for the case when ENABLE_LOCK_ELISION was not defined.
|
||||||
|
* sysdeps/s390/configure: Regenerated.
|
||||||
|
* sysdeps/s390/configure.ac: Remove references to enable_lock_elision..
|
||||||
|
* nptl/tst-mutex8.c:
|
||||||
|
Deleted all #ifndef ENABLE_LOCK_ELISION from the test.
|
||||||
|
* sysdeps/powerpc/powerpc32/sysdep.h:
|
||||||
|
Deleted all ENABLE_LOCK_ELISION checks.
|
||||||
|
* sysdeps/powerpc/powerpc64/sysdep.h: Likewise.
|
||||||
|
* sysdeps/powerpc/sysdep.h: Likewise.
|
||||||
|
* sysdeps/s390/nptl/bits/pthreadtypes-arch.h: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/force-elision.h: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/s390/elision-conf.h: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/s390/force-elision.h: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/s390/Makefile: Remove references to
|
||||||
|
enable-lock-elision.
|
||||||
|
|
||||||
2017-12-05 Joseph Myers <joseph@codesourcery.com>
|
2017-12-05 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* stdlib/strtod.c: Include <bits/floatn.h>.
|
* stdlib/strtod.c: Include <bits/floatn.h>.
|
||||||
|
3
INSTALL
3
INSTALL
@ -116,9 +116,6 @@ will be used, and CFLAGS sets optimization options for the compiler.
|
|||||||
formats may change over time. Consult the 'timezone' subdirectory
|
formats may change over time. Consult the 'timezone' subdirectory
|
||||||
for more details.
|
for more details.
|
||||||
|
|
||||||
'--enable-lock-elision=yes'
|
|
||||||
Enable lock elision for pthread mutexes by default.
|
|
||||||
|
|
||||||
'--enable-stack-protector'
|
'--enable-stack-protector'
|
||||||
'--enable-stack-protector=strong'
|
'--enable-stack-protector=strong'
|
||||||
'--enable-stack-protector=all'
|
'--enable-stack-protector=all'
|
||||||
|
@ -131,9 +131,6 @@
|
|||||||
/* Define if __stack_chk_guard canary should be randomized at program startup. */
|
/* Define if __stack_chk_guard canary should be randomized at program startup. */
|
||||||
#undef ENABLE_STACKGUARD_RANDOMIZE
|
#undef ENABLE_STACKGUARD_RANDOMIZE
|
||||||
|
|
||||||
/* Define if lock elision should be enabled by default. */
|
|
||||||
#undef ENABLE_LOCK_ELISION
|
|
||||||
|
|
||||||
/* Package description. */
|
/* Package description. */
|
||||||
#undef PKGVERSION
|
#undef PKGVERSION
|
||||||
|
|
||||||
|
@ -99,7 +99,6 @@ build-nscd = @build_nscd@
|
|||||||
use-nscd = @use_nscd@
|
use-nscd = @use_nscd@
|
||||||
build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
|
build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
|
||||||
build-pt-chown = @build_pt_chown@
|
build-pt-chown = @build_pt_chown@
|
||||||
enable-lock-elision = @enable_lock_elision@
|
|
||||||
have-tunables = @have_tunables@
|
have-tunables = @have_tunables@
|
||||||
|
|
||||||
# Build tools.
|
# Build tools.
|
||||||
|
17
configure
vendored
17
configure
vendored
@ -679,7 +679,6 @@ enable_werror
|
|||||||
all_warnings
|
all_warnings
|
||||||
force_install
|
force_install
|
||||||
bindnow
|
bindnow
|
||||||
enable_lock_elision
|
|
||||||
hardcoded_path_in_tests
|
hardcoded_path_in_tests
|
||||||
enable_timezone_tools
|
enable_timezone_tools
|
||||||
use_default_link
|
use_default_link
|
||||||
@ -768,7 +767,6 @@ enable_profile
|
|||||||
enable_timezone_tools
|
enable_timezone_tools
|
||||||
enable_hardcoded_path_in_tests
|
enable_hardcoded_path_in_tests
|
||||||
enable_stackguard_randomization
|
enable_stackguard_randomization
|
||||||
enable_lock_elision
|
|
||||||
enable_hidden_plt
|
enable_hidden_plt
|
||||||
enable_bind_now
|
enable_bind_now
|
||||||
enable_stack_protector
|
enable_stack_protector
|
||||||
@ -1428,8 +1426,6 @@ Optional Features:
|
|||||||
--enable-stackguard-randomization
|
--enable-stackguard-randomization
|
||||||
initialize __stack_chk_guard canary with a random
|
initialize __stack_chk_guard canary with a random
|
||||||
number at program start
|
number at program start
|
||||||
--enable-lock-elision=yes/no
|
|
||||||
Enable lock elision for pthread mutexes by default
|
|
||||||
--disable-hidden-plt do not hide internal function calls to avoid PLT
|
--disable-hidden-plt do not hide internal function calls to avoid PLT
|
||||||
--enable-bind-now disable lazy relocations in DSOs
|
--enable-bind-now disable lazy relocations in DSOs
|
||||||
--enable-stack-protector=[yes|no|all|strong]
|
--enable-stack-protector=[yes|no|all|strong]
|
||||||
@ -3395,19 +3391,6 @@ if test "$enable_stackguard_randomize" = yes; then
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check whether --enable-lock-elision was given.
|
|
||||||
if test "${enable_lock_elision+set}" = set; then :
|
|
||||||
enableval=$enable_lock_elision; enable_lock_elision=$enableval
|
|
||||||
else
|
|
||||||
enable_lock_elision=no
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
if test "$enable_lock_elision" = yes ; then
|
|
||||||
$as_echo "#define ENABLE_LOCK_ELISION 1" >>confdefs.h
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check whether --enable-hidden-plt was given.
|
# Check whether --enable-hidden-plt was given.
|
||||||
if test "${enable_hidden_plt+set}" = set; then :
|
if test "${enable_hidden_plt+set}" = set; then :
|
||||||
enableval=$enable_hidden_plt; hidden=$enableval
|
enableval=$enable_hidden_plt; hidden=$enableval
|
||||||
|
10
configure.ac
10
configure.ac
@ -199,16 +199,6 @@ if test "$enable_stackguard_randomize" = yes; then
|
|||||||
AC_DEFINE(ENABLE_STACKGUARD_RANDOMIZE)
|
AC_DEFINE(ENABLE_STACKGUARD_RANDOMIZE)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_ARG_ENABLE([lock-elision],
|
|
||||||
AC_HELP_STRING([--enable-lock-elision[=yes/no]],
|
|
||||||
[Enable lock elision for pthread mutexes by default]),
|
|
||||||
[enable_lock_elision=$enableval],
|
|
||||||
[enable_lock_elision=no])
|
|
||||||
AC_SUBST(enable_lock_elision)
|
|
||||||
if test "$enable_lock_elision" = yes ; then
|
|
||||||
AC_DEFINE(ENABLE_LOCK_ELISION)
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_ARG_ENABLE([hidden-plt],
|
AC_ARG_ENABLE([hidden-plt],
|
||||||
AC_HELP_STRING([--disable-hidden-plt],
|
AC_HELP_STRING([--disable-hidden-plt],
|
||||||
[do not hide internal function calls to avoid PLT]),
|
[do not hide internal function calls to avoid PLT]),
|
||||||
|
@ -96,4 +96,38 @@ glibc {
|
|||||||
default: HWCAP_IMPORTANT
|
default: HWCAP_IMPORTANT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elision {
|
||||||
|
enable {
|
||||||
|
type: INT_32
|
||||||
|
minval: 0
|
||||||
|
maxval: 1
|
||||||
|
security_level: SXID_ERASE
|
||||||
|
}
|
||||||
|
skip_lock_busy {
|
||||||
|
type: INT_32
|
||||||
|
default: 3
|
||||||
|
security_level: SXID_ERASE
|
||||||
|
}
|
||||||
|
skip_lock_internal_abort {
|
||||||
|
type: INT_32
|
||||||
|
default: 3
|
||||||
|
security_level: SXID_ERASE
|
||||||
|
}
|
||||||
|
skip_lock_after_retries {
|
||||||
|
type: INT_32
|
||||||
|
default: 3
|
||||||
|
security_level: SXID_ERASE
|
||||||
|
}
|
||||||
|
tries {
|
||||||
|
type: INT_32
|
||||||
|
default: 3
|
||||||
|
security_level: SXID_ERASE
|
||||||
|
}
|
||||||
|
skip_trylock_internal_abort {
|
||||||
|
type: INT_32
|
||||||
|
default: 3
|
||||||
|
security_level: SXID_ERASE
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,9 +145,6 @@ Note that you need to make sure the external tools are kept in sync with
|
|||||||
the versions that @theglibc{} expects as the data formats may change over
|
the versions that @theglibc{} expects as the data formats may change over
|
||||||
time. Consult the @file{timezone} subdirectory for more details.
|
time. Consult the @file{timezone} subdirectory for more details.
|
||||||
|
|
||||||
@item --enable-lock-elision=yes
|
|
||||||
Enable lock elision for pthread mutexes by default.
|
|
||||||
|
|
||||||
@item --enable-stack-protector
|
@item --enable-stack-protector
|
||||||
@itemx --enable-stack-protector=strong
|
@itemx --enable-stack-protector=strong
|
||||||
@itemx --enable-stack-protector=all
|
@itemx --enable-stack-protector=all
|
||||||
|
@ -31,6 +31,7 @@ their own namespace.
|
|||||||
@menu
|
@menu
|
||||||
* Tunable names:: The structure of a tunable name
|
* Tunable names:: The structure of a tunable name
|
||||||
* Memory Allocation Tunables:: Tunables in the memory allocation subsystem
|
* Memory Allocation Tunables:: Tunables in the memory allocation subsystem
|
||||||
|
* Elision Tunables:: Tunables in elision subsystem
|
||||||
* Hardware Capability Tunables:: Tunables that modify the hardware
|
* Hardware Capability Tunables:: Tunables that modify the hardware
|
||||||
capabilities seen by @theglibc{}
|
capabilities seen by @theglibc{}
|
||||||
@end menu
|
@end menu
|
||||||
@ -212,6 +213,74 @@ pre-fill the per-thread cache with. The default, or when set to zero,
|
|||||||
is no limit.
|
is no limit.
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
|
@node Elision Tunables
|
||||||
|
@section Elision Tunables
|
||||||
|
@cindex elision tunables
|
||||||
|
@cindex tunables, elision
|
||||||
|
|
||||||
|
@deftp {Tunable namespace} glibc.elision
|
||||||
|
Contended locks are usually slow and can lead to performance and scalability
|
||||||
|
issues in multithread code. Lock elision will use memory transactions to under
|
||||||
|
certain conditions, to elide locks and improve performance.
|
||||||
|
Elision behavior can be modified by setting the following tunables in
|
||||||
|
the @code{elision} namespace:
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp Tunable glibc.elision.enable
|
||||||
|
The @code{glibc.elision.enable} tunable enables lock elision if the feature is
|
||||||
|
supported by the hardware. If elision is not supported by the hardware this
|
||||||
|
tunable has no effect.
|
||||||
|
|
||||||
|
Elision tunables are supported for 64-bit Intel, IBM POWER, and z System
|
||||||
|
architectures.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp Tunable glibc.elision.skip_lock_busy
|
||||||
|
The @code{glibc.elision.skip_lock_busy} tunable sets how many times to use a
|
||||||
|
non-transactional lock after a transactional failure has occurred because the
|
||||||
|
lock is already acquired. Expressed in number of lock acquisition attempts.
|
||||||
|
|
||||||
|
The default value of this tunable is @samp{3}.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp Tunable glibc.elision.skip_lock_internal_abort
|
||||||
|
The @code{glibc.elision.skip_lock_internal_abort} tunable sets how many times
|
||||||
|
the thread should avoid using elision if a transaction aborted for any reason
|
||||||
|
other than a different thread's memory accesses. Expressed in number of lock
|
||||||
|
acquisition attempts.
|
||||||
|
|
||||||
|
The default value of this tunable is @samp{3}.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp Tunable glibc.elision.skip_lock_after_retries
|
||||||
|
The @code{glibc.elision.skip_lock_after_retries} tunable sets how many times
|
||||||
|
to try to elide a lock with transactions, that only failed due to a different
|
||||||
|
thread's memory accesses, before falling back to regular lock.
|
||||||
|
Expressed in number of lock elision attempts.
|
||||||
|
|
||||||
|
This tunable is supported only on IBM POWER, and z System architectures.
|
||||||
|
|
||||||
|
The default value of this tunable is @samp{3}.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp Tunable glibc.elision.tries
|
||||||
|
The @code{glibc.elision.tries} sets how many times to retry elision if there is
|
||||||
|
chance for the transaction to finish execution e.g., it wasn't
|
||||||
|
aborted due to the lock being already acquired. If elision is not supported
|
||||||
|
by the hardware this tunable is set to @samp{0} to avoid retries.
|
||||||
|
|
||||||
|
The default value of this tunable is @samp{3}.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp Tunable glibc.elision.skip_trylock_internal_abort
|
||||||
|
The @code{glibc.elision.skip_trylock_internal_abort} tunable sets how many
|
||||||
|
times the thread should avoid trying the lock if a transaction aborted due to
|
||||||
|
reasons other than a different thread's memory accesses. Expressed in number
|
||||||
|
of try lock attempts.
|
||||||
|
|
||||||
|
The default value of this tunable is @samp{3}.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
@node Hardware Capability Tunables
|
@node Hardware Capability Tunables
|
||||||
@section Hardware Capability Tunables
|
@section Hardware Capability Tunables
|
||||||
@cindex hardware capability tunables
|
@cindex hardware capability tunables
|
||||||
|
@ -714,6 +714,10 @@ endif
|
|||||||
|
|
||||||
$(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so
|
$(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so
|
||||||
|
|
||||||
|
# Disable elision for tst-mutex8 so it can verify error case for
|
||||||
|
# destroying a mutex.
|
||||||
|
tst-mutex8-ENV = GLIBC_TUNABLES=glibc.elision.enable=0
|
||||||
|
|
||||||
# The tests here better do not run in parallel
|
# The tests here better do not run in parallel
|
||||||
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
|
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
|
||||||
.NOTPARALLEL:
|
.NOTPARALLEL:
|
||||||
|
@ -127,9 +127,8 @@ check_type (const char *mas, pthread_mutexattr_t *ma)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Elided mutexes don't fail destroy. If elision is not explicitly disabled
|
/* Elided mutexes don't fail destroy, but this test is run with
|
||||||
we don't know, so can also not check this. */
|
elision disabled so we can test them. */
|
||||||
#ifndef ENABLE_LOCK_ELISION
|
|
||||||
e = pthread_mutex_destroy (m);
|
e = pthread_mutex_destroy (m);
|
||||||
if (e == 0)
|
if (e == 0)
|
||||||
{
|
{
|
||||||
@ -142,7 +141,6 @@ check_type (const char *mas, pthread_mutexattr_t *ma)
|
|||||||
mas);
|
mas);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pthread_mutex_unlock (m) != 0)
|
if (pthread_mutex_unlock (m) != 0)
|
||||||
{
|
{
|
||||||
@ -157,7 +155,6 @@ check_type (const char *mas, pthread_mutexattr_t *ma)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Elided mutexes don't fail destroy. */
|
/* Elided mutexes don't fail destroy. */
|
||||||
#ifndef ENABLE_LOCK_ELISION
|
|
||||||
e = pthread_mutex_destroy (m);
|
e = pthread_mutex_destroy (m);
|
||||||
if (e == 0)
|
if (e == 0)
|
||||||
{
|
{
|
||||||
@ -171,7 +168,6 @@ mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
|
|||||||
mas);
|
mas);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pthread_mutex_unlock (m) != 0)
|
if (pthread_mutex_unlock (m) != 0)
|
||||||
{
|
{
|
||||||
@ -207,7 +203,6 @@ mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Elided mutexes don't fail destroy. */
|
/* Elided mutexes don't fail destroy. */
|
||||||
#ifndef ENABLE_LOCK_ELISION
|
|
||||||
e = pthread_mutex_destroy (m);
|
e = pthread_mutex_destroy (m);
|
||||||
if (e == 0)
|
if (e == 0)
|
||||||
{
|
{
|
||||||
@ -220,7 +215,6 @@ mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
|
|||||||
mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
|
mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
done = true;
|
done = true;
|
||||||
if (pthread_cond_signal (&c) != 0)
|
if (pthread_cond_signal (&c) != 0)
|
||||||
@ -280,7 +274,6 @@ mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Elided mutexes don't fail destroy. */
|
/* Elided mutexes don't fail destroy. */
|
||||||
#ifndef ENABLE_LOCK_ELISION
|
|
||||||
e = pthread_mutex_destroy (m);
|
e = pthread_mutex_destroy (m);
|
||||||
if (e == 0)
|
if (e == 0)
|
||||||
{
|
{
|
||||||
@ -295,7 +288,6 @@ mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
|
|||||||
mas);
|
mas);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pthread_cancel (th) != 0)
|
if (pthread_cancel (th) != 0)
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#ifndef ELIDE_PPC_H
|
#ifndef ELIDE_PPC_H
|
||||||
# define ELIDE_PPC_H
|
# define ELIDE_PPC_H
|
||||||
|
|
||||||
#ifdef ENABLE_LOCK_ELISION
|
|
||||||
# include <htm.h>
|
# include <htm.h>
|
||||||
# include <elision-conf.h>
|
# include <elision-conf.h>
|
||||||
|
|
||||||
@ -114,12 +113,4 @@ __elide_unlock (int is_lock_free)
|
|||||||
# define ELIDE_UNLOCK(is_lock_free) \
|
# define ELIDE_UNLOCK(is_lock_free) \
|
||||||
__elide_unlock (is_lock_free)
|
__elide_unlock (is_lock_free)
|
||||||
|
|
||||||
# else
|
|
||||||
|
|
||||||
# define ELIDE_LOCK(adapt_count, is_lock_free) 0
|
|
||||||
# define ELIDE_TRYLOCK(adapt_count, is_lock_free, write) 0
|
|
||||||
# define ELIDE_UNLOCK(is_lock_free) 0
|
|
||||||
|
|
||||||
#endif /* ENABLE_LOCK_ELISION */
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -90,7 +90,7 @@ GOT_LABEL: ; \
|
|||||||
cfi_endproc; \
|
cfi_endproc; \
|
||||||
ASM_SIZE_DIRECTIVE(name)
|
ASM_SIZE_DIRECTIVE(name)
|
||||||
|
|
||||||
#if ! IS_IN(rtld) && defined (ENABLE_LOCK_ELISION)
|
#if ! IS_IN(rtld)
|
||||||
# define ABORT_TRANSACTION \
|
# define ABORT_TRANSACTION \
|
||||||
cmpwi 2,0; \
|
cmpwi 2,0; \
|
||||||
beq 1f; \
|
beq 1f; \
|
||||||
|
@ -263,7 +263,7 @@ LT_LABELSUFFIX(name,_name_end): ; \
|
|||||||
TRACEBACK_MASK(name,mask); \
|
TRACEBACK_MASK(name,mask); \
|
||||||
END_2(name)
|
END_2(name)
|
||||||
|
|
||||||
#if !IS_IN(rtld) && defined (ENABLE_LOCK_ELISION)
|
#if !IS_IN(rtld)
|
||||||
# define ABORT_TRANSACTION \
|
# define ABORT_TRANSACTION \
|
||||||
cmpdi 13,0; \
|
cmpdi 13,0; \
|
||||||
beq 1f; \
|
beq 1f; \
|
||||||
|
@ -21,10 +21,8 @@
|
|||||||
*/
|
*/
|
||||||
#define _SYSDEPS_SYSDEP_H 1
|
#define _SYSDEPS_SYSDEP_H 1
|
||||||
#include <bits/hwcap.h>
|
#include <bits/hwcap.h>
|
||||||
#ifdef ENABLE_LOCK_ELISION
|
|
||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
#include <htm.h>
|
#include <htm.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC)
|
#define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC)
|
||||||
|
|
||||||
@ -176,7 +174,7 @@
|
|||||||
we abort transaction just before syscalls.
|
we abort transaction just before syscalls.
|
||||||
|
|
||||||
[1] Documentation/powerpc/transactional_memory.txt [Syscalls] */
|
[1] Documentation/powerpc/transactional_memory.txt [Syscalls] */
|
||||||
#if !IS_IN(rtld) && defined (ENABLE_LOCK_ELISION)
|
#if !IS_IN(rtld)
|
||||||
# define ABORT_TRANSACTION \
|
# define ABORT_TRANSACTION \
|
||||||
({ \
|
({ \
|
||||||
if (THREAD_GET_TM_CAPABLE ()) \
|
if (THREAD_GET_TM_CAPABLE ()) \
|
||||||
|
2
sysdeps/s390/configure
vendored
2
sysdeps/s390/configure
vendored
@ -35,7 +35,7 @@ fi
|
|||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_builtin_tbegin" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_builtin_tbegin" >&5
|
||||||
$as_echo "$libc_cv_gcc_builtin_tbegin" >&6; }
|
$as_echo "$libc_cv_gcc_builtin_tbegin" >&6; }
|
||||||
|
|
||||||
if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no ; then
|
if 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."
|
critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ else
|
|||||||
fi
|
fi
|
||||||
rm -f conftest* ])
|
rm -f conftest* ])
|
||||||
|
|
||||||
if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no ; then
|
if 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."
|
critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -40,11 +40,7 @@
|
|||||||
/* Definitions for internal mutex struct. */
|
/* Definitions for internal mutex struct. */
|
||||||
#define __PTHREAD_COMPAT_PADDING_MID
|
#define __PTHREAD_COMPAT_PADDING_MID
|
||||||
#define __PTHREAD_COMPAT_PADDING_END
|
#define __PTHREAD_COMPAT_PADDING_END
|
||||||
#ifdef ENABLE_LOCK_ELISION
|
|
||||||
#define __PTHREAD_MUTEX_LOCK_ELISION 1
|
#define __PTHREAD_MUTEX_LOCK_ELISION 1
|
||||||
#else
|
|
||||||
#define __PTHREAD_MUTEX_LOCK_ELISION 0
|
|
||||||
#endif
|
|
||||||
#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND (__WORDSIZE != 64)
|
#define __PTHREAD_MUTEX_NUSERS_AFTER_KIND (__WORDSIZE != 64)
|
||||||
#define __PTHREAD_MUTEX_USE_UNION (__WORDSIZE != 64)
|
#define __PTHREAD_MUTEX_USE_UNION (__WORDSIZE != 64)
|
||||||
|
|
||||||
|
@ -22,6 +22,11 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dl-procinfo.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.
|
/* Reasonable initial tuning values, may be revised in the future.
|
||||||
This is a conservative initial value. */
|
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().
|
DEFAULT locks should be automatically use elision in pthread_mutex_lock().
|
||||||
Disabled for suid programs. Only used when elision is available. */
|
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. */
|
/* Initialize elision. */
|
||||||
|
|
||||||
@ -59,13 +109,26 @@ elision_init (int argc __attribute__ ((unused)),
|
|||||||
char **argv __attribute__ ((unused)),
|
char **argv __attribute__ ((unused)),
|
||||||
char **environ)
|
char **environ)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_LOCK_ELISION
|
#if HAVE_TUNABLES
|
||||||
int elision_available = (GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_HTM) ? 1 : 0;
|
/* Elision depends on tunables and must be explicitly turned on by setting
|
||||||
__pthread_force_elision = __libc_enable_secure ? 0 : elision_available;
|
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
|
#endif
|
||||||
|
|
||||||
if (!__pthread_force_elision)
|
if (!__pthread_force_elision)
|
||||||
/* Disable elision on rwlocks. */
|
__elision_aconf.try_tbegin = 0; /* Disable elision on rwlocks. */
|
||||||
__elision_aconf.try_tbegin = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#ifdef ENABLE_LOCK_ELISION
|
|
||||||
/* Automatically enable elision for existing user lock kinds. */
|
/* Automatically enable elision for existing user lock kinds. */
|
||||||
#define FORCE_ELISION(m, s) \
|
#define FORCE_ELISION(m, s) \
|
||||||
if (__pthread_force_elision \
|
if (__pthread_force_elision \
|
||||||
@ -25,4 +24,3 @@
|
|||||||
mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
|
mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
|
||||||
s; \
|
s; \
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -16,7 +16,6 @@ sysdep_routines += dl-vdso
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(subdir),nptl)
|
ifeq ($(subdir),nptl)
|
||||||
ifeq ($(enable-lock-elision),yes)
|
|
||||||
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
|
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
|
||||||
elision-trylock
|
elision-trylock
|
||||||
|
|
||||||
@ -26,7 +25,6 @@ CFLAGS-elision-timed.c = $(elision-CFLAGS)
|
|||||||
CFLAGS-elision-trylock.c = $(elision-CFLAGS)
|
CFLAGS-elision-trylock.c = $(elision-CFLAGS)
|
||||||
CFLAGS-elision-unlock.c = $(elision-CFLAGS)
|
CFLAGS-elision-unlock.c = $(elision-CFLAGS)
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(subdir),misc)
|
ifeq ($(subdir),misc)
|
||||||
tests += tst-ptrace-singleblock
|
tests += tst-ptrace-singleblock
|
||||||
|
@ -22,6 +22,11 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dl-procinfo.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.
|
/* Reasonable initial tuning values, may be revised in the future.
|
||||||
This is a conservative initial value. */
|
This is a conservative initial value. */
|
||||||
|
|
||||||
@ -53,6 +58,50 @@ struct elision_config __elision_aconf =
|
|||||||
|
|
||||||
int __pthread_force_elision attribute_hidden = 0;
|
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_hwcap) & HWCAP_S390_TE) ? 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 elison. */
|
/* Initialize elison. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -60,11 +109,26 @@ elision_init (int argc __attribute__ ((unused)),
|
|||||||
char **argv __attribute__ ((unused)),
|
char **argv __attribute__ ((unused)),
|
||||||
char **environ)
|
char **environ)
|
||||||
{
|
{
|
||||||
/* Set when the CPU and the kernel supports transactional execution.
|
#if HAVE_TUNABLES
|
||||||
When false elision is never attempted. */
|
/* Elision depends on tunables and must be explicitly turned on by setting
|
||||||
int elision_available = (GLRO (dl_hwcap) & HWCAP_S390_TE) ? 1 : 0;
|
the appropriate tunable on a supported platform. */
|
||||||
|
|
||||||
__pthread_force_elision = __libc_enable_secure ? 0 : elision_available;
|
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)
|
||||||
|
__elision_aconf.try_tbegin = 0; /* Disable elision on rwlocks. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
#ifdef ENABLE_LOCK_ELISION
|
|
||||||
#ifndef _ELISION_CONF_H
|
#ifndef _ELISION_CONF_H
|
||||||
#define _ELISION_CONF_H 1
|
#define _ELISION_CONF_H 1
|
||||||
|
|
||||||
@ -41,4 +40,3 @@ extern int __pthread_force_elision attribute_hidden;
|
|||||||
#define HAVE_ELISION 1
|
#define HAVE_ELISION 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#ifdef ENABLE_LOCK_ELISION
|
|
||||||
/* Automatically enable elision for existing user lock kinds. */
|
/* Automatically enable elision for existing user lock kinds. */
|
||||||
#define FORCE_ELISION(m, s) \
|
#define FORCE_ELISION(m, s) \
|
||||||
if (__pthread_force_elision \
|
if (__pthread_force_elision \
|
||||||
@ -25,4 +24,3 @@
|
|||||||
mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
|
mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
|
||||||
s; \
|
s; \
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include <sysdeps/nptl/lowlevellock.h>
|
#include <sysdeps/nptl/lowlevellock.h>
|
||||||
|
|
||||||
/* Transactional lock elision definitions. */
|
/* Transactional lock elision definitions. */
|
||||||
# ifdef ENABLE_LOCK_ELISION
|
|
||||||
extern int __lll_timedlock_elision
|
extern int __lll_timedlock_elision
|
||||||
(int *futex, short *adapt_count, const struct timespec *timeout, int private)
|
(int *futex, short *adapt_count, const struct timespec *timeout, int private)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
@ -45,6 +44,5 @@ extern int __lll_trylock_elision(int *futex, short *adapt_count)
|
|||||||
__lll_unlock_elision (&(futex), &(adapt_count), private)
|
__lll_unlock_elision (&(futex), &(adapt_count), private)
|
||||||
# define lll_trylock_elision(futex, adapt_count) \
|
# define lll_trylock_elision(futex, adapt_count) \
|
||||||
__lll_trylock_elision(&(futex), &(adapt_count))
|
__lll_trylock_elision(&(futex), &(adapt_count))
|
||||||
# endif /* ENABLE_LOCK_ELISION */
|
|
||||||
|
|
||||||
#endif /* lowlevellock.h */
|
#endif /* lowlevellock.h */
|
||||||
|
@ -22,6 +22,11 @@
|
|||||||
#include <elision-conf.h>
|
#include <elision-conf.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#if HAVE_TUNABLES
|
||||||
|
# define TUNABLE_NAMESPACE elision
|
||||||
|
#endif
|
||||||
|
#include <elf/dl-tunables.h>
|
||||||
|
|
||||||
/* Reasonable initial tuning values, may be revised in the future.
|
/* Reasonable initial tuning values, may be revised in the future.
|
||||||
This is a conservative initial value. */
|
This is a conservative initial value. */
|
||||||
|
|
||||||
@ -48,21 +53,76 @@ struct elision_config __elision_aconf =
|
|||||||
pthread_mutex_lock(). Disabled for suid programs. Only used when elision
|
pthread_mutex_lock(). Disabled for suid programs. Only used when elision
|
||||||
is available. */
|
is available. */
|
||||||
|
|
||||||
int __pthread_force_elision attribute_hidden;
|
int __pthread_force_elision attribute_hidden = 0;
|
||||||
|
|
||||||
/* Initialize elison. */
|
#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 = HAS_CPU_FEATURE (RTM) ? 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 (retry_try_xbegin, int32_t);
|
||||||
|
TUNABLE_CALLBACK_FNDECL (skip_trylock_internal_abort, int32_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialize elision. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
elision_init (int argc __attribute__ ((unused)),
|
elision_init (int argc __attribute__ ((unused)),
|
||||||
char **argv __attribute__ ((unused)),
|
char **argv __attribute__ ((unused)),
|
||||||
char **environ)
|
char **environ)
|
||||||
{
|
{
|
||||||
int elision_available = HAS_CPU_FEATURE (RTM);
|
#if HAVE_TUNABLES
|
||||||
#ifdef ENABLE_LOCK_ELISION
|
/* Elision depends on tunables and must be explicitly turned on by setting
|
||||||
__pthread_force_elision = __libc_enable_secure ? 0 : elision_available;
|
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 (tries, int32_t,
|
||||||
|
TUNABLE_CALLBACK (set_elision_retry_try_xbegin));
|
||||||
|
TUNABLE_GET (skip_trylock_internal_abort, int32_t,
|
||||||
|
TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort));
|
||||||
#endif
|
#endif
|
||||||
if (!elision_available)
|
|
||||||
__elision_aconf.retry_try_xbegin = 0; /* Disable elision on rwlocks */
|
if (!__pthread_force_elision)
|
||||||
|
__elision_aconf.retry_try_xbegin = 0; /* Disable elision on rwlocks. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
|
Reference in New Issue
Block a user