@@ -32,6 +32,7 @@
#include <futex-internal.h>
#include <kernel-features.h>
#include <stack-aliasing.h>
+#include <sysdep-cancel.h>
#ifndef NEED_SEPARATE_REGISTER_STACK
@@ -482,9 +483,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
/* This is at least the second thread. */
pd->header.multiple_threads = 1;
-#ifndef TLS_MULTIPLE_THREADS_IN_TCB
- __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
-#endif
+ SET_SINGLE_THREAD_PTHREAD (1);
#ifndef __ASSUME_PRIVATE_FUTEX
/* The thread must know when private futexes are supported. */
@@ -602,9 +601,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
/* This is at least the second thread. */
pd->header.multiple_threads = 1;
-#ifndef TLS_MULTIPLE_THREADS_IN_TCB
- __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
-#endif
+ SET_SINGLE_THREAD_PTHREAD (1);
#ifndef __ASSUME_PRIVATE_FUTEX
/* The thread must know when private futexes are supported. */
@@ -18,11 +18,9 @@
#include <pthreadP.h>
-#if IS_IN (libc)
-# ifndef TLS_MULTIPLE_THREADS_IN_TCB
+#if IS_IN (libc) && defined (SINGLE_THREAD_BY_GLOBAL)
/* Variable set to a nonzero value either if more than one thread runs or ran,
or if a single-threaded process is trying to cancel itself. See
nptl/descr.h for more context on the single-threaded process case. */
int __libc_multiple_threads attribute_hidden;
-# endif
#endif
@@ -26,18 +26,12 @@
#include <libc-lock.h>
#include <sysdep.h>
#include <ldsodefs.h>
-
+#include <sysdep-cancel.h>
unsigned long int *__fork_generation_pointer;
-#ifdef TLS_MULTIPLE_THREADS_IN_TCB
-void
-#else
-extern int __libc_multiple_threads attribute_hidden;
-
int *
-#endif
__libc_pthread_init (unsigned long int *ptr, void (*reclaim) (void),
const struct pthread_functions *functions)
{
@@ -73,8 +67,10 @@ __libc_pthread_init (unsigned long int *ptr, void (*reclaim) (void),
__libc_pthread_functions_init = 1;
#endif
-#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+#ifdef SINGLE_THREAD_BY_GLOBAL
return &__libc_multiple_threads;
+# else
+ return NULL;
#endif
}
@@ -38,11 +38,9 @@
#include <kernel-features.h>
#include <libc-pointer-arith.h>
#include <pthread-pids.h>
+#include <sysdep-cancel.h>
-#ifndef TLS_MULTIPLE_THREADS_IN_TCB
-/* Pointer to the corresponding variable in libc. */
-int *__libc_multiple_threads_ptr attribute_hidden;
-#endif
+MULTIPLE_THREADS_PTR_DEF;
/* Size and alignment of static TLS block. */
size_t __static_tls_size;
@@ -457,11 +455,9 @@ __pthread_initialize_minimal_internal (void)
GL(dl_wait_lookup_done) = &__wait_lookup_done;
/* Register the fork generation counter with the libc. */
-#ifndef TLS_MULTIPLE_THREADS_IN_TCB
- __libc_multiple_threads_ptr =
-#endif
- __libc_pthread_init (&__fork_generation, __reclaim_stacks,
- ptr_pthread_functions);
+ MULTIPLE_THREADS_PTR_SET (__libc_pthread_init (&__fork_generation,
+ __reclaim_stacks,
+ ptr_pthread_functions));
/* Determine whether the machine is SMP or not. */
__is_smp = is_smp_system ();
@@ -382,23 +382,10 @@ hidden_proto (__nptl_create_event)
hidden_proto (__nptl_death_event)
/* Register the generation counter in the libpthread with the libc. */
-#ifdef TLS_MULTIPLE_THREADS_IN_TCB
-extern void __libc_pthread_init (unsigned long int *ptr,
- void (*reclaim) (void),
- const struct pthread_functions *functions);
-#else
extern int *__libc_pthread_init (unsigned long int *ptr,
void (*reclaim) (void),
const struct pthread_functions *functions);
-/* Variable set to a nonzero value either if more than one thread runs or ran,
- or if a single-threaded process is trying to cancel itself. See
- nptl/descr.h for more context on the single-threaded process case. */
-extern int __pthread_multiple_threads attribute_hidden;
-/* Pointer to the corresponding variable in libc. */
-extern int *__libc_multiple_threads_ptr attribute_hidden;
-#endif
-
/* Find a thread given its TID. */
extern struct pthread *__find_thread_by_id (pid_t tid) attribute_hidden
#ifdef SHARED
@@ -19,10 +19,11 @@
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
-#include "pthreadP.h"
#include <atomic.h>
#include <sysdep.h>
#include <unistd.h>
+#include <pthreadP.h>
+#include <sysdep-cancel.h>
int
__pthread_cancel (pthread_t th)
@@ -88,9 +89,7 @@ __pthread_cancel (pthread_t th)
cannot. So we set multiple_threads to true so that cancellation
points get executed. */
THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
-#ifndef TLS_MULTIPLE_THREADS_IN_TCB
- __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
-#endif
+ SET_SINGLE_THREAD_PTHREAD (1);
}
/* Mark the thread as canceled. This has to be done
atomically since other bits could be modified as well. */
@@ -30,7 +30,7 @@ int __default_pthread_attr_lock = LLL_LOCK_INITIALIZER;
/* Flag whether the machine is SMP or not. */
int __is_smp attribute_hidden;
-#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+#if IS_IN (libpthread) && defined (SINGLE_THREAD_BY_GLOBAL)
/* Variable set to a nonzero value either if more than one thread runs or ran,
or if a single-threaded process is trying to cancel itself. See
nptl/descr.h for more context on the single-threaded process case. */
@@ -52,8 +52,6 @@ typedef struct
void *__private_ss;
} tcbhead_t;
-# define TLS_MULTIPLE_THREADS_IN_TCB 1
-
#else /* __ASSEMBLER__ */
# include <tcb-offsets.h>
#endif
@@ -36,8 +36,6 @@ typedef struct
register struct pthread *__thread_self __asm__("r13");
-# define TLS_MULTIPLE_THREADS_IN_TCB 1
-
#else /* __ASSEMBLER__ */
# include <tcb-offsets.h>
#endif
@@ -10,9 +10,7 @@
# define thread_offsetof(mem) ((ptrdiff_t) THREAD_SELF + offsetof (struct pthread, mem))
-#if TLS_MULTIPLE_THREADS_IN_TCB
MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads)
-#endif
TID thread_offsetof (tid)
POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
TAR_SAVE (offsetof (tcbhead_t, tar_save) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
@@ -43,9 +43,6 @@
# define TLS_DTV_AT_TP 1
# define TLS_TCB_AT_TP 0
-/* We use the multiple_threads field in the pthread struct */
-#define TLS_MULTIPLE_THREADS_IN_TCB 1
-
/* Get the thread descriptor definition. */
# include <nptl/descr.h>
@@ -48,10 +48,6 @@ typedef struct
void *__private_ss;
} tcbhead_t;
-# ifndef __s390x__
-# define TLS_MULTIPLE_THREADS_IN_TCB 1
-# endif
-
#else /* __ASSEMBLER__ */
# include <tcb-offsets.h>
#endif
@@ -36,8 +36,6 @@ typedef struct
uintptr_t pointer_guard;
} tcbhead_t;
-# define TLS_MULTIPLE_THREADS_IN_TCB 1
-
#else /* __ASSEMBLER__ */
# include <tcb-offsets.h>
#endif /* __ASSEMBLER__ */
@@ -41,9 +41,6 @@
# define TLS_DTV_AT_TP 1
# define TLS_TCB_AT_TP 0
-/* We use the multiple_threads field in the pthread struct */
-#define TLS_MULTIPLE_THREADS_IN_TCB 1
-
/* Get the thread descriptor definition. */
# include <nptl/descr.h>
@@ -32,12 +32,24 @@
field. */
#ifdef SINGLE_THREAD_BY_GLOBAL
+
+extern int __pthread_multiple_threads attribute_hidden;
+
+/* Variable set to a nonzero value either if more than one thread runs or ran,
+ or if a single-threaded process is trying to cancel itself. See
+ nptl/descr.h for more context on the single-threaded process case. */
+# define MULTIPLE_THREADS_PTR_DEF \
+ int *__libc_multiple_threads_ptr attribute_hidden
+
+# define MULTIPLE_THREADS_PTR_SET(__ptr) \
+ __libc_multiple_threads_ptr = (__ptr)
+
# if IS_IN (libc)
-extern int __libc_multiple_threads;
+extern int __libc_multiple_threads attribute_hidden;
# define SINGLE_THREAD_P \
__glibc_likely (__libc_multiple_threads == 0)
# elif IS_IN (libpthread)
-extern int __pthread_multiple_threads;
+extern int *__libc_multiple_threads_ptr attribute_hidden;
# define SINGLE_THREAD_P \
__glibc_likely (__pthread_multiple_threads == 0)
# elif IS_IN (librt)
@@ -48,7 +60,16 @@ extern int __pthread_multiple_threads;
/* For rtld, et cetera. */
# define SINGLE_THREAD_P (1)
# endif
+
+# define SET_SINGLE_THREAD_PTHREAD(__value) \
+ *__libc_multiple_threads_ptr = __pthread_multiple_threads = (__value)
+
#else /* SINGLE_THREAD_BY_GLOBAL */
+
+# define MULTIPLE_THREADS_PTR_DEF
+
+# define MULTIPLE_THREADS_PTR_SET(__ptr) __ptr
+
# if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
# define SINGLE_THREAD_P \
__glibc_likely (THREAD_GETMEM (THREAD_SELF, \
@@ -57,6 +78,8 @@ extern int __pthread_multiple_threads;
/* For rtld, et cetera. */
# define SINGLE_THREAD_P (1)
# endif
+
+# define SET_SINGLE_THREAD_PTHREAD(__value)
#endif /* SINGLE_THREAD_BY_GLOBAL */
#define RTLD_SINGLE_THREAD_P \
Changes from previous version [1]: - Removed TLS_MULTIPLE_THREADS_IN_TCB define. --- GLIBC current uses the TLS_MULTIPLE_THREADS_IN_TCB define to declare and set the single thread optimization (STO) access by either a global variable or a field in TCB. However STO refactor (09c76a740998) added a new variable, SINGLE_THREAD_BY_GLOBAL, which essentially provides the same semantic. This patch remove the TLS_MULTIPLE_THREADS_IN_TCB and uses SINGLE_THREAD_BY_GLOBAL instead. It also adds some macros to access and modify the STO field depending of the prefered architecture way. It also make the archictures that actually use the global variable to include them on final lib{c,pthread}.so. For instance m68k lib{c,pthread}.so defines {__{pthread,libc}_multiple threads even though its STO is implemented by TCB access. Checked on x86_64-linux-gnu and on a build with major touched ABIs (aarch64-linux-gnu, alpha-linux-gnu, arm-linux-gnueabihf, hppa-linux-gnu, i686-linux-gnu, m68k-linux-gnu, microblaze-linux-gnu, mips-linux-gnu, mips64-linux-gnu, powerpc-linux-gnu, powerpc64le-linux-gnu, s390-linux-gnu, s390x-linux-gnu, sh4-linux-gnu, sparcv9-linux-gnu, sparc64-linux-gnu, tilegx-linux-gnu). * nptl/allocatestack.c (allocate_state): Use SET_SINGLE_THREAD_PTHREAD macro. * nptl/pthread_cancel.c (__pthread_cancel): Likewise. * nptl/libc_multiple_threads.c (__libc_multiple_threads): Define for libc and SINGLE_THREAD_BY_GLOBAL. * nptl/libc_pthread_init.c (__libc_pthread_init): Use same signature whether SINGLE_THREAD_BY_GLOBAL is set or not. * nptl/pthreadP.h (__libc_pthread_init): Likewise. * nptl/nptl-init.c (__libc_multiple_threads_ptr): Use MULTIPLE_THREADS_PTR_DEF. (__pthread_initialize_minimal_internal): Use MULTIPLE_THREADS_PTR_SET macro. * nptl/vars.c (__pthread_multiple_threads): Define for libpthread and SINGLE_THREAD_BY_GLOBAL. * sysdeps/unix/sysv/linux/sysdep-cancel.h (MULTIPLE_THREADS_PTR_DEF): Define. (MULTIPLE_THREADS_PTR_SET): Likewise. (SET_SINGLE_THREAD_PTHREAD): Likewise. * sysdeps/i386/nptl/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Remove. * sysdeps/ia64/nptl/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Likewise. * sysdeps/powerpc/nptl/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Likewise. * sysdeps/s390/nptl/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Likewise. * sysdeps/sh/nptl/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Likewise. * sysdeps/tile/nptl/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Likewise. * sysdeps/powerpc/nptl/tcb-offsets.sym (TLS_MULTIPLE_THREADS_IN_TCB): Likewise. [1] https://sourceware.org/ml/libc-alpha/2017-08/msg00238.html Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> --- ChangeLog | 29 +++++++++++++++++++++++++++++ nptl/allocatestack.c | 9 +++------ nptl/libc_multiple_threads.c | 4 +--- nptl/libc_pthread_init.c | 12 ++++-------- nptl/nptl-init.c | 14 +++++--------- nptl/pthreadP.h | 13 ------------- nptl/pthread_cancel.c | 7 +++---- nptl/vars.c | 2 +- sysdeps/i386/nptl/tls.h | 2 -- sysdeps/ia64/nptl/tls.h | 2 -- sysdeps/powerpc/nptl/tcb-offsets.sym | 2 -- sysdeps/powerpc/nptl/tls.h | 3 --- sysdeps/s390/nptl/tls.h | 4 ---- sysdeps/sh/nptl/tls.h | 2 -- sysdeps/tile/nptl/tls.h | 3 --- sysdeps/unix/sysv/linux/sysdep-cancel.h | 27 +++++++++++++++++++++++++-- 16 files changed, 71 insertions(+), 64 deletions(-) -- 2.7.4