Message ID | 20190222192703.18177-1-adhemerval.zanella@linaro.org |
---|---|
State | Accepted |
Commit | fdb8a0be9b3fea36e6c8b471c77d42e0b803720e |
Headers | show |
Series | [1/4] Add single-thread.h header | expand |
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 >
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 >>
If no one opposes it, I will commit this shortly (the rest of patchset is already accepted). On 09/05/2019 15:25, Adhemerval Zanella wrote: > 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 >>>
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