diff options
author | Florian Weimer <fweimer@redhat.com> | 2020-11-16 19:33:30 +0100 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2020-11-16 19:33:30 +0100 |
commit | 1daccf403b1bd86370eb94edca794dc106d02039 (patch) | |
tree | e54bc8ee71eb92b7114df79e2f378a477c470029 /sysdeps | |
parent | aac0f62c47beee5b546bacc330acc2dd21cda0dc (diff) | |
download | glibc-1daccf403b1bd86370eb94edca794dc106d02039.tar.gz glibc-1daccf403b1bd86370eb94edca794dc106d02039.tar.xz glibc-1daccf403b1bd86370eb94edca794dc106d02039.zip |
nptl: Move stack list variables into _rtld_global
Now __thread_gscope_wait (the function behind THREAD_GSCOPE_WAIT, formerly __wait_lookup_done) can be implemented directly in ld.so, eliminating the unprotected GL (dl_wait_lookup_done) function pointer. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/aarch64/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/alpha/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/arc/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/arm/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/csky/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 19 | ||||
-rw-r--r-- | sysdeps/hppa/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/i386/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/ia64/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/m68k/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/microblaze/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/mips/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/nios2/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/nptl/dl-thread_gscope_wait.c | 80 | ||||
-rw-r--r-- | sysdeps/powerpc/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/riscv/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/s390/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/sh/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/sparc/nptl/tls.h | 2 | ||||
-rw-r--r-- | sysdeps/x86_64/nptl/tls.h | 2 |
20 files changed, 96 insertions, 39 deletions
diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h index e5627f777e..dbef4704f1 100644 --- a/sysdeps/aarch64/nptl/tls.h +++ b/sysdeps/aarch64/nptl/tls.h @@ -129,8 +129,6 @@ typedef struct atomic_write_barrier (); \ } \ while (0) -# define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () # endif /* __ASSEMBLER__ */ diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h index 82549607fd..f3101f57c9 100644 --- a/sysdeps/alpha/nptl/tls.h +++ b/sysdeps/alpha/nptl/tls.h @@ -123,8 +123,6 @@ typedef struct atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #else /* __ASSEMBLER__ */ # include <tcb-offsets.h> diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h index 184b550ab5..cc5abb1931 100644 --- a/sysdeps/arc/nptl/tls.h +++ b/sysdeps/arc/nptl/tls.h @@ -131,8 +131,6 @@ typedef struct atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* !__ASSEMBLER__ */ diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h index 24a488ff37..91dd7498e4 100644 --- a/sysdeps/arm/nptl/tls.h +++ b/sysdeps/arm/nptl/tls.h @@ -120,8 +120,6 @@ typedef struct atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/csky/nptl/tls.h b/sysdeps/csky/nptl/tls.h index bcca9674a1..f308773d40 100644 --- a/sysdeps/csky/nptl/tls.h +++ b/sysdeps/csky/nptl/tls.h @@ -147,8 +147,6 @@ typedef struct atomic_write_barrier (); \ } \ while (0) -# define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 382eeb9be0..b1da03cafe 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -38,6 +38,7 @@ #include <libc-lock.h> #include <hp-timing.h> #include <tls.h> +#include <list_t.h> __BEGIN_DECLS @@ -461,15 +462,22 @@ struct rtld_global EXTERN void (*_dl_init_static_tls) (struct link_map *); - EXTERN void (*_dl_wait_lookup_done) (void); - /* Scopes to free after next THREAD_GSCOPE_WAIT (). */ EXTERN struct dl_scope_free_list { size_t count; void *list[50]; } *_dl_scope_free_list; -#if !THREAD_GSCOPE_IN_TCB +#if THREAD_GSCOPE_IN_TCB + /* List of active thread stacks, with memory managed by glibc. */ + EXTERN list_t _dl_stack_used; + + /* List of thread stacks that were allocated by the application. */ + EXTERN list_t _dl_stack_user; + + /* Mutex protecting the stack lists. */ + EXTERN int _dl_stack_cache_lock; +#else EXTERN int _dl_thread_gscope_count; #endif #ifdef SHARED @@ -1252,6 +1260,11 @@ link_map_audit_state (struct link_map *l, size_t index) } #endif /* SHARED */ +#if THREAD_GSCOPE_IN_TCB +void __thread_gscope_wait (void) attribute_hidden; +# define THREAD_GSCOPE_WAIT() __thread_gscope_wait () +#endif + __END_DECLS #endif /* ldsodefs.h */ diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h index 2315340735..f319cb42e2 100644 --- a/sysdeps/hppa/nptl/tls.h +++ b/sysdeps/hppa/nptl/tls.h @@ -154,8 +154,6 @@ static inline void __set_cr27(struct pthread *cr27) atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* !__ASSEMBLER__ */ diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h index 5042d52b98..b74347bacd 100644 --- a/sysdeps/i386/nptl/tls.h +++ b/sysdeps/i386/nptl/tls.h @@ -387,8 +387,6 @@ tls_fill_user_desc (union user_desc_init *desc, while (0) #define THREAD_GSCOPE_SET_FLAG() \ THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h index f5b1684ef3..42b082dad6 100644 --- a/sysdeps/ia64/nptl/tls.h +++ b/sysdeps/ia64/nptl/tls.h @@ -175,8 +175,6 @@ register struct pthread *__thread_self __asm__("r13"); atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h index 68ea952e79..69e174484e 100644 --- a/sysdeps/m68k/nptl/tls.h +++ b/sysdeps/m68k/nptl/tls.h @@ -153,8 +153,6 @@ extern void * __m68k_read_tp (void); atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h index a094fdb798..78f63019dc 100644 --- a/sysdeps/microblaze/nptl/tls.h +++ b/sysdeps/microblaze/nptl/tls.h @@ -136,8 +136,6 @@ typedef struct atomic_write_barrier (); \ } \ while (0) -# define THREAD_GSCOPE_WAIT() \ - GL (dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h index 8b55f19c37..7e7ac43d6c 100644 --- a/sysdeps/mips/nptl/tls.h +++ b/sysdeps/mips/nptl/tls.h @@ -178,8 +178,6 @@ typedef struct atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h index facb27c761..776fe9bb2d 100644 --- a/sysdeps/nios2/nptl/tls.h +++ b/sysdeps/nios2/nptl/tls.h @@ -157,8 +157,6 @@ register struct pthread *__thread_self __asm__("r23"); atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/nptl/dl-thread_gscope_wait.c b/sysdeps/nptl/dl-thread_gscope_wait.c new file mode 100644 index 0000000000..a9bfbee24c --- /dev/null +++ b/sysdeps/nptl/dl-thread_gscope_wait.c @@ -0,0 +1,80 @@ +/* Out-of-line notification function for the GSCOPE locking mechanism. + Copyright (C) 2007-2020 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 + <https://www.gnu.org/licenses/>. */ + +#include <nptl/descr.h> +#include <futex-internal.h> +#include <ldsodefs.h> +#include <list.h> +#include <lowlevellock.h> + +void +__thread_gscope_wait (void) +{ + lll_lock (GL (dl_stack_cache_lock), LLL_PRIVATE); + + struct pthread *self = THREAD_SELF; + + /* Iterate over the list with system-allocated threads first. */ + list_t *runp; + list_for_each (runp, &GL (dl_stack_used)) + { + struct pthread *t = list_entry (runp, struct pthread, list); + if (t == self || t->header.gscope_flag == THREAD_GSCOPE_FLAG_UNUSED) + continue; + + int *const gscope_flagp = &t->header.gscope_flag; + + /* We have to wait until this thread is done with the global + scope. First tell the thread that we are waiting and + possibly have to be woken. */ + if (atomic_compare_and_exchange_bool_acq (gscope_flagp, + THREAD_GSCOPE_FLAG_WAIT, + THREAD_GSCOPE_FLAG_USED)) + continue; + + do + futex_wait_simple ((unsigned int *) gscope_flagp, + THREAD_GSCOPE_FLAG_WAIT, FUTEX_PRIVATE); + while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT); + } + + /* Now the list with threads using user-allocated stacks. */ + list_for_each (runp, &GL (dl_stack_user)) + { + struct pthread *t = list_entry (runp, struct pthread, list); + if (t == self || t->header.gscope_flag == THREAD_GSCOPE_FLAG_UNUSED) + continue; + + int *const gscope_flagp = &t->header.gscope_flag; + + /* We have to wait until this thread is done with the global + scope. First tell the thread that we are waiting and + possibly have to be woken. */ + if (atomic_compare_and_exchange_bool_acq (gscope_flagp, + THREAD_GSCOPE_FLAG_WAIT, + THREAD_GSCOPE_FLAG_USED)) + continue; + + do + futex_wait_simple ((unsigned int *) gscope_flagp, + THREAD_GSCOPE_FLAG_WAIT, FUTEX_PRIVATE); + while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT); + } + + lll_unlock (GL (dl_stack_cache_lock), LLL_PRIVATE); +} diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h index b1f0b30fbb..261eecfd18 100644 --- a/sysdeps/powerpc/nptl/tls.h +++ b/sysdeps/powerpc/nptl/tls.h @@ -245,8 +245,6 @@ register void *__thread_register __asm__ ("r13"); atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/riscv/nptl/tls.h b/sysdeps/riscv/nptl/tls.h index a9167bc143..41d9db10cf 100644 --- a/sysdeps/riscv/nptl/tls.h +++ b/sysdeps/riscv/nptl/tls.h @@ -139,8 +139,6 @@ typedef struct atomic_write_barrier (); \ } \ while (0) -# define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h index 4a9b3570eb..7653109617 100644 --- a/sysdeps/s390/nptl/tls.h +++ b/sysdeps/s390/nptl/tls.h @@ -185,8 +185,6 @@ typedef struct atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h index 6ccad251f9..2d5e3731b2 100644 --- a/sysdeps/sh/nptl/tls.h +++ b/sysdeps/sh/nptl/tls.h @@ -161,8 +161,6 @@ typedef struct atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h index 18a548e86b..b08a156131 100644 --- a/sysdeps/sparc/nptl/tls.h +++ b/sysdeps/sparc/nptl/tls.h @@ -158,8 +158,6 @@ register struct pthread *__thread_self __asm__("%g7"); atomic_write_barrier (); \ } \ while (0) -#define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* !ASSEMBLER */ diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h index fbd7f9cb89..a08bf972de 100644 --- a/sysdeps/x86_64/nptl/tls.h +++ b/sysdeps/x86_64/nptl/tls.h @@ -332,8 +332,6 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80, while (0) # define THREAD_GSCOPE_SET_FLAG() \ THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED) -# define THREAD_GSCOPE_WAIT() \ - GL(dl_wait_lookup_done) () #endif /* __ASSEMBLER__ */ |