diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-05-19 07:08:23 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-05-19 07:08:23 +0000 |
commit | df94b6412e0628cd577da0ce5626358a3967ee44 (patch) | |
tree | 3b969d3e4175fe3a72f824c482d8c9f9a3b3bf3e /nptl/sysdeps | |
parent | 2acd01acb10d0c0113f87bf7e787e0854498269d (diff) | |
download | glibc-df94b6412e0628cd577da0ce5626358a3967ee44.tar glibc-df94b6412e0628cd577da0ce5626358a3967ee44.tar.gz glibc-df94b6412e0628cd577da0ce5626358a3967ee44.tar.bz2 glibc-df94b6412e0628cd577da0ce5626358a3967ee44.zip |
* elf/dl-close.c (_dl_close_worker): When removing object from
global scope, wait for all lookups to finish afterwards.
* elf/dl-open.c (add_to_global): When global scope array must
grow, allocate a new one and free old array only after all
lookups finish.
* elf/dl-runtime.c (_dl_fixup): Protect using global scope.
(_dl_lookup_symbol_x): Likewise.
* elf/dl-support.c: Define _dl_wait_lookup_done.
* sysdeps/generic/ldsodefs.h (struct rtld_global): Add
_dl_wait_lookup_done.
Diffstat (limited to 'nptl/sysdeps')
-rw-r--r-- | nptl/sysdeps/i386/tls.h | 33 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/pthread-functions.h | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c | 7 | ||||
-rw-r--r-- | nptl/sysdeps/x86_64/tls.h | 26 |
4 files changed, 66 insertions, 2 deletions
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h index d5b3797e69..d9044f3fde 100644 --- a/nptl/sysdeps/i386/tls.h +++ b/nptl/sysdeps/i386/tls.h @@ -1,5 +1,5 @@ /* Definition for thread-local data handling. nptl/i386 version. - Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2002,2003,2004,2005,2006,2007 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 @@ -27,6 +27,7 @@ # include <stdint.h> # include <stdlib.h> # include <list.h> +# include <sysdep.h> /* Type for the dtv. */ @@ -51,6 +52,7 @@ typedef struct uintptr_t sysinfo; uintptr_t stack_guard; uintptr_t pointer_guard; + int gscope_flag; } tcbhead_t; # define TLS_MULTIPLE_THREADS_IN_TCB 1 @@ -431,6 +433,35 @@ union user_desc_init = THREAD_GETMEM (THREAD_SELF, header.pointer_guard)) +/* Get and set the global scope generation counter in the TCB head. */ +#define THREAD_GSCOPE_FLAG_UNUSED 0 +#define THREAD_GSCOPE_FLAG_USED 1 +#define THREAD_GSCOPE_FLAG_WAIT 2 +#define THREAD_GSCOPE_RESET_FLAG() \ + do \ + { int __res; \ + asm volatile ("xchg %0, %%gs:%P1" \ + : "=r" (__res) \ + : "i" (offsetof (struct pthread, header.gscope_flag)), \ + "0" (THREAD_GSCOPE_FLAG_UNUSED)); \ + if (__res == THREAD_GSCOPE_FLAG_WAIT) \ + lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ + } \ + while (0) +#define THREAD_GSCOPE_SET_FLAG() \ + THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED) +#ifdef PTR_DEMANGLE +# define THREAD_GSCOPE_WAIT() \ + do { void (*ptr) (void) = GL(dl_wait_lookup_done); \ + PTR_DEMANGLE (ptr); \ + ptr (); \ + } while (0) +#else +# define THREAD_GSCOPE_WAIT() \ + GL(dl_wait_lookup_done) () +#endif + + #endif /* __ASSEMBLER__ */ #endif /* tls.h */ diff --git a/nptl/sysdeps/pthread/pthread-functions.h b/nptl/sysdeps/pthread/pthread-functions.h index a13b937032..f0eddd3053 100644 --- a/nptl/sysdeps/pthread/pthread-functions.h +++ b/nptl/sysdeps/pthread/pthread-functions.h @@ -97,7 +97,7 @@ struct pthread_functions void (*ptr__nptl_deallocate_tsd) (void); int (*ptr__nptl_setxid) (struct xid_command *); void (*ptr_freeres) (void); - void (*ptr_wait_lookup_done) (int); + void (*ptr_wait_lookup_done) (void); }; /* Variable in libc.so. */ diff --git a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c index 92a188a2f3..25509eb3d6 100644 --- a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c +++ b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c @@ -26,6 +26,7 @@ #include <pthreadP.h> #include <bits/libc-lock.h> #include <sysdep.h> +#include <ldsodefs.h> #ifdef TLS_MULTIPLE_THREADS_IN_TCB @@ -70,6 +71,12 @@ __libc_pthread_init (ptr, reclaim, functions) dest->parr[cnt] = p; } __libc_pthread_functions_init = 1; + +# ifdef RTLD_NOT_MANGLED + GL(dl_wait_lookup_done) = functions->ptr_wait_lookup_done; +# else + GL(dl_wait_lookup_done) = __libc_pthread_functions.ptr_wait_lookup_done; +# endif #endif #ifndef TLS_MULTIPLE_THREADS_IN_TCB diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h index 0b5aeb00ff..00c9abbfcb 100644 --- a/nptl/sysdeps/x86_64/tls.h +++ b/nptl/sysdeps/x86_64/tls.h @@ -26,6 +26,7 @@ # include <stddef.h> # include <stdint.h> # include <stdlib.h> +# include <sysdep.h> /* Type for the dtv. */ @@ -47,6 +48,7 @@ typedef struct dtv_t *dtv; void *self; /* Pointer to the thread descriptor. */ int multiple_threads; + int gscope_flag; uintptr_t sysinfo; uintptr_t stack_guard; uintptr_t pointer_guard; @@ -337,6 +339,30 @@ typedef struct = THREAD_GETMEM (THREAD_SELF, header.pointer_guard)) +/* Get and set the global scope generation counter in the TCB head. */ +#define THREAD_GSCOPE_FLAG_UNUSED 0 +#define THREAD_GSCOPE_FLAG_USED 1 +#define THREAD_GSCOPE_FLAG_WAIT 2 +#define THREAD_GSCOPE_RESET_FLAG() \ + do \ + { int __res; \ + asm volatile ("xchgl %0, %%fs:%P1" \ + : "=r" (__res) \ + : "i" (offsetof (struct pthread, header.gscope_flag)), \ + "0" (THREAD_GSCOPE_FLAG_UNUSED)); \ + if (__res == THREAD_GSCOPE_FLAG_WAIT) \ + lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ + } \ + while (0) +#define THREAD_GSCOPE_SET_FLAG() \ + THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED) +#define THREAD_GSCOPE_WAIT() \ + do { void (*ptr) (void) = GL(dl_wait_lookup_done); \ + PTR_DEMANGLE (ptr); \ + ptr (); \ + } while (0) + + #endif /* __ASSEMBLER__ */ #endif /* tls.h */ |