1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-07 06:43:00 +03:00

misc: Optimize internal usage of __libc_single_threaded

By adding an internal alias to avoid the GOT indirection.
On some architecture, __libc_single_thread may be accessed through
copy relocations and thus it requires to update also the copies
default copy.

This is done by adding a new internal macro,
libc_hidden_data_{proto,def}, which has an addition argument that
specifies the alias name (instead of default __GI_ one).

Checked on x86_64-linux-gnu and i686-linux-gnu.

Reviewed-by: Fangrui Song <maskray@google.com>
This commit is contained in:
Adhemerval Zanella
2022-06-07 11:11:03 -03:00
parent 5b41b2659d
commit baf2a265c7
7 changed files with 42 additions and 4 deletions

View File

@@ -38,7 +38,7 @@ __libc_early_init (_Bool initial)
__libc_single_threaded = initial; __libc_single_threaded = initial;
#ifdef SHARED #ifdef SHARED
__libc_initial = initial; __libc_single_threaded_internal = __libc_initial = initial;
#endif #endif
__pthread_early_init (); __pthread_early_init ();

View File

@@ -534,11 +534,15 @@ for linking")
__attribute__ ((visibility ("hidden"), ##attrs)) __attribute__ ((visibility ("hidden"), ##attrs))
# define hidden_proto(name, attrs...) \ # define hidden_proto(name, attrs...) \
__hidden_proto (name, , __GI_##name, ##attrs) __hidden_proto (name, , __GI_##name, ##attrs)
# define hidden_proto_alias(name, alias, attrs...) \
__hidden_proto_alias (name, , alias, ##attrs)
# define hidden_tls_proto(name, attrs...) \ # define hidden_tls_proto(name, attrs...) \
__hidden_proto (name, __thread, __GI_##name, ##attrs) __hidden_proto (name, __thread, __GI_##name, ##attrs)
# define __hidden_proto(name, thread, internal, attrs...) \ # define __hidden_proto(name, thread, internal, attrs...) \
extern thread __typeof (name) name __asm__ (__hidden_asmname (#internal)) \ extern thread __typeof (name) name __asm__ (__hidden_asmname (#internal)) \
__hidden_proto_hiddenattr (attrs); __hidden_proto_hiddenattr (attrs);
# define __hidden_proto_alias(name, thread, internal, attrs...) \
extern thread __typeof (name) internal __hidden_proto_hiddenattr (attrs);
# define __hidden_asmname(name) \ # define __hidden_asmname(name) \
__hidden_asmname1 (__USER_LABEL_PREFIX__, name) __hidden_asmname1 (__USER_LABEL_PREFIX__, name)
# define __hidden_asmname1(prefix, name) __hidden_asmname2(prefix, name) # define __hidden_asmname1(prefix, name) __hidden_asmname2(prefix, name)
@@ -554,7 +558,10 @@ for linking")
# define hidden_ver(local, name) __hidden_ver1(local, __GI_##name, name); # define hidden_ver(local, name) __hidden_ver1(local, __GI_##name, name);
# define hidden_data_ver(local, name) hidden_ver(local, name) # define hidden_data_ver(local, name) hidden_ver(local, name)
# define hidden_def(name) __hidden_ver1(__GI_##name, name, name); # define hidden_def(name) __hidden_ver1(__GI_##name, name, name);
# define hidden_def_alias(name, internal) \
strong_alias (name, internal)
# define hidden_data_def(name) hidden_def(name) # define hidden_data_def(name) hidden_def(name)
# define hidden_data_def_alias(name, alias) hidden_def_alias(name, alias)
# define hidden_tls_def(name) \ # define hidden_tls_def(name) \
__hidden_ver2 (__thread, __GI_##name, name, name); __hidden_ver2 (__thread, __GI_##name, name, name);
# define hidden_weak(name) \ # define hidden_weak(name) \
@@ -581,9 +588,11 @@ for linking")
hidden_proto doesn't make sense for assembly but the equivalent hidden_proto doesn't make sense for assembly but the equivalent
is to call via the HIDDEN_JUMPTARGET macro instead of JUMPTARGET. */ is to call via the HIDDEN_JUMPTARGET macro instead of JUMPTARGET. */
# define hidden_def(name) strong_alias (name, __GI_##name) # define hidden_def(name) strong_alias (name, __GI_##name)
# define hidden_def_alias(name, alias) strong_alias (name, alias)
# define hidden_weak(name) hidden_def (name) # define hidden_weak(name) hidden_def (name)
# define hidden_ver(local, name) strong_alias (local, __GI_##name) # define hidden_ver(local, name) strong_alias (local, __GI_##name)
# define hidden_data_def(name) strong_data_alias (name, __GI_##name) # define hidden_data_def(name) strong_data_alias (name, __GI_##name)
# define hidden_data_def_alias(name, alias) strong_data_alias (name, alias)
# define hidden_tls_def(name) hidden_data_def (name) # define hidden_tls_def(name) hidden_data_def (name)
# define hidden_data_weak(name) hidden_data_def (name) # define hidden_data_weak(name) hidden_data_def (name)
# define hidden_data_ver(local, name) strong_data_alias (local, __GI_##name) # define hidden_data_ver(local, name) strong_data_alias (local, __GI_##name)
@@ -598,12 +607,17 @@ for linking")
__attribute__ ((visibility ("hidden"), ##attrs)) __attribute__ ((visibility ("hidden"), ##attrs))
# define hidden_proto(name, attrs...) \ # define hidden_proto(name, attrs...) \
__hidden_proto (name, , name, ##attrs) __hidden_proto (name, , name, ##attrs)
# define hidden_proto_alias(name, alias, attrs...) \
__hidden_proto_alias (name, , alias, ##attrs)
# define hidden_tls_proto(name, attrs...) \ # define hidden_tls_proto(name, attrs...) \
__hidden_proto (name, __thread, name, ##attrs) __hidden_proto (name, __thread, name, ##attrs)
# define __hidden_proto(name, thread, internal, attrs...) \ # define __hidden_proto(name, thread, internal, attrs...) \
extern thread __typeof (name) name __hidden_proto_hiddenattr (attrs); extern thread __typeof (name) name __hidden_proto_hiddenattr (attrs);
# define __hidden_proto_alias(name, thread, internal, attrs...) \
extern thread __typeof (name) internal __hidden_proto_hiddenattr (attrs);
# else # else
# define hidden_proto(name, attrs...) # define hidden_proto(name, attrs...)
# define hidden_proto_alias(name, alias, attrs...)
# define hidden_tls_proto(name, attrs...) # define hidden_tls_proto(name, attrs...)
# endif # endif
# else # else
@@ -611,9 +625,11 @@ for linking")
# endif /* Not __ASSEMBLER__ */ # endif /* Not __ASSEMBLER__ */
# define hidden_weak(name) # define hidden_weak(name)
# define hidden_def(name) # define hidden_def(name)
# define hidden_def_alias(name, alias)
# define hidden_ver(local, name) # define hidden_ver(local, name)
# define hidden_data_weak(name) # define hidden_data_weak(name)
# define hidden_data_def(name) # define hidden_data_def(name)
# define hidden_data_def_alias(name, alias)
# define hidden_tls_def(name) # define hidden_tls_def(name)
# define hidden_data_ver(local, name) # define hidden_data_ver(local, name)
# define hidden_nolink(name, lib, version) # define hidden_nolink(name, lib, version)
@@ -621,22 +637,28 @@ for linking")
#if IS_IN (libc) #if IS_IN (libc)
# define libc_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) # define libc_hidden_proto(name, attrs...) hidden_proto (name, ##attrs)
# define libc_hidden_proto_alias(name, alias, attrs...) \
hidden_proto_alias (name, alias, ##attrs)
# define libc_hidden_tls_proto(name, attrs...) hidden_tls_proto (name, ##attrs) # define libc_hidden_tls_proto(name, attrs...) hidden_tls_proto (name, ##attrs)
# define libc_hidden_def(name) hidden_def (name) # define libc_hidden_def(name) hidden_def (name)
# define libc_hidden_def_alias(name, alias) hidden_def_alias (name, alias)
# define libc_hidden_weak(name) hidden_weak (name) # define libc_hidden_weak(name) hidden_weak (name)
# define libc_hidden_nolink_sunrpc(name, version) hidden_nolink (name, libc, version) # define libc_hidden_nolink_sunrpc(name, version) hidden_nolink (name, libc, version)
# define libc_hidden_ver(local, name) hidden_ver (local, name) # define libc_hidden_ver(local, name) hidden_ver (local, name)
# define libc_hidden_data_def(name) hidden_data_def (name) # define libc_hidden_data_def(name) hidden_data_def (name)
# define libc_hidden_data_def_alias(name, alias) hidden_data_def_alias (name, alias)
# define libc_hidden_tls_def(name) hidden_tls_def (name) # define libc_hidden_tls_def(name) hidden_tls_def (name)
# define libc_hidden_data_weak(name) hidden_data_weak (name) # define libc_hidden_data_weak(name) hidden_data_weak (name)
# define libc_hidden_data_ver(local, name) hidden_data_ver (local, name) # define libc_hidden_data_ver(local, name) hidden_data_ver (local, name)
#else #else
# define libc_hidden_proto(name, attrs...) # define libc_hidden_proto(name, attrs...)
# define libc_hidden_proto_alias(name, alias, attrs...)
# define libc_hidden_tls_proto(name, attrs...) # define libc_hidden_tls_proto(name, attrs...)
# define libc_hidden_def(name) # define libc_hidden_def(name)
# define libc_hidden_weak(name) # define libc_hidden_weak(name)
# define libc_hidden_ver(local, name) # define libc_hidden_ver(local, name)
# define libc_hidden_data_def(name) # define libc_hidden_data_def(name)
# define libc_hidden_data_def_alias(name, alias)
# define libc_hidden_tls_def(name) # define libc_hidden_tls_def(name)
# define libc_hidden_data_weak(name) # define libc_hidden_data_weak(name)
# define libc_hidden_data_ver(local, name) # define libc_hidden_data_ver(local, name)

View File

@@ -1 +1,12 @@
#include <misc/sys/single_threaded.h> #include <misc/sys/single_threaded.h>
#ifndef _ISOMAC
libc_hidden_proto_alias (__libc_single_threaded,
__libc_single_threaded_internal);
#if !defined SHARED || !IS_IN(libc)
# define __libc_single_threaded_internal __libc_single_threaded
#endif
#endif

View File

@@ -25,3 +25,5 @@ char __libc_single_threaded;
#else #else
char __libc_single_threaded = 1; char __libc_single_threaded = 1;
#endif #endif
libc_hidden_data_def_alias (__libc_single_threaded,
__libc_single_threaded_internal)

View File

@@ -624,9 +624,12 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
/* Avoid a data race in the multi-threaded case, and call the /* Avoid a data race in the multi-threaded case, and call the
deferred initialization only once. */ deferred initialization only once. */
if (__libc_single_threaded) if (__libc_single_threaded_internal)
{ {
late_init (); late_init ();
__libc_single_threaded_internal = 0;
/* __libc_single_threaded can be accessed through copy relocations, so
it requires to update the external copy. */
__libc_single_threaded = 0; __libc_single_threaded = 0;
} }

View File

@@ -45,7 +45,7 @@ __libc_fork (void)
requirement for fork (Austin Group tracker issue #62) this is requirement for fork (Austin Group tracker issue #62) this is
best effort to make is async-signal-safe at least for single-thread best effort to make is async-signal-safe at least for single-thread
case. */ case. */
bool multiple_threads = __libc_single_threaded == 0; bool multiple_threads = __libc_single_threaded_internal == 0;
uint64_t lastrun; uint64_t lastrun;
lastrun = __run_prefork_handlers (multiple_threads); lastrun = __run_prefork_handlers (multiple_threads);

View File

@@ -29,7 +29,7 @@
#define INLINE_SETXID_SYSCALL(name, nr, args...) \ #define INLINE_SETXID_SYSCALL(name, nr, args...) \
({ \ ({ \
int __result; \ int __result; \
if (!__libc_single_threaded) \ if (!__libc_single_threaded_internal) \
{ \ { \
struct xid_command __cmd; \ struct xid_command __cmd; \
__cmd.syscall_no = __NR_##name; \ __cmd.syscall_no = __NR_##name; \