diff options
Diffstat (limited to 'ldso/dynlink.c')
-rw-r--r-- | ldso/dynlink.c | 38 |
1 files changed, 6 insertions, 32 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c index c7d9dd3..025ed1b 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -18,6 +18,7 @@ #include <ctype.h> #include <dlfcn.h> #include <semaphore.h> +#include <sys/membarrier.h> #include "pthread_impl.h" #include "libc.h" #include "dynlink.h" @@ -1351,18 +1352,6 @@ static void update_tls_size() tls_align); } -void __dl_prepare_for_threads(void) -{ - /* MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED */ - __syscall(SYS_membarrier, 1<<4, 0); -} - -static sem_t barrier_sem; -static void bcast_barrier(int s) -{ - sem_post(&barrier_sem); -} - static void install_new_tls(void) { sigset_t set; @@ -1397,26 +1386,11 @@ static void install_new_tls(void) } /* Broadcast barrier to ensure contents of new dtv is visible - * if the new dtv pointer is. Use SYS_membarrier if it works, - * otherwise emulate with a signal. */ - - /* MEMBARRIER_CMD_PRIVATE_EXPEDITED */ - if (__syscall(SYS_membarrier, 1<<3, 0)) { - sem_init(&barrier_sem, 0, 0); - struct sigaction sa = { - .sa_flags = SA_RESTART, - .sa_handler = bcast_barrier - }; - memset(&sa.sa_mask, -1, sizeof sa.sa_mask); - __libc_sigaction(SIGSYNCCALL, &sa, 0); - for (td=self->next; td!=self; td=td->next) - __syscall(SYS_tkill, td->tid, SIGSYNCCALL); - for (td=self->next; td!=self; td=td->next) - sem_wait(&barrier_sem); - sa.sa_handler = SIG_IGN; - __libc_sigaction(SIGSYNCCALL, &sa, 0); - sem_destroy(&barrier_sem); - } + * if the new dtv pointer is. The __membarrier function has a + * fallback emulation using signals for kernels that lack the + * feature at the syscall level. */ + + __membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0); /* Install new dtv for each thread. */ for (j=0, td=self; !j || td!=self; j++, td=td->next) { |