summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog147
-rw-r--r--nptl/Makefile13
-rw-r--r--nptl/Versions5
-rw-r--r--nptl/internaltypes.h (renamed from nptl/sysdeps/unix/sysv/linux/internaltypes.h)0
-rw-r--r--nptl/libc-lowlevellock.c (renamed from nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c)0
-rw-r--r--nptl/libc_multiple_threads.c (renamed from nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c)0
-rw-r--r--nptl/libc_pthread_init.c (renamed from nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c)0
-rw-r--r--nptl/lowlevelbarrier.sym (renamed from nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym)0
-rw-r--r--nptl/lowlevelcond.sym (renamed from nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym)0
-rw-r--r--nptl/lowlevellock.c (renamed from nptl/sysdeps/unix/sysv/linux/lowlevellock.c)0
-rw-r--r--nptl/lowlevelrobustlock.c (renamed from nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c)0
-rw-r--r--nptl/lowlevelrobustlock.sym (renamed from nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym)0
-rw-r--r--nptl/lowlevelrwlock.sym (renamed from nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym)0
-rw-r--r--nptl/pt-fork.c (renamed from nptl/sysdeps/unix/sysv/linux/pt-fork.c)0
-rw-r--r--nptl/pthread-pi-defines.sym (renamed from nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym)0
-rw-r--r--nptl/pthread_attr_getaffinity.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c)0
-rw-r--r--nptl/pthread_attr_setaffinity.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c)0
-rw-r--r--nptl/pthread_mutex_cond_lock.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c)0
-rw-r--r--nptl/pthread_once.c109
-rw-r--r--nptl/pthread_yield.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_yield.c)0
-rw-r--r--nptl/register-atfork.c (renamed from nptl/sysdeps/unix/sysv/linux/register-atfork.c)0
-rw-r--r--nptl/sem_post.c (renamed from nptl/sysdeps/unix/sysv/linux/sem_post.c)0
-rw-r--r--nptl/sem_timedwait.c (renamed from nptl/sysdeps/unix/sysv/linux/sem_timedwait.c)0
-rw-r--r--nptl/sem_trywait.c (renamed from nptl/sysdeps/unix/sysv/linux/sem_trywait.c)0
-rw-r--r--nptl/sem_wait.c (renamed from nptl/sysdeps/unix/sysv/linux/sem_wait.c)0
-rw-r--r--nptl/structsem.sym (renamed from nptl/sysdeps/unix/sysv/linux/structsem.sym)0
-rw-r--r--nptl/sysdeps/unix/sysv/linux/Makefile39
-rw-r--r--nptl/sysdeps/unix/sysv/linux/Versions15
-rw-r--r--nptl/sysdeps/unix/sysv/linux/createthread.c23
-rw-r--r--nptl/sysdeps/unix/sysv/linux/mq_notify.c282
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread_once.c131
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sigtimedwait.c2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sigwait.c2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sigwaitinfo.c2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sleep.c10
-rw-r--r--nptl/unregister-atfork.c (renamed from nptl/sysdeps/unix/sysv/linux/unregister-atfork.c)0
-rw-r--r--nptl/unwindbuf.sym (renamed from nptl/sysdeps/unix/sysv/linux/unwindbuf.sym)0
-rw-r--r--sysdeps/nptl/fork.c (renamed from nptl/sysdeps/unix/sysv/linux/fork.c)0
-rw-r--r--sysdeps/nptl/fork.h (renamed from nptl/sysdeps/unix/sysv/linux/fork.h)0
-rw-r--r--sysdeps/nptl/jmp-unwind.c (renamed from nptl/sysdeps/unix/sysv/linux/jmp-unwind.c)0
-rw-r--r--sysdeps/nptl/lowlevellock.h (renamed from nptl/lowlevellock.h)0
-rw-r--r--sysdeps/sparc/sparc32/sparcv9/sem_trywait.c2
-rw-r--r--sysdeps/unix/sysv/linux/Makefile8
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/sigaction.c10
-rw-r--r--sysdeps/unix/sysv/linux/aio_misc.h (renamed from nptl/sysdeps/unix/sysv/linux/aio_misc.h)0
-rw-r--r--sysdeps/unix/sysv/linux/allocrtsig.c (renamed from nptl/sysdeps/unix/sysv/linux/allocrtsig.c)0
-rw-r--r--sysdeps/unix/sysv/linux/alpha/sem_post.c2
-rw-r--r--sysdeps/unix/sysv/linux/arm/sigaction.c10
-rw-r--r--sysdeps/unix/sysv/linux/getpid.c (renamed from nptl/sysdeps/unix/sysv/linux/getpid.c)0
-rw-r--r--sysdeps/unix/sysv/linux/i386/sigaction.c10
-rw-r--r--sysdeps/unix/sysv/linux/ia64/fork.S40
-rw-r--r--sysdeps/unix/sysv/linux/ia64/sigaction.c10
-rw-r--r--sysdeps/unix/sysv/linux/kernel-posix-timers.h (renamed from nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h)0
-rw-r--r--sysdeps/unix/sysv/linux/mips/sigaction.c9
-rw-r--r--sysdeps/unix/sysv/linux/mq_notify.c251
-rw-r--r--sysdeps/unix/sysv/linux/pt-raise.c (renamed from nptl/sysdeps/unix/sysv/linux/pt-raise.c)0
-rw-r--r--sysdeps/unix/sysv/linux/pthread_getaffinity.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_getaffinity.c)0
-rw-r--r--sysdeps/unix/sysv/linux/pthread_getcpuclockid.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c)0
-rw-r--r--sysdeps/unix/sysv/linux/pthread_getname.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_getname.c)0
-rw-r--r--sysdeps/unix/sysv/linux/pthread_kill.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_kill.c)0
-rw-r--r--sysdeps/unix/sysv/linux/pthread_setaffinity.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c)0
-rw-r--r--sysdeps/unix/sysv/linux/pthread_setname.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_setname.c)0
-rw-r--r--sysdeps/unix/sysv/linux/pthread_sigqueue.c (renamed from nptl/sysdeps/unix/sysv/linux/pthread_sigqueue.c)0
-rw-r--r--sysdeps/unix/sysv/linux/raise.c (renamed from nptl/sysdeps/unix/sysv/linux/raise.c)0
-rw-r--r--sysdeps/unix/sysv/linux/s390/jmp-unwind.c2
-rw-r--r--sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c2
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c10
-rw-r--r--sysdeps/unix/sysv/linux/sigaction.c10
-rw-r--r--sysdeps/unix/sysv/linux/sigtimedwait.c1
-rw-r--r--sysdeps/unix/sysv/linux/sigwait.c1
-rw-r--r--sysdeps/unix/sysv/linux/sigwaitinfo.c1
-rw-r--r--sysdeps/unix/sysv/linux/sleep.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c9
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c9
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list1
-rw-r--r--sysdeps/unix/sysv/linux/timer_create.c (renamed from nptl/sysdeps/unix/sysv/linux/timer_create.c)0
-rw-r--r--sysdeps/unix/sysv/linux/timer_delete.c (renamed from nptl/sysdeps/unix/sysv/linux/timer_delete.c)0
-rw-r--r--sysdeps/unix/sysv/linux/timer_getoverr.c (renamed from nptl/sysdeps/unix/sysv/linux/timer_getoverr.c)0
-rw-r--r--sysdeps/unix/sysv/linux/timer_gettime.c (renamed from nptl/sysdeps/unix/sysv/linux/timer_gettime.c)0
-rw-r--r--sysdeps/unix/sysv/linux/timer_routines.c (renamed from nptl/sysdeps/unix/sysv/linux/timer_routines.c)0
-rw-r--r--sysdeps/unix/sysv/linux/timer_settime.c (renamed from nptl/sysdeps/unix/sysv/linux/timer_settime.c)0
-rw-r--r--sysdeps/unix/sysv/linux/tst-setgetname.c (renamed from nptl/sysdeps/unix/sysv/linux/tst-setgetname.c)0
-rw-r--r--sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sigaction.c11
84 files changed, 528 insertions, 664 deletions
diff --git a/ChangeLog b/ChangeLog
index d5458c7030..39f0e78837 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,150 @@
+2014-07-07 Roland McGrath <roland@hack.frob.com>
+
+ * 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
+ <nptl/sigaction.c> 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 <nptl/pthreadP.h>.
+ * 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 <siddhesh@redhat.com>
* 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
index d127f688cf..d127f688cf 100644
--- a/nptl/sysdeps/unix/sysv/linux/internaltypes.h
+++ b/nptl/internaltypes.h
diff --git a/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c b/nptl/libc-lowlevellock.c
index 080d4bdafb..080d4bdafb 100644
--- a/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c
+++ b/nptl/libc-lowlevellock.c
diff --git a/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c b/nptl/libc_multiple_threads.c
index acf3594d71..acf3594d71 100644
--- a/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c
+++ b/nptl/libc_multiple_threads.c
diff --git a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c b/nptl/libc_pthread_init.c
index 4d8d710cca..4d8d710cca 100644
--- a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
+++ b/nptl/libc_pthread_init.c
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym b/nptl/lowlevelbarrier.sym
index cfe22b0892..cfe22b0892 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym
+++ b/nptl/lowlevelbarrier.sym
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym b/nptl/lowlevelcond.sym
index 18e1adad43..18e1adad43 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym
+++ b/nptl/lowlevelcond.sym
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/nptl/lowlevellock.c
index e198af7e8d..e198af7e8d 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
+++ b/nptl/lowlevellock.c
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/nptl/lowlevelrobustlock.c
index 35258071cf..35258071cf 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+++ b/nptl/lowlevelrobustlock.c
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym b/nptl/lowlevelrobustlock.sym
index 2f1e9da52b..2f1e9da52b 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym
+++ b/nptl/lowlevelrobustlock.sym
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym b/nptl/lowlevelrwlock.sym
index f50b25bfb8..f50b25bfb8 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym
+++ b/nptl/lowlevelrwlock.sym
diff --git a/nptl/sysdeps/unix/sysv/linux/pt-fork.c b/nptl/pt-fork.c
index 582409486e..582409486e 100644
--- a/nptl/sysdeps/unix/sysv/linux/pt-fork.c
+++ b/nptl/pt-fork.c
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym b/nptl/pthread-pi-defines.sym
index 0ac51dba98..0ac51dba98 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
+++ b/nptl/pthread-pi-defines.sym
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c b/nptl/pthread_attr_getaffinity.c
index c80fef47c4..c80fef47c4 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c
+++ b/nptl/pthread_attr_getaffinity.c
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c b/nptl/pthread_attr_setaffinity.c
index 96c52ea531..96c52ea531 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c
+++ b/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
index 7b6fbc18aa..7b6fbc18aa 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
+++ b/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 <drepper@redhat.com>, 2002.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 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 <lowlevellock.h>
+#include <atomic.h>
+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
index 7f5f2065d3..7f5f2065d3 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_yield.c
+++ b/nptl/pthread_yield.c
diff --git a/nptl/sysdeps/unix/sysv/linux/register-atfork.c b/nptl/register-atfork.c
index 2cc49540b9..2cc49540b9 100644
--- a/nptl/sysdeps/unix/sysv/linux/register-atfork.c
+++ b/nptl/register-atfork.c
diff --git a/nptl/sysdeps/unix/sysv/linux/sem_post.c b/nptl/sem_post.c
index 4906adf332..4906adf332 100644
--- a/nptl/sysdeps/unix/sysv/linux/sem_post.c
+++ b/nptl/sem_post.c
diff --git a/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c b/nptl/sem_timedwait.c
index 7dfe51dd8b..7dfe51dd8b 100644
--- a/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
+++ b/nptl/sem_timedwait.c
diff --git a/nptl/sysdeps/unix/sysv/linux/sem_trywait.c b/nptl/sem_trywait.c
index 94c323c18e..94c323c18e 100644
--- a/nptl/sysdeps/unix/sysv/linux/sem_trywait.c
+++ b/nptl/sem_trywait.c
diff --git a/nptl/sysdeps/unix/sysv/linux/sem_wait.c b/nptl/sem_wait.c
index b12babb596..b12babb596 100644
--- a/nptl/sysdeps/unix/sysv/linux/sem_wait.c
+++ b/nptl/sem_wait.c
diff --git a/nptl/sysdeps/unix/sysv/linux/structsem.sym b/nptl/structsem.sym
index 0e2a15f2b5..0e2a15f2b5 100644
--- a/nptl/sysdeps/unix/sysv/linux/structsem.sym
+++ b/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 <drepper@redhat.com>, 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
-# <http://www.gnu.org/licenses/>.
-
-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='<nptl/sigaction.c>'
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 <schwidefsky@de.ibm.com>.
-
- 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
- <http://www.gnu.org/licenses/>. */
-
-/* Value passed to 'clone' for initialization of the thread register. */
-#define TLS_VALUE pd
-
-/* Get the real implementation. */
-#include <nptl/createthread.c>
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 <drepper@redhat.com>, 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
- <http://www.gnu.org/licenses/>. */
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <mqueue.h>
-#include <pthread.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysdep.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <not-cancel.h>
-#include <nptl/pthreadP.h>
-
-
-#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 (&notify_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 (&notify_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 (&notify_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 <rt/mq_notify.c>
-#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 <jakub@redhat.com>, 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
- <http://www.gnu.org/licenses/>. */
-
-#include "pthreadP.h"
-#include <lowlevellock.h>
-#include <atomic.h>
-
-
-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 <nptl/pthreadP.h>
-#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 <nptl/pthreadP.h>
-#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 <nptl/pthreadP.h>
-#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 <sleep.c>
-#else
-/* This defines the CANCELLATION_P macro, which sleep.c checks for. */
-# include <pthreadP.h>
-# include_next <sleep.c>
-#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c b/nptl/unregister-atfork.c
index 9005160f99..9005160f99 100644
--- a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
+++ b/nptl/unregister-atfork.c
diff --git a/nptl/sysdeps/unix/sysv/linux/unwindbuf.sym b/nptl/unwindbuf.sym
index 8044b4078c..8044b4078c 100644
--- a/nptl/sysdeps/unix/sysv/linux/unwindbuf.sym
+++ b/nptl/unwindbuf.sym
diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/sysdeps/nptl/fork.c
index 70201a294c..70201a294c 100644
--- a/nptl/sysdeps/unix/sysv/linux/fork.c
+++ b/sysdeps/nptl/fork.c
diff --git a/nptl/sysdeps/unix/sysv/linux/fork.h b/sysdeps/nptl/fork.h
index 8e28a76098..8e28a76098 100644
--- a/nptl/sysdeps/unix/sysv/linux/fork.h
+++ b/sysdeps/nptl/fork.h
diff --git a/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c b/sysdeps/nptl/jmp-unwind.c
index b3a960c980..b3a960c980 100644
--- a/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c
+++ b/sysdeps/nptl/jmp-unwind.c
diff --git a/nptl/lowlevellock.h b/sysdeps/nptl/lowlevellock.h
index 7d1913a58d..7d1913a58d 100644
--- a/nptl/lowlevellock.h
+++ b/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 <sysdeps/unix/sysv/linux/sem_trywait.c>
+#include <nptl/sem_trywait.c>
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 <nptl/sigaction.c>
diff --git a/nptl/sysdeps/unix/sysv/linux/aio_misc.h b/sysdeps/unix/sysv/linux/aio_misc.h
index 58ac45153f..58ac45153f 100644
--- a/nptl/sysdeps/unix/sysv/linux/aio_misc.h
+++ b/sysdeps/unix/sysv/linux/aio_misc.h
diff --git a/nptl/sysdeps/unix/sysv/linux/allocrtsig.c b/sysdeps/unix/sysv/linux/allocrtsig.c
index 0ed7d089c6..0ed7d089c6 100644
--- a/nptl/sysdeps/unix/sysv/linux/allocrtsig.c
+++ b/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 <nptl/sysdeps/unix/sysv/linux/sem_post.c>
+#include <nptl/sem_post.c>
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 <nptl/sigaction.c>
diff --git a/nptl/sysdeps/unix/sysv/linux/getpid.c b/sysdeps/unix/sysv/linux/getpid.c
index 937b1d4e11..937b1d4e11 100644
--- a/nptl/sysdeps/unix/sysv/linux/getpid.c
+++ b/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 <nptl/sigaction.c>
/* 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
- <http://www.gnu.org/licenses/>. */
-
-
-#include <sysdep.h>
-#define _SIGNAL_H
-#include <bits/signum.h>
-
-/* 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 <nptl/sigaction.c>
diff --git a/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h b/sysdeps/unix/sysv/linux/kernel-posix-timers.h
index 532da55e14..532da55e14 100644
--- a/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h
+++ b/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 <nptl/sigaction.c>
-#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 <drepper@redhat.com>, 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
<http://www.gnu.org/licenses/>. */
+#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
#include <mqueue.h>
-#include <stddef.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
#include <sysdep.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <not-cancel.h>
+#include <nptl/pthreadP.h>
+
#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 (&notify_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 (&notify_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 (&notify_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
index fc26e858b3..fc26e858b3 100644
--- a/nptl/sysdeps/unix/sysv/linux/pt-raise.c
+++ b/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
index f58e9cc3e9..f58e9cc3e9 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_getaffinity.c
+++ b/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
index 3e634a03c8..3e634a03c8 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
+++ b/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
index e5a319a3e1..e5a319a3e1 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_getname.c
+++ b/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
index 0a4d8627a9..0a4d8627a9 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c
+++ b/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
index 874cf4b578..874cf4b578 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c
+++ b/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
index 409560e586..409560e586 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_setname.c
+++ b/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
index 1e66815416..1e66815416 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_sigqueue.c
+++ b/sysdeps/unix/sysv/linux/pthread_sigqueue.c
diff --git a/nptl/sysdeps/unix/sysv/linux/raise.c b/sysdeps/unix/sysv/linux/raise.c
index 4106e8c458..4106e8c458 100644
--- a/nptl/sysdeps/unix/sysv/linux/raise.c
+++ b/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 <setjmp.h>
#include <stddef.h>
-#include <pthreadP.h>
+#include <nptl/pthreadP.h>
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 <elision-conf.h>
-#include <nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c>
+#include <nptl/pthread_mutex_cond_lock.c>
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 <nptl/sigaction.c>
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 <nptl/sigaction.c>
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 <signal.h>
#include <string.h>
+#include <nptl/pthreadP.h>
#include <sysdep-cancel.h>
#include <sys/syscall.h>
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 <stddef.h>
#include <string.h>
+#include <nptl/pthreadP.h>
#include <sysdep-cancel.h>
#include <sys/syscall.h>
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 <stddef.h>
#include <string.h>
+#include <nptl/pthreadP.h>
#include <sysdep-cancel.h>
#include <sys/syscall.h>
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 <string.h> /* For the real memset prototype. */
#include <unistd.h>
#include <sys/param.h>
+#include <nptl/pthreadP.h>
#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 <nptl/sigaction.c>
-#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 <nptl/sigaction.c>
-#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
index e5c056bf2c..e5c056bf2c 100644
--- a/nptl/sysdeps/unix/sysv/linux/timer_create.c
+++ b/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
index 1de81236e2..1de81236e2 100644
--- a/nptl/sysdeps/unix/sysv/linux/timer_delete.c
+++ b/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
index 0ac394114e..0ac394114e 100644
--- a/nptl/sysdeps/unix/sysv/linux/timer_getoverr.c
+++ b/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
index 7783034a76..7783034a76 100644
--- a/nptl/sysdeps/unix/sysv/linux/timer_gettime.c
+++ b/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
index 4ac9bbe896..4ac9bbe896 100644
--- a/nptl/sysdeps/unix/sysv/linux/timer_routines.c
+++ b/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
index f7f7c91c51..f7f7c91c51 100644
--- a/nptl/sysdeps/unix/sysv/linux/timer_settime.c
+++ b/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
index f5693e26c4..f5693e26c4 100644
--- a/nptl/sysdeps/unix/sysv/linux/tst-setgetname.c
+++ b/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 <elision-conf.h>
-#include "sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c"
+#include <nptl/pthread_mutex_cond_lock.c>
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
-
-#ifndef LIBC_SIGACTION
-weak_alias (__libc_sigaction, __sigaction)
-libc_hidden_weak (__sigaction)
-weak_alias (__libc_sigaction, sigaction)
-#endif
+#include <nptl/sigaction.c>
+
/* NOTE: Please think twice before making any changes to the bits of
code below. GDB needs some intimate knowledge about it to