diff --git a/ChangeLog b/ChangeLog index d5458c7030..39f0e78837 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,150 @@ +2014-07-07 Roland McGrath + + * nptl/Makefile (routines): Add libc_pthread_init, + libc_multiple_threads, register-atfork and unregister-atfork. + (libpthread-routines): Add pthread_mutex_cond_lock and pt-fork here. + (gen-as-const-headers): Add lowlevelcond.sym, lowlevelrwlock.sym, + lowlevelbarrier.sym, unwindbuf.sym, lowlevelrobustlock.sym, + pthread-pi-defines.sym, structsem.sym. + * sysdeps/unix/sysv/linux/Makefile [$(subdir) = posix] + (CFLAGS-fork.c, CFLAGS-getpid.o, CFLAGS-getpid.os): New variables. + [$(subdir) = nptl] (tests): Add tst-setgetname. + * nptl/sysdeps/unix/sysv/linux/Makefile: File removed. + * sysdeps/unix/sysv/linux/sigaction.c: Just include + directly here, instead of WRAPPER_INCLUDE. + [!LIBC_SIGACTION]: Remove aliases. + * sysdeps/unix/sysv/linux/aarch64/sigaction.c: Likewise. + * sysdeps/unix/sysv/linux/arm/sigaction.c: Likewise. + * sysdeps/unix/sysv/linux/i386/sigaction.c: Likewise. + * sysdeps/unix/sysv/linux/ia64/sigaction.c: Likewise. + * sysdeps/unix/sysv/linux/mips/sigaction.c: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c: Likewise. + * sysdeps/unix/sysv/linux/x86_64/sigaction.c: Likewise. + * nptl/Versions (libc: GLIBC_2.3.2): Add __register_atfork. + (libc: GLIBC_PRIVATE): Add __libc_pthread_init, + __libc_current_sigrtmin_private, __libc_current_sigrtmax_private, + __libc_allocate_rtsig_private. + * nptl/sysdeps/unix/sysv/linux/Versions: File removed. + * sysdeps/unix/sysv/linux/sigtimedwait.c: Include . + * sysdeps/unix/sysv/linux/sigwait.c: Likewise. + * sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise. + * sysdeps/unix/sysv/linux/sleep.c: Likewise. + * nptl/sysdeps/unix/sysv/linux/sigwait.c: File removed. + * nptl/sysdeps/unix/sysv/linux/sigtimedwait.c: File removed. + * nptl/sysdeps/unix/sysv/linux/sigwaitinfo.c: File removed. + * nptl/sysdeps/unix/sysv/linux/sleep.c: File removed. + * nptl/sysdeps/unix/sysv/linux/createthread.c: File removed. + * sysdeps/unix/sysv/linux/ia64/fork.S: File removed. + * nptl/sysdeps/unix/sysv/linux/internaltypes.h: Moved ... + * nptl/internaltypes.h: ... here. + * nptl/sysdeps/unix/sysv/linux/jmp-unwind.c: Moved ... + * sysdeps/nptl/jmp-unwind.c: ... here. + * nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c: Moved ... + * nptl/libc-lowlevellock.c: ... here. + * nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c: Moved ... + * nptl/libc_multiple_threads.c: ... here. + * nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c: Moved ... + * nptl/libc_pthread_init.c: ... here. + * nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym: Moved ... + * nptl/lowlevelbarrier.sym: ... here. + * nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym: Moved ... + * nptl/lowlevelcond.sym: ... here. + * nptl/sysdeps/unix/sysv/linux/lowlevellock.c: Moved ... + * nptl/lowlevellock.c: ... here. + * nptl/lowlevellock.h: Moved ... + * sysdeps/nptl/lowlevellock.h: ... here. + * nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c: Moved ... + * nptl/lowlevelrobustlock.c: ... here. + * nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym: Moved ... + * nptl/lowlevelrobustlock.sym: ... here. + * nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym: Moved ... + * nptl/lowlevelrwlock.sym: ... here. + * nptl/sysdeps/unix/sysv/linux/pt-fork.c: Moved ... + * nptl/pt-fork.c: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym: Moved ... + * nptl/pthread-pi-defines.sym: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c: Moved ... + * nptl/pthread_attr_getaffinity.c: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c: Moved ... + * nptl/pthread_attr_setaffinity.c: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c: Moved ... + * nptl/pthread_mutex_cond_lock.c: ... here. + * sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c: + Update #include. + * sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c: Likewise. + * nptl/sysdeps/unix/sysv/linux/pthread_once.c: Moved ... + * nptl/pthread_once.c: ... here, replacing old file. + * nptl/sysdeps/unix/sysv/linux/pthread_yield.c: Moved ... + * nptl/pthread_yield.c: ... here. + * nptl/sysdeps/unix/sysv/linux/register-atfork.c: Moved ... + * nptl/register-atfork.c: ... here. + * nptl/sysdeps/unix/sysv/linux/sem_post.c: Moved ... + * nptl/sem_post.c: ... here. + * sysdeps/unix/sysv/linux/alpha/sem_post.c: Update #include. + * nptl/sysdeps/unix/sysv/linux/sem_timedwait.c: Moved ... + * nptl/sem_timedwait.c: ... here. + * nptl/sysdeps/unix/sysv/linux/sem_trywait.c: Moved ... + * nptl/sem_trywait.c: ... here. + * sysdeps/sparc/sparc32/sparcv9/sem_trywait.c: Update #include. + * nptl/sysdeps/unix/sysv/linux/sem_wait.c: Moved ... + * nptl/sem_wait.c: ... here. + * nptl/sysdeps/unix/sysv/linux/structsem.sym: Moved ... + * nptl/structsem.sym: ... here. + * nptl/sysdeps/unix/sysv/linux/mq_notify.c: Moved ... + * sysdeps/unix/sysv/linux/mq_notify.c: ... here, replacing old file. + * nptl/sysdeps/unix/sysv/linux/unregister-atfork.c: Moved ... + * nptl/unregister-atfork.c: ... here. + * nptl/sysdeps/unix/sysv/linux/unwindbuf.sym: Moved ... + * nptl/unwindbuf.sym: ... here. + * nptl/sysdeps/unix/sysv/linux/fork.c: Moved ... + * sysdeps/nptl/fork.c: ... here. + * nptl/sysdeps/unix/sysv/linux/fork.h: Moved ... + * sysdeps/nptl/fork.h: ... here. + * sysdeps/unix/sysv/linux/syscalls.list: Remove fork. + * nptl/sysdeps/unix/sysv/linux/aio_misc.h: Moved ... + * sysdeps/unix/sysv/linux/aio_misc.h: ... here. + * nptl/sysdeps/unix/sysv/linux/allocrtsig.c: Moved ... + * sysdeps/unix/sysv/linux/allocrtsig.c: ... here. + * nptl/sysdeps/unix/sysv/linux/getpid.c: Moved ... + * sysdeps/unix/sysv/linux/getpid.c: ... here. + * nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h: Moved ... + * sysdeps/unix/sysv/linux/kernel-posix-timers.h: ... here. + * nptl/sysdeps/unix/sysv/linux/pt-raise.c: Moved ... + * sysdeps/unix/sysv/linux/pt-raise.c: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread_getaffinity.c: Moved ... + * sysdeps/unix/sysv/linux/pthread_getaffinity.c: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c: Moved ... + * sysdeps/unix/sysv/linux/pthread_getcpuclockid.c: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread_getname.c: Moved ... + * sysdeps/unix/sysv/linux/pthread_getname.c: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread_kill.c: Moved ... + * sysdeps/unix/sysv/linux/pthread_kill.c: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c: Moved ... + * sysdeps/unix/sysv/linux/pthread_setaffinity.c: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread_setname.c: Moved ... + * sysdeps/unix/sysv/linux/pthread_setname.c: ... here. + * nptl/sysdeps/unix/sysv/linux/pthread_sigqueue.c: Moved ... + * sysdeps/unix/sysv/linux/pthread_sigqueue.c: ... here. + * nptl/sysdeps/unix/sysv/linux/raise.c: Moved ... + * sysdeps/unix/sysv/linux/raise.c: ... here. + * nptl/sysdeps/unix/sysv/linux/timer_create.c: Moved ... + * sysdeps/unix/sysv/linux/timer_create.c: ... here. + * nptl/sysdeps/unix/sysv/linux/timer_delete.c: Moved ... + * sysdeps/unix/sysv/linux/timer_delete.c: ... here. + * nptl/sysdeps/unix/sysv/linux/timer_getoverr.c: Moved ... + * sysdeps/unix/sysv/linux/timer_getoverr.c: ... here. + * nptl/sysdeps/unix/sysv/linux/timer_gettime.c: Moved ... + * sysdeps/unix/sysv/linux/timer_gettime.c: ... here. + * nptl/sysdeps/unix/sysv/linux/timer_routines.c: Moved ... + * sysdeps/unix/sysv/linux/timer_routines.c: ... here. + * nptl/sysdeps/unix/sysv/linux/timer_settime.c: Moved ... + * sysdeps/unix/sysv/linux/timer_settime.c: ... here. + * nptl/sysdeps/unix/sysv/linux/tst-setgetname.c: Moved ... + * sysdeps/unix/sysv/linux/tst-setgetname.c: ... here. + * sysdeps/unix/sysv/linux/s390/jmp-unwind.c: Update #include. + 2014-07-04 Siddhesh Poyarekar * sysdeps/generic/memcopy.h: Add comment for diff --git a/nptl/Makefile b/nptl/Makefile index cd3be126d6..67f7d5bfa9 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -29,7 +29,8 @@ extra-libs-others := $(extra-libs) install-lib-ldscripts := libpthread.so routines = alloca_cutoff forward libc-lowlevellock libc-cancellation \ - libc-cleanup + libc-cleanup libc_pthread_init libc_multiple_threads \ + register-atfork unregister-atfork shared-only-routines = forward libpthread-routines = nptl-init vars events version \ @@ -54,6 +55,7 @@ libpthread-routines = nptl-init vars events version \ pthread_mutex_init pthread_mutex_destroy \ pthread_mutex_lock pthread_mutex_trylock \ pthread_mutex_timedlock pthread_mutex_unlock \ + pthread_mutex_cond_lock \ pthread_mutexattr_init pthread_mutexattr_destroy \ pthread_mutexattr_getpshared \ pthread_mutexattr_setpshared \ @@ -103,7 +105,7 @@ libpthread-routines = nptl-init vars events version \ pt-longjmp pt-cleanup\ cancellation \ lowlevellock lowlevelrobustlock \ - pt-vfork \ + pt-fork pt-vfork \ ptw-write ptw-read ptw-close ptw-fcntl ptw-accept \ ptw-connect ptw-recv ptw-recvfrom ptw-recvmsg ptw-send \ ptw-sendmsg ptw-sendto ptw-fsync ptw-lseek ptw-llseek \ @@ -277,7 +279,12 @@ test-srcs = tst-oddstacklimit # Files which must not be linked with libpthread. tests-nolibpthread = tst-unload -gen-as-const-headers = pthread-errnos.sym +gen-as-const-headers = pthread-errnos.sym \ + lowlevelcond.sym lowlevelrwlock.sym \ + lowlevelbarrier.sym unwindbuf.sym \ + lowlevelrobustlock.sym pthread-pi-defines.sym \ + structsem.sym + LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst diff --git a/nptl/Versions b/nptl/Versions index 17a68ed5ee..b7d4a9b9d3 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -21,6 +21,8 @@ libc { pthread_attr_init; } GLIBC_2.3.2 { + __register_atfork; + # Changed pthread_cond_t. pthread_cond_init; pthread_cond_destroy; pthread_cond_wait; pthread_cond_signal; @@ -31,6 +33,9 @@ libc { # Internal libc interface to libpthread __libc_dl_error_tsd; __libc_vfork; + __libc_pthread_init; + __libc_current_sigrtmin_private; __libc_current_sigrtmax_private; + __libc_allocate_rtsig_private; } } diff --git a/nptl/sysdeps/unix/sysv/linux/internaltypes.h b/nptl/internaltypes.h similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/internaltypes.h rename to nptl/internaltypes.h diff --git a/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c b/nptl/libc-lowlevellock.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c rename to nptl/libc-lowlevellock.c diff --git a/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c b/nptl/libc_multiple_threads.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c rename to nptl/libc_multiple_threads.c diff --git a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c b/nptl/libc_pthread_init.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c rename to nptl/libc_pthread_init.c diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym b/nptl/lowlevelbarrier.sym similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym rename to nptl/lowlevelbarrier.sym diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym b/nptl/lowlevelcond.sym similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym rename to nptl/lowlevelcond.sym diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/nptl/lowlevellock.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/lowlevellock.c rename to nptl/lowlevellock.c diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/nptl/lowlevelrobustlock.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c rename to nptl/lowlevelrobustlock.c diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym b/nptl/lowlevelrobustlock.sym similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym rename to nptl/lowlevelrobustlock.sym diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym b/nptl/lowlevelrwlock.sym similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym rename to nptl/lowlevelrwlock.sym diff --git a/nptl/sysdeps/unix/sysv/linux/pt-fork.c b/nptl/pt-fork.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pt-fork.c rename to nptl/pt-fork.c diff --git a/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym b/nptl/pthread-pi-defines.sym similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym rename to nptl/pthread-pi-defines.sym diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c b/nptl/pthread_attr_getaffinity.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c rename to nptl/pthread_attr_getaffinity.c diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c b/nptl/pthread_attr_setaffinity.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c rename to nptl/pthread_attr_setaffinity.c diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c b/nptl/pthread_mutex_cond_lock.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c rename to nptl/pthread_mutex_cond_lock.c diff --git a/nptl/pthread_once.c b/nptl/pthread_once.c index 664b048acb..10c01d6023 100644 --- a/nptl/pthread_once.c +++ b/nptl/pthread_once.c @@ -1,6 +1,6 @@ -/* Copyright (C) 2002-2014 Free Software Foundation, Inc. +/* Copyright (C) 2003-2014 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2002. + Contributed by Jakub Jelinek , 2003. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -9,7 +9,7 @@ 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 + 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 @@ -18,37 +18,114 @@ #include "pthreadP.h" #include +#include - -static int once_lock = LLL_LOCK_INITIALIZER; +unsigned long int __fork_generation attribute_hidden; +static void +clear_once_control (void *arg) +{ + pthread_once_t *once_control = (pthread_once_t *) arg; + + /* Reset to the uninitialized state here. We don't need a stronger memory + order because we do not need to make any other of our writes visible to + other threads that see this value: This function will be called if we + get interrupted (see __pthread_once), so all we need to relay to other + threads is the state being reset again. */ + *once_control = 0; + lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); +} + + +/* This is similar to a lock implementation, but we distinguish between three + states: not yet initialized (0), initialization finished (2), and + initialization in progress (__fork_generation | 1). If in the first state, + threads will try to run the initialization by moving to the second state; + the first thread to do so via a CAS on once_control runs init_routine, + other threads block. + When forking the process, some threads can be interrupted during the second + state; they won't be present in the forked child, so we need to restart + initialization in the child. To distinguish an in-progress initialization + from an interrupted initialization (in which case we need to reclaim the + lock), we look at the fork generation that's part of the second state: We + can reclaim iff it differs from the current fork generation. + XXX: This algorithm has an ABA issue on the fork generation: If an + initialization is interrupted, we then fork 2^30 times (30 bits of + once_control are used for the fork generation), and try to initialize + again, we can deadlock because we can't distinguish the in-progress and + interrupted cases anymore. */ int __pthread_once (once_control, init_routine) pthread_once_t *once_control; void (*init_routine) (void); { - /* XXX Depending on whether the LOCK_IN_ONCE_T is defined use a - global lock variable or one which is part of the pthread_once_t - object. */ - if (*once_control == PTHREAD_ONCE_INIT) + while (1) { - lll_lock (once_lock, LLL_PRIVATE); + int oldval, val, newval; - /* XXX This implementation is not complete. It doesn't take - cancelation and fork into account. */ - if (*once_control == PTHREAD_ONCE_INIT) + /* We need acquire memory order for this load because if the value + signals that initialization has finished, we need to be see any + data modifications done during initialization. */ + val = *once_control; + atomic_read_barrier(); + do { - init_routine (); + /* Check if the initialization has already been done. */ + if (__glibc_likely ((val & 2) != 0)) + return 0; - *once_control = !PTHREAD_ONCE_INIT; + oldval = val; + /* We try to set the state to in-progress and having the current + fork generation. We don't need atomic accesses for the fork + generation because it's immutable in a particular process, and + forked child processes start with a single thread that modified + the generation. */ + newval = __fork_generation | 1; + /* We need acquire memory order here for the same reason as for the + load from once_control above. */ + val = atomic_compare_and_exchange_val_acq (once_control, newval, + oldval); + } + while (__glibc_unlikely (val != oldval)); + + /* Check if another thread already runs the initializer. */ + if ((oldval & 1) != 0) + { + /* Check whether the initializer execution was interrupted by a + fork. We know that for both values, bit 0 is set and bit 1 is + not. */ + if (oldval == newval) + { + /* Same generation, some other thread was faster. Wait. */ + lll_futex_wait (once_control, newval, LLL_PRIVATE); + continue; + } } - lll_unlock (once_lock, LLL_PRIVATE); + /* This thread is the first here. Do the initialization. + Register a cleanup handler so that in case the thread gets + interrupted the initialization can be restarted. */ + pthread_cleanup_push (clear_once_control, once_control); + + init_routine (); + + pthread_cleanup_pop (0); + + + /* Mark *once_control as having finished the initialization. We need + release memory order here because we need to synchronize with other + threads that want to use the initialized data. */ + atomic_write_barrier(); + *once_control = 2; + + /* Wake up all other threads. */ + lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); + break; } return 0; } -strong_alias (__pthread_once, pthread_once) +weak_alias (__pthread_once, pthread_once) hidden_def (__pthread_once) diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_yield.c b/nptl/pthread_yield.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_yield.c rename to nptl/pthread_yield.c diff --git a/nptl/sysdeps/unix/sysv/linux/register-atfork.c b/nptl/register-atfork.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/register-atfork.c rename to nptl/register-atfork.c diff --git a/nptl/sysdeps/unix/sysv/linux/sem_post.c b/nptl/sem_post.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/sem_post.c rename to nptl/sem_post.c diff --git a/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c b/nptl/sem_timedwait.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/sem_timedwait.c rename to nptl/sem_timedwait.c diff --git a/nptl/sysdeps/unix/sysv/linux/sem_trywait.c b/nptl/sem_trywait.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/sem_trywait.c rename to nptl/sem_trywait.c diff --git a/nptl/sysdeps/unix/sysv/linux/sem_wait.c b/nptl/sem_wait.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/sem_wait.c rename to nptl/sem_wait.c diff --git a/nptl/sysdeps/unix/sysv/linux/structsem.sym b/nptl/structsem.sym similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/structsem.sym rename to nptl/structsem.sym diff --git a/nptl/sysdeps/unix/sysv/linux/Makefile b/nptl/sysdeps/unix/sysv/linux/Makefile deleted file mode 100644 index 1a5a29df69..0000000000 --- a/nptl/sysdeps/unix/sysv/linux/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2002-2014 Free Software Foundation, Inc. -# This file is part of the GNU C Library. -# Contributed by Ulrich Drepper , 2002. - -# 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 -# . - -ifeq ($(subdir),nptl) -sysdep_routines += register-atfork unregister-atfork libc_pthread_init \ - libc_multiple_threads - -libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock - -gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \ - lowlevelbarrier.sym unwindbuf.sym \ - lowlevelrobustlock.sym pthread-pi-defines.sym \ - structsem.sym -tests += tst-setgetname -endif - -ifeq ($(subdir),posix) -CFLAGS-fork.c = $(libio-mtsafe) -CFLAGS-getpid.o = -fomit-frame-pointer -CFLAGS-getpid.os = -fomit-frame-pointer -endif - -# Needed in both the signal and nptl subdir. -CFLAGS-sigaction.c = -DWRAPPER_INCLUDE='' diff --git a/nptl/sysdeps/unix/sysv/linux/Versions b/nptl/sysdeps/unix/sysv/linux/Versions deleted file mode 100644 index d18255521c..0000000000 --- a/nptl/sysdeps/unix/sysv/linux/Versions +++ /dev/null @@ -1,15 +0,0 @@ -libc { - GLIBC_2.3.2 { - __register_atfork; - } - GLIBC_PRIVATE { - __libc_pthread_init; - __libc_current_sigrtmin_private; __libc_current_sigrtmax_private; - __libc_allocate_rtsig_private; - } -} -libpthread { - GLIBC_2.0 { - fork; __fork; - } -} diff --git a/nptl/sysdeps/unix/sysv/linux/createthread.c b/nptl/sysdeps/unix/sysv/linux/createthread.c deleted file mode 100644 index 9a21f3997a..0000000000 --- a/nptl/sysdeps/unix/sysv/linux/createthread.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2003-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Martin Schwidefsky . - - 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 - . */ - -/* Value passed to 'clone' for initialization of the thread register. */ -#define TLS_VALUE pd - -/* Get the real implementation. */ -#include diff --git a/nptl/sysdeps/unix/sysv/linux/mq_notify.c b/nptl/sysdeps/unix/sysv/linux/mq_notify.c deleted file mode 100644 index d50a9f2d57..0000000000 --- a/nptl/sysdeps/unix/sysv/linux/mq_notify.c +++ /dev/null @@ -1,282 +0,0 @@ -/* Copyright (C) 2004-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contribute by Ulrich Drepper , 2004. - - 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifdef __NR_mq_notify - -/* Defined in the kernel headers: */ -#define NOTIFY_COOKIE_LEN 32 /* Length of the cookie used. */ -#define NOTIFY_WOKENUP 1 /* Code for notifcation. */ -#define NOTIFY_REMOVED 2 /* Code for closed message queue - of de-notifcation. */ - - -/* Data structure for the queued notification requests. */ -union notify_data -{ - struct - { - void (*fct) (union sigval); /* The function to run. */ - union sigval param; /* The parameter to pass. */ - pthread_attr_t *attr; /* Attributes to create the thread with. */ - /* NB: on 64-bit machines the struct as a size of 24 bytes. Which means - byte 31 can still be used for returning the status. */ - }; - char raw[NOTIFY_COOKIE_LEN]; -}; - - -/* Keep track of the initialization. */ -static pthread_once_t once = PTHREAD_ONCE_INIT; - - -/* The netlink socket. */ -static int netlink_socket = -1; - - -/* Barrier used to make sure data passed to the new thread is not - resused by the parent. */ -static pthread_barrier_t notify_barrier; - - -/* Modify the signal mask. We move this into a separate function so - that the stack space needed for sigset_t is not deducted from what - the thread can use. */ -static int -__attribute__ ((noinline)) -change_sigmask (int how, sigset_t *oss) -{ - sigset_t ss; - sigfillset (&ss); - return pthread_sigmask (how, &ss, oss); -} - - -/* The function used for the notification. */ -static void * -notification_function (void *arg) -{ - /* Copy the function and parameter so that the parent thread can go - on with its life. */ - volatile union notify_data *data = (volatile union notify_data *) arg; - void (*fct) (union sigval) = data->fct; - union sigval param = data->param; - - /* Let the parent go. */ - (void) pthread_barrier_wait (¬ify_barrier); - - /* Make the thread detached. */ - (void) pthread_detach (pthread_self ()); - - /* The parent thread has all signals blocked. This is probably a - bit surprising for this thread. So we unblock all of them. */ - (void) change_sigmask (SIG_UNBLOCK, NULL); - - /* Now run the user code. */ - fct (param); - - /* And we are done. */ - return NULL; -} - - -/* Helper thread. */ -static void * -helper_thread (void *arg) -{ - while (1) - { - union notify_data data; - - ssize_t n = recv (netlink_socket, &data, sizeof (data), - MSG_NOSIGNAL | MSG_WAITALL); - if (n < NOTIFY_COOKIE_LEN) - continue; - - if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_WOKENUP) - { - /* Just create the thread as instructed. There is no way to - report a problem with creating a thread. */ - pthread_t th; - if (__builtin_expect (pthread_create (&th, data.attr, - notification_function, &data) - == 0, 0)) - /* Since we passed a pointer to DATA to the new thread we have - to wait until it is done with it. */ - (void) pthread_barrier_wait (¬ify_barrier); - } - else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED) - /* The only state we keep is the copy of the thread attributes. */ - free (data.attr); - } - return NULL; -} - - -static void -reset_once (void) -{ - once = PTHREAD_ONCE_INIT; -} - - -static void -init_mq_netlink (void) -{ - /* This code might be called a second time after fork(). The file - descriptor is inherited from the parent. */ - if (netlink_socket == -1) - { - /* Just a normal netlink socket, not bound. */ - netlink_socket = socket (AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, 0); - /* No need to do more if we have no socket. */ - if (netlink_socket == -1) - return; - } - - int err = 1; - - /* Initialize the barrier. */ - if (__builtin_expect (pthread_barrier_init (¬ify_barrier, NULL, 2) == 0, - 0)) - { - /* Create the helper thread. */ - pthread_attr_t attr; - (void) pthread_attr_init (&attr); - (void) pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - /* We do not need much stack space, the bare minimum will be enough. */ - (void) pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr)); - - /* Temporarily block all signals so that the newly created - thread inherits the mask. */ - sigset_t oss; - int have_no_oss = change_sigmask (SIG_BLOCK, &oss); - - pthread_t th; - err = pthread_create (&th, &attr, helper_thread, NULL); - - /* Reset the signal mask. */ - if (!have_no_oss) - pthread_sigmask (SIG_SETMASK, &oss, NULL); - - (void) pthread_attr_destroy (&attr); - - if (err == 0) - { - static int added_atfork; - - if (added_atfork == 0 - && pthread_atfork (NULL, NULL, reset_once) != 0) - { - /* The child thread will call recv() which is a - cancellation point. */ - (void) pthread_cancel (th); - err = 1; - } - else - added_atfork = 1; - } - } - - if (err != 0) - { - close_not_cancel_no_status (netlink_socket); - netlink_socket = -1; - } -} - - -/* Register notification upon message arrival to an empty message queue - MQDES. */ -int -mq_notify (mqd_t mqdes, const struct sigevent *notification) -{ - /* Make sure the type is correctly defined. */ - assert (sizeof (union notify_data) == NOTIFY_COOKIE_LEN); - - /* Special treatment needed for SIGEV_THREAD. */ - if (notification == NULL || notification->sigev_notify != SIGEV_THREAD) - return INLINE_SYSCALL (mq_notify, 2, mqdes, notification); - - /* The kernel cannot directly start threads. This will have to be - done at userlevel. Since we cannot start threads from signal - handlers we have to create a dedicated thread which waits for - notifications for arriving messages and creates threads in - response. */ - - /* Initialize only once. */ - pthread_once (&once, init_mq_netlink); - - /* If we cannot create the netlink socket we cannot provide - SIGEV_THREAD support. */ - if (__glibc_unlikely (netlink_socket == -1)) - { - __set_errno (ENOSYS); - return -1; - } - - /* Create the cookie. It will hold almost all the state. */ - union notify_data data; - memset (&data, '\0', sizeof (data)); - data.fct = notification->sigev_notify_function; - data.param = notification->sigev_value; - - if (notification->sigev_notify_attributes != NULL) - { - /* The thread attribute has to be allocated separately. */ - data.attr = (pthread_attr_t *) malloc (sizeof (pthread_attr_t)); - if (data.attr == NULL) - return -1; - - memcpy (data.attr, notification->sigev_notify_attributes, - sizeof (pthread_attr_t)); - } - - /* Construct the new request. */ - struct sigevent se; - se.sigev_notify = SIGEV_THREAD; - se.sigev_signo = netlink_socket; - se.sigev_value.sival_ptr = &data; - - /* Tell the kernel. */ - int retval = INLINE_SYSCALL (mq_notify, 2, mqdes, &se); - - /* If it failed, free the allocated memory. */ - if (__glibc_unlikely (retval != 0)) - free (data.attr); - - return retval; -} - -#else -# include -#endif diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/pthread_once.c deleted file mode 100644 index 10c01d6023..0000000000 --- a/nptl/sysdeps/unix/sysv/linux/pthread_once.c +++ /dev/null @@ -1,131 +0,0 @@ -/* Copyright (C) 2003-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek , 2003. - - 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 - . */ - -#include "pthreadP.h" -#include -#include - - -unsigned long int __fork_generation attribute_hidden; - - -static void -clear_once_control (void *arg) -{ - pthread_once_t *once_control = (pthread_once_t *) arg; - - /* Reset to the uninitialized state here. We don't need a stronger memory - order because we do not need to make any other of our writes visible to - other threads that see this value: This function will be called if we - get interrupted (see __pthread_once), so all we need to relay to other - threads is the state being reset again. */ - *once_control = 0; - lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); -} - - -/* This is similar to a lock implementation, but we distinguish between three - states: not yet initialized (0), initialization finished (2), and - initialization in progress (__fork_generation | 1). If in the first state, - threads will try to run the initialization by moving to the second state; - the first thread to do so via a CAS on once_control runs init_routine, - other threads block. - When forking the process, some threads can be interrupted during the second - state; they won't be present in the forked child, so we need to restart - initialization in the child. To distinguish an in-progress initialization - from an interrupted initialization (in which case we need to reclaim the - lock), we look at the fork generation that's part of the second state: We - can reclaim iff it differs from the current fork generation. - XXX: This algorithm has an ABA issue on the fork generation: If an - initialization is interrupted, we then fork 2^30 times (30 bits of - once_control are used for the fork generation), and try to initialize - again, we can deadlock because we can't distinguish the in-progress and - interrupted cases anymore. */ -int -__pthread_once (once_control, init_routine) - pthread_once_t *once_control; - void (*init_routine) (void); -{ - while (1) - { - int oldval, val, newval; - - /* We need acquire memory order for this load because if the value - signals that initialization has finished, we need to be see any - data modifications done during initialization. */ - val = *once_control; - atomic_read_barrier(); - do - { - /* Check if the initialization has already been done. */ - if (__glibc_likely ((val & 2) != 0)) - return 0; - - oldval = val; - /* We try to set the state to in-progress and having the current - fork generation. We don't need atomic accesses for the fork - generation because it's immutable in a particular process, and - forked child processes start with a single thread that modified - the generation. */ - newval = __fork_generation | 1; - /* We need acquire memory order here for the same reason as for the - load from once_control above. */ - val = atomic_compare_and_exchange_val_acq (once_control, newval, - oldval); - } - while (__glibc_unlikely (val != oldval)); - - /* Check if another thread already runs the initializer. */ - if ((oldval & 1) != 0) - { - /* Check whether the initializer execution was interrupted by a - fork. We know that for both values, bit 0 is set and bit 1 is - not. */ - if (oldval == newval) - { - /* Same generation, some other thread was faster. Wait. */ - lll_futex_wait (once_control, newval, LLL_PRIVATE); - continue; - } - } - - /* This thread is the first here. Do the initialization. - Register a cleanup handler so that in case the thread gets - interrupted the initialization can be restarted. */ - pthread_cleanup_push (clear_once_control, once_control); - - init_routine (); - - pthread_cleanup_pop (0); - - - /* Mark *once_control as having finished the initialization. We need - release memory order here because we need to synchronize with other - threads that want to use the initialized data. */ - atomic_write_barrier(); - *once_control = 2; - - /* Wake up all other threads. */ - lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); - break; - } - - return 0; -} -weak_alias (__pthread_once, pthread_once) -hidden_def (__pthread_once) diff --git a/nptl/sysdeps/unix/sysv/linux/sigtimedwait.c b/nptl/sysdeps/unix/sysv/linux/sigtimedwait.c deleted file mode 100644 index 8560e8b40a..0000000000 --- a/nptl/sysdeps/unix/sysv/linux/sigtimedwait.c +++ /dev/null @@ -1,2 +0,0 @@ -#include -#include "../../../../../sysdeps/unix/sysv/linux/sigtimedwait.c" diff --git a/nptl/sysdeps/unix/sysv/linux/sigwait.c b/nptl/sysdeps/unix/sysv/linux/sigwait.c deleted file mode 100644 index c358bfbeed..0000000000 --- a/nptl/sysdeps/unix/sysv/linux/sigwait.c +++ /dev/null @@ -1,2 +0,0 @@ -#include -#include "../../../../../sysdeps/unix/sysv/linux/sigwait.c" diff --git a/nptl/sysdeps/unix/sysv/linux/sigwaitinfo.c b/nptl/sysdeps/unix/sysv/linux/sigwaitinfo.c deleted file mode 100644 index a4f9fe8f5f..0000000000 --- a/nptl/sysdeps/unix/sysv/linux/sigwaitinfo.c +++ /dev/null @@ -1,2 +0,0 @@ -#include -#include "../../../../../sysdeps/unix/sysv/linux/sigwaitinfo.c" diff --git a/nptl/sysdeps/unix/sysv/linux/sleep.c b/nptl/sysdeps/unix/sysv/linux/sleep.c deleted file mode 100644 index 2dce3210ca..0000000000 --- a/nptl/sysdeps/unix/sysv/linux/sleep.c +++ /dev/null @@ -1,10 +0,0 @@ -/* We want an #include_next, but we are the main source file. - So, #include ourselves and in that incarnation we can use #include_next. */ -#ifndef INCLUDED_SELF -# define INCLUDED_SELF -# include -#else -/* This defines the CANCELLATION_P macro, which sleep.c checks for. */ -# include -# include_next -#endif diff --git a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c b/nptl/unregister-atfork.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/unregister-atfork.c rename to nptl/unregister-atfork.c diff --git a/nptl/sysdeps/unix/sysv/linux/unwindbuf.sym b/nptl/unwindbuf.sym similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/unwindbuf.sym rename to nptl/unwindbuf.sym diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/sysdeps/nptl/fork.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/fork.c rename to sysdeps/nptl/fork.c diff --git a/nptl/sysdeps/unix/sysv/linux/fork.h b/sysdeps/nptl/fork.h similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/fork.h rename to sysdeps/nptl/fork.h diff --git a/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c b/sysdeps/nptl/jmp-unwind.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/jmp-unwind.c rename to sysdeps/nptl/jmp-unwind.c diff --git a/nptl/lowlevellock.h b/sysdeps/nptl/lowlevellock.h similarity index 100% rename from nptl/lowlevellock.h rename to sysdeps/nptl/lowlevellock.h diff --git a/sysdeps/sparc/sparc32/sparcv9/sem_trywait.c b/sysdeps/sparc/sparc32/sparcv9/sem_trywait.c index 80157c5d2a..a8d4acc3f0 100644 --- a/sysdeps/sparc/sparc32/sparcv9/sem_trywait.c +++ b/sysdeps/sparc/sparc32/sparcv9/sem_trywait.c @@ -1 +1 @@ -#include +#include diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 02eda45067..9ad6d2252b 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -144,6 +144,10 @@ sysdep_headers += bits/initspin.h sysdep_routines += sched_getcpu tests += tst-getcpu + +CFLAGS-fork.c = $(libio-mtsafe) +CFLAGS-getpid.o = -fomit-frame-pointer +CFLAGS-getpid.os = -fomit-frame-pointer endif ifeq ($(subdir),inet) @@ -190,3 +194,7 @@ ifeq ($(subdir),nscd) sysdep-CFLAGS += -DHAVE_EPOLL -DHAVE_SENDFILE -DHAVE_INOTIFY -DHAVE_NETLINK CFLAGS-gai.c += -DNEED_NETLINK endif + +ifeq ($(subdir),nptl) +tests += tst-setgetname +endif diff --git a/sysdeps/unix/sysv/linux/aarch64/sigaction.c b/sysdeps/unix/sysv/linux/aarch64/sigaction.c index 7dabe4689b..ae6c3fde25 100644 --- a/sysdeps/unix/sysv/linux/aarch64/sigaction.c +++ b/sysdeps/unix/sysv/linux/aarch64/sigaction.c @@ -67,12 +67,4 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) } libc_hidden_def (__libc_sigaction) -#ifdef WRAPPER_INCLUDE -# include WRAPPER_INCLUDE -#endif - -#ifndef LIBC_SIGACTION -weak_alias (__libc_sigaction, __sigaction) -libc_hidden_weak (__sigaction) -weak_alias (__libc_sigaction, sigaction) -#endif +#include diff --git a/nptl/sysdeps/unix/sysv/linux/aio_misc.h b/sysdeps/unix/sysv/linux/aio_misc.h similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/aio_misc.h rename to sysdeps/unix/sysv/linux/aio_misc.h diff --git a/nptl/sysdeps/unix/sysv/linux/allocrtsig.c b/sysdeps/unix/sysv/linux/allocrtsig.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/allocrtsig.c rename to sysdeps/unix/sysv/linux/allocrtsig.c diff --git a/sysdeps/unix/sysv/linux/alpha/sem_post.c b/sysdeps/unix/sysv/linux/alpha/sem_post.c index befa49723b..9d4495312e 100644 --- a/sysdeps/unix/sysv/linux/alpha/sem_post.c +++ b/sysdeps/unix/sysv/linux/alpha/sem_post.c @@ -2,4 +2,4 @@ the acquire/release semantics of atomic_exchange_and_add. And even if we don't do this, we should be using atomic_full_barrier or otherwise. */ #define __lll_rel_instr "mb" -#include +#include diff --git a/sysdeps/unix/sysv/linux/arm/sigaction.c b/sysdeps/unix/sysv/linux/arm/sigaction.c index 24a2774f8b..8bd2adf7d5 100644 --- a/sysdeps/unix/sysv/linux/arm/sigaction.c +++ b/sysdeps/unix/sysv/linux/arm/sigaction.c @@ -84,12 +84,4 @@ __libc_sigaction (sig, act, oact) } libc_hidden_def (__libc_sigaction) -#ifdef WRAPPER_INCLUDE -# include WRAPPER_INCLUDE -#endif - -#ifndef LIBC_SIGACTION -weak_alias (__libc_sigaction, __sigaction) -libc_hidden_weak (__sigaction) -weak_alias (__libc_sigaction, sigaction) -#endif +#include diff --git a/nptl/sysdeps/unix/sysv/linux/getpid.c b/sysdeps/unix/sysv/linux/getpid.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/getpid.c rename to sysdeps/unix/sysv/linux/getpid.c diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c index 778037aee8..b0e71057ad 100644 --- a/sysdeps/unix/sysv/linux/i386/sigaction.c +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c @@ -84,15 +84,7 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) } libc_hidden_def (__libc_sigaction) -#ifdef WRAPPER_INCLUDE -# include WRAPPER_INCLUDE -#endif - -#ifndef LIBC_SIGACTION -weak_alias (__libc_sigaction, __sigaction) -libc_hidden_weak (__sigaction) -weak_alias (__libc_sigaction, sigaction) -#endif +#include /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to diff --git a/sysdeps/unix/sysv/linux/ia64/fork.S b/sysdeps/unix/sysv/linux/ia64/fork.S deleted file mode 100644 index 496d0b7eff..0000000000 --- a/sysdeps/unix/sysv/linux/ia64/fork.S +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2000-2014 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 - . */ - - -#include -#define _SIGNAL_H -#include - -/* pid_t fork(void); */ -/* Implemented as a clone system call with parameters SIGCHLD and 0 */ - -ENTRY(__libc_fork) - alloc r2=ar.pfs,0,0,2,0 - mov out0=SIGCHLD /* Return SIGCHLD when child finishes */ - /* no other clone flags; nothing shared */ - mov out1=0 /* Standard sp value. */ - ;; - DO_CALL (SYS_ify (clone)) - cmp.eq p6,p0=-1,r10 -(p6) br.cond.spnt.few __syscall_error - ret -PSEUDO_END(__libc_fork) - -weak_alias (__libc_fork, __fork) -libc_hidden_def (__fork) -weak_alias (__libc_fork, fork) diff --git a/sysdeps/unix/sysv/linux/ia64/sigaction.c b/sysdeps/unix/sysv/linux/ia64/sigaction.c index 97f7f499be..2033f11a45 100644 --- a/sysdeps/unix/sysv/linux/ia64/sigaction.c +++ b/sysdeps/unix/sysv/linux/ia64/sigaction.c @@ -45,12 +45,4 @@ __libc_sigaction (sig, act, oact) } libc_hidden_def (__libc_sigaction) -#ifdef WRAPPER_INCLUDE -# include WRAPPER_INCLUDE -#endif - -#ifndef LIBC_SIGACTION -weak_alias (__libc_sigaction, __sigaction) -libc_hidden_def (__sigaction) -weak_alias (__libc_sigaction, sigaction) -#endif +#include diff --git a/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h b/sysdeps/unix/sysv/linux/kernel-posix-timers.h similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h rename to sysdeps/unix/sysv/linux/kernel-posix-timers.h diff --git a/sysdeps/unix/sysv/linux/mips/sigaction.c b/sysdeps/unix/sysv/linux/mips/sigaction.c index 6b808a6cdf..90b1a3b13d 100644 --- a/sysdeps/unix/sysv/linux/mips/sigaction.c +++ b/sysdeps/unix/sysv/linux/mips/sigaction.c @@ -87,15 +87,8 @@ __libc_sigaction (sig, act, oact) } libc_hidden_def (__libc_sigaction) -#ifdef WRAPPER_INCLUDE -# include WRAPPER_INCLUDE -#endif +#include -#ifndef LIBC_SIGACTION -weak_alias (__libc_sigaction, __sigaction) -libc_hidden_weak (__sigaction) -weak_alias (__libc_sigaction, sigaction) -#endif /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to diff --git a/sysdeps/unix/sysv/linux/mq_notify.c b/sysdeps/unix/sysv/linux/mq_notify.c index a61839f507..d50a9f2d57 100644 --- a/sysdeps/unix/sysv/linux/mq_notify.c +++ b/sysdeps/unix/sysv/linux/mq_notify.c @@ -1,5 +1,6 @@ /* Copyright (C) 2004-2014 Free Software Foundation, Inc. This file is part of the GNU C Library. + Contribute by Ulrich Drepper , 2004. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -15,27 +16,265 @@ License along with the GNU C Library; if not, see . */ +#include #include +#include #include -#include +#include +#include +#include +#include #include +#include +#include +#include +#include + #ifdef __NR_mq_notify +/* Defined in the kernel headers: */ +#define NOTIFY_COOKIE_LEN 32 /* Length of the cookie used. */ +#define NOTIFY_WOKENUP 1 /* Code for notifcation. */ +#define NOTIFY_REMOVED 2 /* Code for closed message queue + of de-notifcation. */ + + +/* Data structure for the queued notification requests. */ +union notify_data +{ + struct + { + void (*fct) (union sigval); /* The function to run. */ + union sigval param; /* The parameter to pass. */ + pthread_attr_t *attr; /* Attributes to create the thread with. */ + /* NB: on 64-bit machines the struct as a size of 24 bytes. Which means + byte 31 can still be used for returning the status. */ + }; + char raw[NOTIFY_COOKIE_LEN]; +}; + + +/* Keep track of the initialization. */ +static pthread_once_t once = PTHREAD_ONCE_INIT; + + +/* The netlink socket. */ +static int netlink_socket = -1; + + +/* Barrier used to make sure data passed to the new thread is not + resused by the parent. */ +static pthread_barrier_t notify_barrier; + + +/* Modify the signal mask. We move this into a separate function so + that the stack space needed for sigset_t is not deducted from what + the thread can use. */ +static int +__attribute__ ((noinline)) +change_sigmask (int how, sigset_t *oss) +{ + sigset_t ss; + sigfillset (&ss); + return pthread_sigmask (how, &ss, oss); +} + + +/* The function used for the notification. */ +static void * +notification_function (void *arg) +{ + /* Copy the function and parameter so that the parent thread can go + on with its life. */ + volatile union notify_data *data = (volatile union notify_data *) arg; + void (*fct) (union sigval) = data->fct; + union sigval param = data->param; + + /* Let the parent go. */ + (void) pthread_barrier_wait (¬ify_barrier); + + /* Make the thread detached. */ + (void) pthread_detach (pthread_self ()); + + /* The parent thread has all signals blocked. This is probably a + bit surprising for this thread. So we unblock all of them. */ + (void) change_sigmask (SIG_UNBLOCK, NULL); + + /* Now run the user code. */ + fct (param); + + /* And we are done. */ + return NULL; +} + + +/* Helper thread. */ +static void * +helper_thread (void *arg) +{ + while (1) + { + union notify_data data; + + ssize_t n = recv (netlink_socket, &data, sizeof (data), + MSG_NOSIGNAL | MSG_WAITALL); + if (n < NOTIFY_COOKIE_LEN) + continue; + + if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_WOKENUP) + { + /* Just create the thread as instructed. There is no way to + report a problem with creating a thread. */ + pthread_t th; + if (__builtin_expect (pthread_create (&th, data.attr, + notification_function, &data) + == 0, 0)) + /* Since we passed a pointer to DATA to the new thread we have + to wait until it is done with it. */ + (void) pthread_barrier_wait (¬ify_barrier); + } + else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED) + /* The only state we keep is the copy of the thread attributes. */ + free (data.attr); + } + return NULL; +} + + +static void +reset_once (void) +{ + once = PTHREAD_ONCE_INIT; +} + + +static void +init_mq_netlink (void) +{ + /* This code might be called a second time after fork(). The file + descriptor is inherited from the parent. */ + if (netlink_socket == -1) + { + /* Just a normal netlink socket, not bound. */ + netlink_socket = socket (AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, 0); + /* No need to do more if we have no socket. */ + if (netlink_socket == -1) + return; + } + + int err = 1; + + /* Initialize the barrier. */ + if (__builtin_expect (pthread_barrier_init (¬ify_barrier, NULL, 2) == 0, + 0)) + { + /* Create the helper thread. */ + pthread_attr_t attr; + (void) pthread_attr_init (&attr); + (void) pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + /* We do not need much stack space, the bare minimum will be enough. */ + (void) pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr)); + + /* Temporarily block all signals so that the newly created + thread inherits the mask. */ + sigset_t oss; + int have_no_oss = change_sigmask (SIG_BLOCK, &oss); + + pthread_t th; + err = pthread_create (&th, &attr, helper_thread, NULL); + + /* Reset the signal mask. */ + if (!have_no_oss) + pthread_sigmask (SIG_SETMASK, &oss, NULL); + + (void) pthread_attr_destroy (&attr); + + if (err == 0) + { + static int added_atfork; + + if (added_atfork == 0 + && pthread_atfork (NULL, NULL, reset_once) != 0) + { + /* The child thread will call recv() which is a + cancellation point. */ + (void) pthread_cancel (th); + err = 1; + } + else + added_atfork = 1; + } + } + + if (err != 0) + { + close_not_cancel_no_status (netlink_socket); + netlink_socket = -1; + } +} + + /* Register notification upon message arrival to an empty message queue MQDES. */ int mq_notify (mqd_t mqdes, const struct sigevent *notification) { - /* mq_notify which handles SIGEV_THREAD is included in the thread - add-on. */ - if (notification != NULL - && notification->sigev_notify == SIGEV_THREAD) + /* Make sure the type is correctly defined. */ + assert (sizeof (union notify_data) == NOTIFY_COOKIE_LEN); + + /* Special treatment needed for SIGEV_THREAD. */ + if (notification == NULL || notification->sigev_notify != SIGEV_THREAD) + return INLINE_SYSCALL (mq_notify, 2, mqdes, notification); + + /* The kernel cannot directly start threads. This will have to be + done at userlevel. Since we cannot start threads from signal + handlers we have to create a dedicated thread which waits for + notifications for arriving messages and creates threads in + response. */ + + /* Initialize only once. */ + pthread_once (&once, init_mq_netlink); + + /* If we cannot create the netlink socket we cannot provide + SIGEV_THREAD support. */ + if (__glibc_unlikely (netlink_socket == -1)) { __set_errno (ENOSYS); return -1; } - return INLINE_SYSCALL (mq_notify, 2, mqdes, notification); + + /* Create the cookie. It will hold almost all the state. */ + union notify_data data; + memset (&data, '\0', sizeof (data)); + data.fct = notification->sigev_notify_function; + data.param = notification->sigev_value; + + if (notification->sigev_notify_attributes != NULL) + { + /* The thread attribute has to be allocated separately. */ + data.attr = (pthread_attr_t *) malloc (sizeof (pthread_attr_t)); + if (data.attr == NULL) + return -1; + + memcpy (data.attr, notification->sigev_notify_attributes, + sizeof (pthread_attr_t)); + } + + /* Construct the new request. */ + struct sigevent se; + se.sigev_notify = SIGEV_THREAD; + se.sigev_signo = netlink_socket; + se.sigev_value.sival_ptr = &data; + + /* Tell the kernel. */ + int retval = INLINE_SYSCALL (mq_notify, 2, mqdes, &se); + + /* If it failed, free the allocated memory. */ + if (__glibc_unlikely (retval != 0)) + free (data.attr); + + return retval; } #else diff --git a/nptl/sysdeps/unix/sysv/linux/pt-raise.c b/sysdeps/unix/sysv/linux/pt-raise.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pt-raise.c rename to sysdeps/unix/sysv/linux/pt-raise.c diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_getaffinity.c b/sysdeps/unix/sysv/linux/pthread_getaffinity.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_getaffinity.c rename to sysdeps/unix/sysv/linux/pthread_getaffinity.c diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c b/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c rename to sysdeps/unix/sysv/linux/pthread_getcpuclockid.c diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_getname.c b/sysdeps/unix/sysv/linux/pthread_getname.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_getname.c rename to sysdeps/unix/sysv/linux/pthread_getname.c diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c b/sysdeps/unix/sysv/linux/pthread_kill.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_kill.c rename to sysdeps/unix/sysv/linux/pthread_kill.c diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c b/sysdeps/unix/sysv/linux/pthread_setaffinity.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c rename to sysdeps/unix/sysv/linux/pthread_setaffinity.c diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_setname.c b/sysdeps/unix/sysv/linux/pthread_setname.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_setname.c rename to sysdeps/unix/sysv/linux/pthread_setname.c diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_sigqueue.c b/sysdeps/unix/sysv/linux/pthread_sigqueue.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/pthread_sigqueue.c rename to sysdeps/unix/sysv/linux/pthread_sigqueue.c diff --git a/nptl/sysdeps/unix/sysv/linux/raise.c b/sysdeps/unix/sysv/linux/raise.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/raise.c rename to sysdeps/unix/sysv/linux/raise.c diff --git a/sysdeps/unix/sysv/linux/s390/jmp-unwind.c b/sysdeps/unix/sysv/linux/s390/jmp-unwind.c index f35eab5ac1..32226bc593 100644 --- a/sysdeps/unix/sysv/linux/s390/jmp-unwind.c +++ b/sysdeps/unix/sysv/linux/s390/jmp-unwind.c @@ -18,7 +18,7 @@ #include #include -#include +#include extern void __pthread_cleanup_upto (__jmp_buf env, char *targetframe); #pragma weak __pthread_cleanup_upto diff --git a/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c b/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c index 6fc0f969ef..aa6cf9a79e 100644 --- a/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c +++ b/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c @@ -19,4 +19,4 @@ already elided locks. */ #include -#include +#include diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c b/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c index e9a984b5af..995afbc2fc 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c +++ b/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c @@ -43,12 +43,4 @@ __libc_sigaction (sig, act, oact) } libc_hidden_def (__libc_sigaction) -#ifdef WRAPPER_INCLUDE -# include WRAPPER_INCLUDE -#endif - -#ifndef LIBC_SIGACTION -weak_alias (__libc_sigaction, __sigaction) -libc_hidden_weak (__sigaction) -weak_alias (__libc_sigaction, sigaction) -#endif +#include diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c index eaa517577f..c8694c17e3 100644 --- a/sysdeps/unix/sysv/linux/sigaction.c +++ b/sysdeps/unix/sysv/linux/sigaction.c @@ -69,12 +69,4 @@ __libc_sigaction (sig, act, oact) } libc_hidden_def (__libc_sigaction) -#ifdef WRAPPER_INCLUDE -# include WRAPPER_INCLUDE -#endif - -#ifndef LIBC_SIGACTION -weak_alias (__libc_sigaction, __sigaction) -libc_hidden_weak (__sigaction) -weak_alias (__libc_sigaction, sigaction) -#endif +#include diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c index 5491b480ea..c7727cf4c6 100644 --- a/sysdeps/unix/sysv/linux/sigtimedwait.c +++ b/sysdeps/unix/sysv/linux/sigtimedwait.c @@ -19,6 +19,7 @@ #include #include +#include #include #include diff --git a/sysdeps/unix/sysv/linux/sigwait.c b/sysdeps/unix/sysv/linux/sigwait.c index 26528227e6..b7ac868bb5 100644 --- a/sysdeps/unix/sysv/linux/sigwait.c +++ b/sysdeps/unix/sysv/linux/sigwait.c @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/sysdeps/unix/sysv/linux/sigwaitinfo.c b/sysdeps/unix/sysv/linux/sigwaitinfo.c index 9218afc551..fa9b0b73db 100644 --- a/sysdeps/unix/sysv/linux/sigwaitinfo.c +++ b/sysdeps/unix/sysv/linux/sigwaitinfo.c @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/sysdeps/unix/sysv/linux/sleep.c b/sysdeps/unix/sysv/linux/sleep.c index 3b352c68bc..5411fd5e98 100644 --- a/sysdeps/unix/sysv/linux/sleep.c +++ b/sysdeps/unix/sysv/linux/sleep.c @@ -23,6 +23,7 @@ #include /* For the real memset prototype. */ #include #include +#include #if 0 diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c index 5e8cf69800..a54d532c85 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c @@ -62,15 +62,8 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) } libc_hidden_def (__libc_sigaction) -#ifdef WRAPPER_INCLUDE -# include WRAPPER_INCLUDE -#endif +#include -#ifndef LIBC_SIGACTION -weak_alias (__libc_sigaction, __sigaction); -libc_hidden_weak (__sigaction) -weak_alias (__libc_sigaction, sigaction); -#endif static void __rt_sigreturn_stub (void) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c index 665e658cf9..514dabfe50 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c @@ -63,15 +63,8 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) } libc_hidden_def (__libc_sigaction) -#ifdef WRAPPER_INCLUDE -# include WRAPPER_INCLUDE -#endif +#include -#ifndef LIBC_SIGACTION -weak_alias (__libc_sigaction, __sigaction); -libc_hidden_weak (__sigaction) -weak_alias (__libc_sigaction, sigaction); -#endif static void __rt_sigreturn_stub (void) diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 2e6cf9c60d..d639d63cf9 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -15,7 +15,6 @@ epoll_ctl EXTRA epoll_ctl i:iiip epoll_ctl epoll_wait EXTRA epoll_wait Ci:ipii epoll_wait fdatasync - fdatasync Ci:i fdatasync flock - flock i:ii __flock flock -fork - fork i: __libc_fork __fork fork get_kernel_syms EXTRA get_kernel_syms i:p get_kernel_syms getegid - getegid Ei: __getegid getegid geteuid - geteuid Ei: __geteuid geteuid diff --git a/nptl/sysdeps/unix/sysv/linux/timer_create.c b/sysdeps/unix/sysv/linux/timer_create.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/timer_create.c rename to sysdeps/unix/sysv/linux/timer_create.c diff --git a/nptl/sysdeps/unix/sysv/linux/timer_delete.c b/sysdeps/unix/sysv/linux/timer_delete.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/timer_delete.c rename to sysdeps/unix/sysv/linux/timer_delete.c diff --git a/nptl/sysdeps/unix/sysv/linux/timer_getoverr.c b/sysdeps/unix/sysv/linux/timer_getoverr.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/timer_getoverr.c rename to sysdeps/unix/sysv/linux/timer_getoverr.c diff --git a/nptl/sysdeps/unix/sysv/linux/timer_gettime.c b/sysdeps/unix/sysv/linux/timer_gettime.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/timer_gettime.c rename to sysdeps/unix/sysv/linux/timer_gettime.c diff --git a/nptl/sysdeps/unix/sysv/linux/timer_routines.c b/sysdeps/unix/sysv/linux/timer_routines.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/timer_routines.c rename to sysdeps/unix/sysv/linux/timer_routines.c diff --git a/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/sysdeps/unix/sysv/linux/timer_settime.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/timer_settime.c rename to sysdeps/unix/sysv/linux/timer_settime.c diff --git a/nptl/sysdeps/unix/sysv/linux/tst-setgetname.c b/sysdeps/unix/sysv/linux/tst-setgetname.c similarity index 100% rename from nptl/sysdeps/unix/sysv/linux/tst-setgetname.c rename to sysdeps/unix/sysv/linux/tst-setgetname.c diff --git a/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c b/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c index 34c705235a..8d215915df 100644 --- a/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c +++ b/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c @@ -19,4 +19,4 @@ already elided locks. */ #include -#include "sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c" +#include diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c index 6735b70c10..53a8134b6a 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c @@ -73,15 +73,8 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) } libc_hidden_def (__libc_sigaction) -#ifdef WRAPPER_INCLUDE -# include WRAPPER_INCLUDE -#endif +#include -#ifndef LIBC_SIGACTION -weak_alias (__libc_sigaction, __sigaction) -libc_hidden_weak (__sigaction) -weak_alias (__libc_sigaction, sigaction) -#endif /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to