From patchwork Mon Jun 23 23:06:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roland McGrath X-Patchwork-Id: 1679 Received: (qmail 26718 invoked by alias); 23 Jun 2014 23:06:38 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 26696 invoked by uid 89); 23 Jun 2014 23:06:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_50 autolearn=ham version=3.3.2 X-HELO: topped-with-meat.com MIME-Version: 1.0 From: Roland McGrath To: "GNU C. Library" Subject: [PATCH roland/nptl] Get rid of nptl/sysdeps/ entirely! Message-Id: <20140623230625.642742C39BA@topped-with-meat.com> Date: Mon, 23 Jun 2014 16:06:25 -0700 (PDT) X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=SvUDtp+0 c=1 sm=1 tr=0 a=WkljmVdYkabdwxfqvArNOQ==:117 a=14OXPxybAAAA:8 a=nuOWHFnv4cYA:10 a=Z6MIti7PxpgA:10 a=kj9zAlcOel0A:10 a=hOe2yjtxAAAA:8 a=20KFwNOVAAAA:8 a=mDV3o1hIAAAA:8 a=VnNF1IyMAAAA:8 a=oAgnniP7XOG4NGlj0R4A:9 a=UIQ_i4vN7P4ACtk8:21 a=_HShb1fh7EkjIuOS:21 a=CjuIK1q_8ugA:10 a=jEp0ucaQiEUA:10 Verified on x86_64-linux-gnu and i686-linux-gnu that there are no significant code changes (lots of offsets changed and some things got reordered in the .so's, but the individual ET_REL files had no changes except for assert line numbers and the like). Note that the changes that look nontrivial in the patch are mostly actually just an existing nptl/sysdeps/.../foo file replacing an existing sysdeps/.../foo file that was never used. It's reasonably likely that this requires the machine-specific changes I've previously posted. So if there is a roland/nptl-ARCH branch extant for your machine, then please catch up with reviewing and approving that stuff so I can merge it all in before you try to test this change. From this point, I'll start harrassing machine maintainers just about daily. If people have not responded by next week, then I'll be inclined to just go ahead with the generic changes like this and make those machine maintainers catch up later. Thanks, Roland * 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/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/x86/pthread_mutex_cond_lock.c: Update #include. * 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. * 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. * 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. diff --git a/nptl/Makefile b/nptl/Makefile index cd3be12..67f7d5b 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 17a68ed..b7d4a9b 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 664b048..10c01d6 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 +unsigned long int __fork_generation attribute_hidden; -static int once_lock = LLL_LOCK_INITIALIZER; +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; + + 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)); - *once_control = !PTHREAD_ONCE_INIT; + /* 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 1a5a29d..0000000 --- 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 d182555..0000000 --- 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 9a21f39..0000000 --- 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 d50a9f2..0000000 --- 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 10c01d6..0000000 --- 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 8560e8b..0000000 --- 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 c358bfb..0000000 --- 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 a4f9fe8..0000000 --- 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 2dce321..0000000 --- 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/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 02eda45..9ad6d22 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 418207f..92b0596 100644 --- a/sysdeps/unix/sysv/linux/aarch64/sigaction.c +++ b/sysdeps/unix/sysv/linux/aarch64/sigaction.c @@ -69,12 +69,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/arm/sigaction.c b/sysdeps/unix/sysv/linux/arm/sigaction.c index e1d87cb..d4fcd04 100644 --- a/sysdeps/unix/sysv/linux/arm/sigaction.c +++ b/sysdeps/unix/sysv/linux/arm/sigaction.c @@ -85,12 +85,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 a901bc6..4ad4e15 100644 --- a/sysdeps/unix/sysv/linux/i386/sigaction.c +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c @@ -86,15 +86,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 496d0b7..0000000 --- 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 97f7f49..2033f11 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 a8ba3fe..ce10250 100644 --- a/sysdeps/unix/sysv/linux/mips/sigaction.c +++ b/sysdeps/unix/sysv/linux/mips/sigaction.c @@ -89,15 +89,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 a61839f..d50a9f2 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/s390-64/sigaction.c b/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c index e9a984b..995afbc 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 043d164..14f7091 100644 --- a/sysdeps/unix/sysv/linux/sigaction.c +++ b/sysdeps/unix/sysv/linux/sigaction.c @@ -71,12 +71,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 5491b48..c7727cf 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 2652822..b7ac868 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 9218afc..fa9b0b7 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 3b352c6..5411fd5 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 5e8cf69..a54d532 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 665e658..514dabf 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 2e6cf9c..d639d63 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 34c7052..8d21591 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 ab23985..efeb7d9 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c @@ -75,15 +75,8 @@ __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