This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 3/3] Single thread optimization refactor


Ping (x2).

On 31/08/2017 16:17, Adhemerval Zanella wrote:
> Ping.
> 
> On 07/08/2017 18:11, Adhemerval Zanella wrote:
>> Current GLIBC uses the define TLS_MULTIPLE_THREADS_IN_TCB to whether
>> declare or not the global variables used for the single thread
>> optimization for cancellable syscalls (STOCS).  ALthough it does work
>> correctly, this is not the correct define since there are architectures
>> that do not define TLS_MULTIPLE_THREADS_IN_TCB but does not use the
>> global variables (by prefering accessing the TCB/pthread_t fields
>> instead).
>>
>> With single thread optimization for cancellable syscalls refactored
>> by using SINGLE_THREAD_BY_GLOBAL define, we can use it instead to
>> define where the __{libc,pthread}_multiple_threads is defined.
>>
>> This is based on my "Remove sysdep-cancel assembly macro" patchset [1].
>>
>> 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.
>>
>> [1] https://sourceware.org/ml/libc-alpha/2017-08/msg00095.html
>> ---
>>  ChangeLog                               | 19 +++++++++++++++++++
>>  nptl/allocatestack.c                    |  9 +++------
>>  nptl/libc_multiple_threads.c            |  4 +---
>>  nptl/libc_pthread_init.c                | 12 ++++--------
>>  nptl/nptl-init.c                        | 14 +++++---------
>>  nptl/pthreadP.h                         | 14 --------------
>>  nptl/pthread_cancel.c                   |  7 +++----
>>  nptl/vars.c                             | 12 ++++++------
>>  sysdeps/unix/sysv/linux/sysdep-cancel.h | 27 +++++++++++++++++++++++++--
>>  9 files changed, 66 insertions(+), 52 deletions(-)
>>
>> diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
>> index ce2e24a..89cb0de 100644
>> --- a/nptl/allocatestack.c
>> +++ b/nptl/allocatestack.c
>> @@ -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
>> @@ -456,9 +457,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.  */
>> @@ -576,9 +575,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.  */
>> diff --git a/nptl/libc_multiple_threads.c b/nptl/libc_multiple_threads.c
>> index ef6a4be..1ae23e2 100644
>> --- a/nptl/libc_multiple_threads.c
>> +++ b/nptl/libc_multiple_threads.c
>> @@ -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
>> diff --git a/nptl/libc_pthread_init.c b/nptl/libc_pthread_init.c
>> index 0db7a10..aedd92f 100644
>> --- a/nptl/libc_pthread_init.c
>> +++ b/nptl/libc_pthread_init.c
>> @@ -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
>>  internal_function
>>  __libc_pthread_init (unsigned long int *ptr, void (*reclaim) (void),
>>  		     const struct pthread_functions *functions)
>> @@ -74,8 +68,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
>>  }
>>  
>> diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
>> index 2921607..a1320f3 100644
>> --- a/nptl/nptl-init.c
>> +++ b/nptl/nptl-init.c
>> @@ -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 ();
>> diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
>> index 6e7d6ff..a79f0b2 100644
>> --- a/nptl/pthreadP.h
>> +++ b/nptl/pthreadP.h
>> @@ -384,25 +384,11 @@ 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)
>> -     internal_function;
>> -#else
>>  extern int *__libc_pthread_init (unsigned long int *ptr,
>>  				 void (*reclaim) (void),
>>  				 const struct pthread_functions *functions)
>>       internal_function;
>>  
>> -/* 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
>> diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
>> index 742dfe6..f52ea08 100644
>> --- a/nptl/pthread_cancel.c
>> +++ b/nptl/pthread_cancel.c
>> @@ -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.  */
>> diff --git a/nptl/vars.c b/nptl/vars.c
>> index 198f463..20ebcd5 100644
>> --- a/nptl/vars.c
>> +++ b/nptl/vars.c
>> @@ -30,14 +30,14 @@ 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
>> +/* Table of the key information.  */
>> +struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX]
>> +  __attribute__ ((nocommon));
>> +hidden_data_def (__pthread_keys)
>> +
>> +#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.  */
>>  int __pthread_multiple_threads attribute_hidden;
>>  #endif
>> -
>> -/* Table of the key information.  */
>> -struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX]
>> -  __attribute__ ((nocommon));
>> -hidden_data_def (__pthread_keys)
>> diff --git a/sysdeps/unix/sysv/linux/sysdep-cancel.h b/sysdeps/unix/sysv/linux/sysdep-cancel.h
>> index 821114b..86044de 100644
>> --- a/sysdeps/unix/sysv/linux/sysdep-cancel.h
>> +++ b/sysdeps/unix/sysv/linux/sysdep-cancel.h
>> @@ -30,12 +30,24 @@
>>     thread check to use global variables instead of the pthread_t
>>     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)
>> @@ -46,7 +58,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
>> +
>> +# 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,			\
>> @@ -55,6 +76,8 @@ extern int __pthread_multiple_threads;
>>  /* For rtld, et cetera.  */
>>  #  define SINGLE_THREAD_P (1)
>>  # endif
>> +
>> +# define SET_SINGLE_THREAD_PTHREAD(__value)
>>  #endif
>>  
>>  #define RTLD_SINGLE_THREAD_P \
>>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]