diff options
-rw-r--r-- | ChangeLog | 147 | ||||
-rw-r--r-- | nptl/Makefile | 13 | ||||
-rw-r--r-- | nptl/Versions | 5 | ||||
-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.c | 109 | ||||
-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/Makefile | 39 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/Versions | 15 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/createthread.c | 23 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/mq_notify.c | 282 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/pthread_once.c | 131 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sigtimedwait.c | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sigwait.c | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sigwaitinfo.c | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sleep.c | 10 | ||||
-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.c | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/Makefile | 8 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/aarch64/sigaction.c | 10 | ||||
-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.c | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/arm/sigaction.c | 10 | ||||
-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.c | 10 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/ia64/fork.S | 40 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/ia64/sigaction.c | 10 | ||||
-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.c | 9 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/mq_notify.c | 251 | ||||
-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.c | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c | 10 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sigaction.c | 10 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sigtimedwait.c | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sigwait.c | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sigwaitinfo.c | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sleep.c | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c | 9 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c | 9 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/syscalls.list | 1 | ||||
-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.c | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/sigaction.c | 11 |
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 (¬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 <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 (¬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 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 |