This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH 1/4] Add single-thread.h header
- From: Adhemerval Zanella <adhemerval dot zanella at linaro dot org>
- To: libc-alpha at sourceware dot org
- Date: Thu, 9 May 2019 15:25:02 -0300
- Subject: Re: [PATCH 1/4] Add single-thread.h header
- References: <20190222192703.18177-1-adhemerval.zanella@linaro.org> <b201f27d-0ed8-a3c0-293f-1439da8e0750@linaro.org>
Ping (x2). This is mostly a refactor patch, no semantic changes
are expected.
On 09/04/2019 09:11, Adhemerval Zanella wrote:
> Ping.
>
> On 22/02/2019 16:27, Adhemerval Zanella wrote:
>> This patch move the single-thread syscall optimization defintions from
>> syscall-cancel.h to new header file single-thread.h and also move the
>> cancellation definitions from pthreadP.h to syscall-cancel.h.
>>
>> The idea is just simplify the inclusion of both syscall-cancel.h and
>> single-thread.h (without the requirement of including all pthreadP.h
>> defintions).
>>
>> No semantic changes expected, checked on a build for all major ABIs.
>>
>> * nptl/pthreadP.h (CANCEL_ASYNC, CANCEL_RESET, LIBC_CANCEL_ASYNC,
>> LIBC_CANCEL_RESET, __libc_enable_asynccancel,
>> __libc_disable_asynccancel, __librt_enable_asynccancel,
>> __libc_disable_asynccancel, __librt_enable_asynccancel,
>> __librt_disable_asynccancel): Move to ...
>> * sysdeps/unix/sysv/linux/sysdep-cancel.h: ... here.
>> (SINGLE_THREAD_P, RTLD_SINGLE_THREAD_P): Move to ...
>> * sysdeps/unix/sysv/linux/single-thread.h: ... here.
>> * sysdeps/generic/single-thread.h: New file.
>> * sysdeps/unix/sysdep.h: Include single-thread.h.
>> * sysdeps/unix/sysv/linux/futex-internal.h: Include sysdep-cancel.h.
>> * sysdeps/unix/sysv/linux/lowlevellock-futex.h: Likewise.
>> ---
>> nptl/pthreadP.h | 37 ---------
>> sysdeps/generic/single-thread.h | 24 ++++++
>> sysdeps/unix/sysdep.h | 2 +-
>> sysdeps/unix/sysv/linux/futex-internal.h | 2 +-
>> sysdeps/unix/sysv/linux/lowlevellock-futex.h | 2 +-
>> sysdeps/unix/sysv/linux/single-thread.h | 64 ++++++++++++++++
>> sysdeps/unix/sysv/linux/sysdep-cancel.h | 81 ++++++++++----------
>> 7 files changed, 133 insertions(+), 79 deletions(-)
>> create mode 100644 sysdeps/generic/single-thread.h
>> create mode 100644 sysdeps/unix/sysv/linux/single-thread.h
>>
>> diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
>> index 626bd4b096..0beacd1266 100644
>> --- a/nptl/pthreadP.h
>> +++ b/nptl/pthreadP.h
>> @@ -311,34 +311,6 @@ __do_cancel (void)
>> }
>>
>>
>> -/* Set cancellation mode to asynchronous. */
>> -#define CANCEL_ASYNC() \
>> - __pthread_enable_asynccancel ()
>> -/* Reset to previous cancellation mode. */
>> -#define CANCEL_RESET(oldtype) \
>> - __pthread_disable_asynccancel (oldtype)
>> -
>> -#if IS_IN (libc)
>> -/* Same as CANCEL_ASYNC, but for use in libc.so. */
>> -# define LIBC_CANCEL_ASYNC() \
>> - __libc_enable_asynccancel ()
>> -/* Same as CANCEL_RESET, but for use in libc.so. */
>> -# define LIBC_CANCEL_RESET(oldtype) \
>> - __libc_disable_asynccancel (oldtype)
>> -#elif IS_IN (libpthread)
>> -# define LIBC_CANCEL_ASYNC() CANCEL_ASYNC ()
>> -# define LIBC_CANCEL_RESET(val) CANCEL_RESET (val)
>> -#elif IS_IN (librt)
>> -# define LIBC_CANCEL_ASYNC() \
>> - __librt_enable_asynccancel ()
>> -# define LIBC_CANCEL_RESET(val) \
>> - __librt_disable_asynccancel (val)
>> -#else
>> -# define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */
>> -# define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it. */
>> -#endif
>> -
>> -
>> /* Internal prototypes. */
>>
>> /* Thread list handling. */
>> @@ -545,15 +517,6 @@ extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t *cond,
>> extern int __pthread_getaffinity_np (pthread_t th, size_t cpusetsize,
>> cpu_set_t *cpuset);
>>
>> -/* The two functions are in libc.so and not exported. */
>> -extern int __libc_enable_asynccancel (void) attribute_hidden;
>> -extern void __libc_disable_asynccancel (int oldtype) attribute_hidden;
>> -
>> -
>> -/* The two functions are in librt.so and not exported. */
>> -extern int __librt_enable_asynccancel (void) attribute_hidden;
>> -extern void __librt_disable_asynccancel (int oldtype) attribute_hidden;
>> -
>> #if IS_IN (libpthread)
>> /* Special versions which use non-exported functions. */
>> extern void __pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
>> diff --git a/sysdeps/generic/single-thread.h b/sysdeps/generic/single-thread.h
>> new file mode 100644
>> index 0000000000..0a1520ec49
>> --- /dev/null
>> +++ b/sysdeps/generic/single-thread.h
>> @@ -0,0 +1,24 @@
>> +/* Single thread optimization, generic version.
>> + Copyright (C) 2019 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
>> + modify it under the terms of the GNU Lesser General Public
>> + License as published by the Free Software Foundation; either
>> + version 2.1 of the License, or (at your option) any later version.
>> +
>> + The GNU C Library is distributed in the hope that it will be useful,
>> + but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + Lesser General Public License for more details.
>> +
>> + You should have received a copy of the GNU Lesser General Public
>> + License along with the GNU C Library; if not, see
>> + <http://www.gnu.org/licenses/>. */
>> +
>> +#ifndef _SINGLE_THREAD_H
>> +#define _SINGLE_THREAD_H
>> +
>> +#define SINGLE_THREAD_P (0)
>> +
>> +#endif /* _SINGLE_THREAD_H */
>> diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h
>> index 7cb6c89825..6e503d7688 100644
>> --- a/sysdeps/unix/sysdep.h
>> +++ b/sysdeps/unix/sysdep.h
>> @@ -16,7 +16,7 @@
>> <http://www.gnu.org/licenses/>. */
>>
>> #include <sysdeps/generic/sysdep.h>
>> -
>> +#include <single-thread.h>
>> #include <sys/syscall.h>
>> #define HAVE_SYSCALLS
>>
>> diff --git a/sysdeps/unix/sysv/linux/futex-internal.h b/sysdeps/unix/sysv/linux/futex-internal.h
>> index 55f0fab77c..501f993853 100644
>> --- a/sysdeps/unix/sysv/linux/futex-internal.h
>> +++ b/sysdeps/unix/sysv/linux/futex-internal.h
>> @@ -22,7 +22,7 @@
>> #include <sysdeps/nptl/futex-internal.h>
>> #include <errno.h>
>> #include <lowlevellock-futex.h>
>> -#include <nptl/pthreadP.h>
>> +#include <sysdep-cancel.h>
>>
>> /* See sysdeps/nptl/futex-internal.h for documentation; this file only
>> contains Linux-specific comments.
>> diff --git a/sysdeps/unix/sysv/linux/lowlevellock-futex.h b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
>> index 6f060b1739..030a14b8dc 100644
>> --- a/sysdeps/unix/sysv/linux/lowlevellock-futex.h
>> +++ b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
>> @@ -21,7 +21,7 @@
>>
>> #ifndef __ASSEMBLER__
>> #include <sysdep.h>
>> -#include <tls.h>
>> +#include <sysdep-cancel.h>
>> #include <kernel-features.h>
>> #endif
>>
>> diff --git a/sysdeps/unix/sysv/linux/single-thread.h b/sysdeps/unix/sysv/linux/single-thread.h
>> new file mode 100644
>> index 0000000000..8248c5d8b8
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/single-thread.h
>> @@ -0,0 +1,64 @@
>> +/* Single thread optimization, Linux version.
>> + Copyright (C) 2019 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
>> + modify it under the terms of the GNU Lesser General Public
>> + License as published by the Free Software Foundation; either
>> + version 2.1 of the License, or (at your option) any later version.
>> +
>> + The GNU C Library is distributed in the hope that it will be useful,
>> + but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + Lesser General Public License for more details.
>> +
>> + You should have received a copy of the GNU Lesser General Public
>> + License along with the GNU C Library; if not, see
>> + <http://www.gnu.org/licenses/>. */
>> +
>> +#ifndef _SINGLE_THREAD_H
>> +#define _SINGLE_THREAD_H
>> +
>> +/* The default way to check if the process is single thread is by using the
>> + pthread_t 'multiple_threads' field. However for some architectures it
>> + is faster to either use an extra field on TCB or global varibles
>> + (the TCB field is also used on x86 for some single-thread atomic
>> + optimizations).
>> +
>> + The ABI might define SINGLE_THREAD_BY_GLOBAL to enable the single
>> + thread check to use global variables instead of the pthread_t
>> + field. */
>> +
>> +#ifdef SINGLE_THREAD_BY_GLOBAL
>> +# if IS_IN (libc)
>> +extern int __libc_multiple_threads;
>> +# define SINGLE_THREAD_P \
>> + __glibc_likely (__libc_multiple_threads == 0)
>> +# elif IS_IN (libpthread)
>> +extern int __pthread_multiple_threads;
>> +# define SINGLE_THREAD_P \
>> + __glibc_likely (__pthread_multiple_threads == 0)
>> +# elif IS_IN (librt)
>> +# define SINGLE_THREAD_P \
>> + __glibc_likely (THREAD_GETMEM (THREAD_SELF, \
>> + header.multiple_threads) == 0)
>> +# else
>> +/* For rtld, et cetera. */
>> +# define SINGLE_THREAD_P (1)
>> +# endif
>> +#else /* SINGLE_THREAD_BY_GLOBAL */
>> +# if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
>> +# define SINGLE_THREAD_P \
>> + __glibc_likely (THREAD_GETMEM (THREAD_SELF, \
>> + header.multiple_threads) == 0)
>> +# else
>> +/* For rtld, et cetera. */
>> +# define SINGLE_THREAD_P (1)
>> +# endif
>> +#endif /* SINGLE_THREAD_BY_GLOBAL */
>> +
>> +#define RTLD_SINGLE_THREAD_P \
>> + __glibc_likely (THREAD_GETMEM (THREAD_SELF, \
>> + header.multiple_threads) == 0)
>> +
>> +#endif /* _SINGLE_THREAD_H */
>> diff --git a/sysdeps/unix/sysv/linux/sysdep-cancel.h b/sysdeps/unix/sysv/linux/sysdep-cancel.h
>> index 896549c7f7..a831b30106 100644
>> --- a/sysdeps/unix/sysv/linux/sysdep-cancel.h
>> +++ b/sysdeps/unix/sysv/linux/sysdep-cancel.h
>> @@ -17,48 +17,51 @@
>> License along with the GNU C Library; if not, see
>> <http://www.gnu.org/licenses/>. */
>>
>> +#ifndef _SYSDEP_CANCEL_H
>> +#define _SYSDEP_CANCEL_H
>> +
>> #include <sysdep.h>
>> #include <tls.h>
>> -#include <nptl/pthreadP.h>
>> +#include <errno.h>
>> +
>> +/* The two functions are in libc.so and not exported. */
>> +extern int __libc_enable_asynccancel (void) attribute_hidden;
>> +extern void __libc_disable_asynccancel (int oldtype) attribute_hidden;
>> +
>> +/* The two functions are in librt.so and not exported. */
>> +extern int __librt_enable_asynccancel (void) attribute_hidden;
>> +extern void __librt_disable_asynccancel (int oldtype) attribute_hidden;
>> +
>> +/* The two functions are in libpthread.so and not exported. */
>> +extern int __pthread_enable_asynccancel (void) attribute_hidden;
>> +extern void __pthread_disable_asynccancel (int oldtype) attribute_hidden;
>>
>> -/* The default way to check if the process is single thread is by using the
>> - pthread_t 'multiple_threads' field. However for some architectures it
>> - is faster to either use an extra field on TCB or global varibles
>> - (the TCB field is also used on x86 for some single-thread atomic
>> - optimizations).
>> +/* Set cancellation mode to asynchronous. */
>> +#define CANCEL_ASYNC() \
>> + __pthread_enable_asynccancel ()
>> +/* Reset to previous cancellation mode. */
>> +#define CANCEL_RESET(oldtype) \
>> + __pthread_disable_asynccancel (oldtype)
>>
>> - The ABI might define SINGLE_THREAD_BY_GLOBAL to enable the single
>> - thread check to use global variables instead of the pthread_t
>> - field. */
>> +#if IS_IN (libc)
>> +/* Same as CANCEL_ASYNC, but for use in libc.so. */
>> +# define LIBC_CANCEL_ASYNC() \
>> + __libc_enable_asynccancel ()
>> +/* Same as CANCEL_RESET, but for use in libc.so. */
>> +# define LIBC_CANCEL_RESET(oldtype) \
>> + __libc_disable_asynccancel (oldtype)
>> +#elif IS_IN (libpthread)
>> +# define LIBC_CANCEL_ASYNC() CANCEL_ASYNC ()
>> +# define LIBC_CANCEL_RESET(val) CANCEL_RESET (val)
>> +#elif IS_IN (librt)
>> +# define LIBC_CANCEL_ASYNC() \
>> + __librt_enable_asynccancel ()
>> +# define LIBC_CANCEL_RESET(val) \
>> + __librt_disable_asynccancel (val)
>> +#else
>> +# define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */
>> +# define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it. */
>> +#endif
>>
>> -#ifdef SINGLE_THREAD_BY_GLOBAL
>> -# if IS_IN (libc)
>> -extern int __libc_multiple_threads;
>> -# define SINGLE_THREAD_P \
>> - __glibc_likely (__libc_multiple_threads == 0)
>> -# elif IS_IN (libpthread)
>> -extern int __pthread_multiple_threads;
>> -# define SINGLE_THREAD_P \
>> - __glibc_likely (__pthread_multiple_threads == 0)
>> -# elif IS_IN (librt)
>> -# define SINGLE_THREAD_P \
>> - __glibc_likely (THREAD_GETMEM (THREAD_SELF, \
>> - header.multiple_threads) == 0)
>> -# else
>> -/* For rtld, et cetera. */
>> -# define SINGLE_THREAD_P (1)
>> -# endif
>> -#else /* SINGLE_THREAD_BY_GLOBAL */
>> -# if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
>> -# define SINGLE_THREAD_P \
>> - __glibc_likely (THREAD_GETMEM (THREAD_SELF, \
>> - header.multiple_threads) == 0)
>> -# else
>> -/* For rtld, et cetera. */
>> -# define SINGLE_THREAD_P (1)
>> -# endif
>> -#endif /* SINGLE_THREAD_BY_GLOBAL */
>>
>> -#define RTLD_SINGLE_THREAD_P \
>> - __glibc_likely (THREAD_GETMEM (THREAD_SELF, \
>> - header.multiple_threads) == 0)
>> +#endif
>>