aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2020-11-16 19:33:30 +0100
committerFlorian Weimer <fweimer@redhat.com>2020-11-16 19:33:30 +0100
commit1daccf403b1bd86370eb94edca794dc106d02039 (patch)
treee54bc8ee71eb92b7114df79e2f378a477c470029 /sysdeps
parentaac0f62c47beee5b546bacc330acc2dd21cda0dc (diff)
downloadglibc-1daccf403b1bd86370eb94edca794dc106d02039.tar
glibc-1daccf403b1bd86370eb94edca794dc106d02039.tar.gz
glibc-1daccf403b1bd86370eb94edca794dc106d02039.tar.bz2
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.h2
-rw-r--r--sysdeps/alpha/nptl/tls.h2
-rw-r--r--sysdeps/arc/nptl/tls.h2
-rw-r--r--sysdeps/arm/nptl/tls.h2
-rw-r--r--sysdeps/csky/nptl/tls.h2
-rw-r--r--sysdeps/generic/ldsodefs.h19
-rw-r--r--sysdeps/hppa/nptl/tls.h2
-rw-r--r--sysdeps/i386/nptl/tls.h2
-rw-r--r--sysdeps/ia64/nptl/tls.h2
-rw-r--r--sysdeps/m68k/nptl/tls.h2
-rw-r--r--sysdeps/microblaze/nptl/tls.h2
-rw-r--r--sysdeps/mips/nptl/tls.h2
-rw-r--r--sysdeps/nios2/nptl/tls.h2
-rw-r--r--sysdeps/nptl/dl-thread_gscope_wait.c80
-rw-r--r--sysdeps/powerpc/nptl/tls.h2
-rw-r--r--sysdeps/riscv/nptl/tls.h2
-rw-r--r--sysdeps/s390/nptl/tls.h2
-rw-r--r--sysdeps/sh/nptl/tls.h2
-rw-r--r--sysdeps/sparc/nptl/tls.h2
-rw-r--r--sysdeps/x86_64/nptl/tls.h2
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__ */