From a032a6587011cbdac8c2f7e11f15dc4e592bbb55 Mon Sep 17 00:00:00 2001 From: Austin Foxley Date: Tue, 16 Feb 2010 12:27:18 -0800 Subject: mass sync with glibc nptl Signed-off-by: Austin Foxley --- .../nptl/sysdeps/unix/sysv/linux/Makefile.in | 43 +- .../nptl/sysdeps/unix/sysv/linux/alpha/Versions | 13 - .../sysdeps/unix/sysv/linux/alpha/bits/local_lim.h | 13 +- .../unix/sysv/linux/alpha/bits/pthreadtypes.h | 8 +- .../sysdeps/unix/sysv/linux/alpha/bits/semaphore.h | 3 - .../sysdeps/unix/sysv/linux/alpha/lowlevellock.h | 255 ++++--- .../sysdeps/unix/sysv/linux/alpha/pthread_once.c | 8 +- .../sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h | 14 +- .../nptl/sysdeps/unix/sysv/linux/alpha/vfork.S | 2 +- .../nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h | 114 ++- .../unix/sysv/linux/arm/bits/pthreadtypes.h | 16 +- .../sysdeps/unix/sysv/linux/arm/bits/semaphore.h | 5 +- .../sysdeps/unix/sysv/linux/arm/lowlevellock.c | 55 +- .../sysdeps/unix/sysv/linux/arm/lowlevellock.h | 407 +++++----- .../sysdeps/unix/sysv/linux/arm/pthread_once.c | 6 +- .../sysdeps/unix/sysv/linux/arm/sysdep-cancel.h | 60 +- .../unix/sysv/linux/arm/unwind-forcedunwind.c | 133 ++-- .../sysdeps/unix/sysv/linux/arm/unwind-resume.c | 92 ++- .../nptl/sysdeps/unix/sysv/linux/arm/unwind.h | 7 +- .../nptl/sysdeps/unix/sysv/linux/bits/local_lim.h | 13 +- .../nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h | 94 ++- libpthread/nptl/sysdeps/unix/sysv/linux/fork.c | 23 +- libpthread/nptl/sysdeps/unix/sysv/linux/fork.h | 10 +- libpthread/nptl/sysdeps/unix/sysv/linux/getpid.c | 9 +- .../sysdeps/unix/sysv/linux/i386/Makefile.arch | 3 +- .../unix/sysv/linux/i386/bits/pthreadtypes.h | 9 +- .../sysdeps/unix/sysv/linux/i386/bits/semaphore.h | 3 - .../nptl/sysdeps/unix/sysv/linux/i386/fork.c | 2 +- .../unix/sysv/linux/i386/i486/libc-lowlevellock.S | 12 +- .../unix/sysv/linux/i386/i486/lowlevellock.S | 349 ++++++--- .../unix/sysv/linux/i386/i486/lowlevelrobustlock.S | 233 ++++++ .../sysv/linux/i386/i486/pthread_barrier_wait.S | 71 +- .../sysv/linux/i386/i486/pthread_cond_broadcast.S | 152 +++- .../sysv/linux/i386/i486/pthread_cond_signal.S | 155 +++- .../sysv/linux/i386/i486/pthread_cond_timedwait.S | 384 ++++++++-- .../unix/sysv/linux/i386/i486/pthread_cond_wait.S | 383 ++++++++-- .../sysv/linux/i386/i486/pthread_rwlock_rdlock.S | 74 +- .../linux/i386/i486/pthread_rwlock_timedrdlock.S | 96 ++- .../linux/i386/i486/pthread_rwlock_timedwrlock.S | 92 ++- .../sysv/linux/i386/i486/pthread_rwlock_unlock.S | 59 +- .../sysv/linux/i386/i486/pthread_rwlock_wrlock.S | 69 +- .../sysdeps/unix/sysv/linux/i386/i486/sem_post.S | 76 +- .../unix/sysv/linux/i386/i486/sem_timedwait.S | 266 +++++-- .../unix/sysv/linux/i386/i486/sem_trywait.S | 12 +- .../sysdeps/unix/sysv/linux/i386/i486/sem_wait.S | 243 ++++-- .../unix/sysv/linux/i386/i586/lowlevelrobustlock.S | 20 + .../unix/sysv/linux/i386/i686/lowlevelrobustlock.S | 20 + .../sysdeps/unix/sysv/linux/i386/lowlevellock.h | 703 ++++++++++++------ .../nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h | 51 +- .../nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S | 34 +- .../sysdeps/unix/sysv/linux/i386/pthread_once.S | 32 +- libpthread/nptl/sysdeps/unix/sysv/linux/i386/smp.h | 38 +- .../sysdeps/unix/sysv/linux/i386/sysdep-cancel.h | 18 +- .../nptl/sysdeps/unix/sysv/linux/i386/vfork.S | 2 +- .../nptl/sysdeps/unix/sysv/linux/internaltypes.h | 23 +- .../nptl/sysdeps/unix/sysv/linux/jmp-unwind.c | 12 +- .../sysdeps/unix/sysv/linux/libc_pthread_init.c | 44 +- .../sysdeps/unix/sysv/linux/lowlevelbarrier.sym | 1 + .../nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym | 2 +- .../nptl/sysdeps/unix/sysv/linux/lowlevellock.c | 64 +- .../sysdeps/unix/sysv/linux/lowlevelrobustlock.sym | 6 + .../sysdeps/unix/sysv/linux/lowlevelrwlock.sym | 2 + .../unix/sysv/linux/mips/bits/pthreadtypes.h | 26 +- .../sysdeps/unix/sysv/linux/mips/bits/semaphore.h | 5 +- .../sysdeps/unix/sysv/linux/mips/lowlevellock.h | 269 ++++--- .../sysdeps/unix/sysv/linux/mips/pthread_once.c | 6 +- .../sysdeps/unix/sysv/linux/mips/sysdep-cancel.h | 59 +- .../nptl/sysdeps/unix/sysv/linux/mq_notify.c | 5 +- .../nptl/sysdeps/unix/sysv/linux/powerpc/Versions | 5 - .../unix/sysv/linux/powerpc/bits/pthreadtypes.h | 15 +- .../unix/sysv/linux/powerpc/bits/semaphore.h | 3 - .../sysdeps/unix/sysv/linux/powerpc/lowlevellock.h | 251 ++++--- .../unix/sysv/linux/powerpc/powerpc32/clone.S | 12 +- .../sysv/linux/powerpc/powerpc32/sysdep-cancel.h | 37 +- .../unix/sysv/linux/powerpc/powerpc32/vfork.S | 2 +- .../unix/sysv/linux/powerpc/powerpc64/Versions | 7 - .../unix/sysv/linux/powerpc/powerpc64/clone.S | 12 +- .../sysv/linux/powerpc/powerpc64/sysdep-cancel.h | 16 +- .../unix/sysv/linux/powerpc/powerpc64/vfork.S | 2 +- .../sysdeps/unix/sysv/linux/powerpc/pthread_once.c | 8 +- .../unix/sysv/linux/powerpc/pthread_spin_unlock.c | 29 + .../sysdeps/unix/sysv/linux/powerpc/sem_post.c | 19 +- libpthread/nptl/sysdeps/unix/sysv/linux/pt-fork.c | 1 - libpthread/nptl/sysdeps/unix/sysv/linux/pt-raise.c | 9 +- .../sysdeps/unix/sysv/linux/pthread-pi-defines.sym | 8 + .../unix/sysv/linux/pthread_attr_getaffinity.c | 3 +- .../unix/sysv/linux/pthread_attr_setaffinity.c | 7 +- .../sysdeps/unix/sysv/linux/pthread_getaffinity.c | 1 + .../unix/sysv/linux/pthread_getcpuclockid.c | 56 +- .../nptl/sysdeps/unix/sysv/linux/pthread_kill.c | 18 +- .../unix/sysv/linux/pthread_mutex_cond_lock.c | 10 +- .../sysdeps/unix/sysv/linux/pthread_setaffinity.c | 13 +- .../sysdeps/unix/sysv/linux/pthread_sigqueue.c | 83 +++ libpthread/nptl/sysdeps/unix/sysv/linux/raise.c | 9 +- .../nptl/sysdeps/unix/sysv/linux/register-atfork.c | 52 +- libpthread/nptl/sysdeps/unix/sysv/linux/sem_post.c | 30 +- .../nptl/sysdeps/unix/sysv/linux/sem_timedwait.c | 62 +- libpthread/nptl/sysdeps/unix/sysv/linux/sem_wait.c | 54 +- .../nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch | 5 +- .../sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h | 19 +- .../sysdeps/unix/sysv/linux/sh/bits/semaphore.h | 3 - libpthread/nptl/sysdeps/unix/sysv/linux/sh/fork.c | 1 - .../sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S | 2 +- .../sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h | 12 +- .../nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S | 421 ++++++++--- .../nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h | 311 +++++--- .../unix/sysv/linux/sh/lowlevelrobustlock.S | 264 +++++++ .../nptl/sysdeps/unix/sysv/linux/sh/not-cancel.h | 83 +-- .../nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c | 21 +- .../unix/sysv/linux/sh/pthread_barrier_wait.S | 49 +- .../unix/sysv/linux/sh/pthread_cond_broadcast.S | 99 ++- .../unix/sysv/linux/sh/pthread_cond_signal.S | 119 ++- .../unix/sysv/linux/sh/pthread_cond_timedwait.S | 184 +++-- .../sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S | 220 ++++-- .../nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S | 68 +- .../unix/sysv/linux/sh/pthread_rwlock_rdlock.S | 62 +- .../sysv/linux/sh/pthread_rwlock_timedrdlock.S | 70 +- .../sysv/linux/sh/pthread_rwlock_timedwrlock.S | 67 +- .../unix/sysv/linux/sh/pthread_rwlock_unlock.S | 48 +- .../unix/sysv/linux/sh/pthread_rwlock_wrlock.S | 58 +- .../nptl/sysdeps/unix/sysv/linux/sh/sem_post.S | 50 +- .../sysdeps/unix/sysv/linux/sh/sem_timedwait.S | 266 +++++-- .../nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S | 9 +- .../nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S | 265 +++++-- .../sysdeps/unix/sysv/linux/sh/sysdep-cancel.h | 128 +--- libpthread/nptl/sysdeps/unix/sysv/linux/sh/vfork.S | 2 +- libpthread/nptl/sysdeps/unix/sysv/linux/smp.h | 30 +- .../sysdeps/unix/sysv/linux/sparc/Makefile.arch | 3 +- .../nptl/sysdeps/unix/sysv/linux/sparc/Versions | 6 - .../sysdeps/unix/sysv/linux/sparc/bits/local_lim.h | 13 +- .../unix/sysv/linux/sparc/bits/pthreadtypes.h | 13 +- .../sysdeps/unix/sysv/linux/sparc/bits/semaphore.h | 3 - .../sysdeps/unix/sysv/linux/sparc/internaltypes.h | 34 + .../sysdeps/unix/sysv/linux/sparc/lowlevellock.c | 37 +- .../sysdeps/unix/sysv/linux/sparc/lowlevellock.h | 166 +++-- .../sysdeps/unix/sysv/linux/sparc/not-cancel.h | 1 + .../sysv/linux/sparc/pthread_barrier_destroy.c | 45 ++ .../unix/sysv/linux/sparc/pthread_barrier_init.c | 55 ++ .../sysdeps/unix/sysv/linux/sparc/pthread_once.c | 8 +- .../nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c | 57 ++ .../linux/sparc/sparc32/pthread_barrier_wait.c | 94 +++ .../unix/sysv/linux/sparc/sparc32/sem_post.c | 55 ++ .../unix/sysv/linux/sparc/sparc32/sem_timedwait.c | 148 ++++ .../unix/sysv/linux/sparc/sparc32/sem_trywait.c | 54 ++ .../unix/sysv/linux/sparc/sparc32/sem_wait.c | 127 ++++ .../unix/sysv/linux/sparc/sparc32/sysdep-cancel.h | 91 +-- .../sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S | 2 +- .../sysdeps/unix/sysv/linux/sparc/sparc64/Versions | 7 - .../nptl/sysdeps/unix/sysv/linux/structsem.sym | 12 + .../nptl/sysdeps/unix/sysv/linux/timer_create.c | 21 +- .../nptl/sysdeps/unix/sysv/linux/timer_delete.c | 26 +- .../nptl/sysdeps/unix/sysv/linux/timer_getoverr.c | 3 +- .../nptl/sysdeps/unix/sysv/linux/timer_routines.c | 59 +- .../sysdeps/unix/sysv/linux/unregister-atfork.c | 26 +- .../nptl/sysdeps/unix/sysv/linux/x86_64/Versions | 7 - .../unix/sysv/linux/x86_64/bits/semaphore.h | 3 - .../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S | 334 +++++++-- .../sysdeps/unix/sysv/linux/x86_64/lowlevellock.h | 718 ++++++++++++------ .../nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S | 2 + .../unix/sysv/linux/x86_64/pthread_barrier_wait.S | 40 +- .../sysv/linux/x86_64/pthread_cond_broadcast.S | 81 +- .../unix/sysv/linux/x86_64/pthread_cond_signal.S | 93 ++- .../sysv/linux/x86_64/pthread_cond_timedwait.S | 819 +++++++++++++++------ .../unix/sysv/linux/x86_64/pthread_cond_wait.S | 470 +++++++----- .../sysdeps/unix/sysv/linux/x86_64/pthread_once.S | 152 ++-- .../unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S | 47 +- .../sysv/linux/x86_64/pthread_rwlock_timedrdlock.S | 121 ++- .../sysv/linux/x86_64/pthread_rwlock_timedwrlock.S | 120 ++- .../unix/sysv/linux/x86_64/pthread_rwlock_unlock.S | 43 +- .../unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S | 47 +- .../nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S | 57 +- .../sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S | 327 ++++++-- .../sysdeps/unix/sysv/linux/x86_64/sem_trywait.S | 11 +- .../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S | 187 +++-- 174 files changed, 9961 insertions(+), 4242 deletions(-) delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/alpha/Versions create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Versions delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/pthread_sigqueue.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Versions create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/not-cancel.h create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_destroy.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_init.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/Versions create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/structsem.sym delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Versions (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux') diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in index 6c491b6e5..fa73a8a78 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in @@ -10,6 +10,7 @@ libpthread_CSRC = pthread_attr_getaffinity.c \ pthread_getcpuclockid.c pthread_kill.c \ pthread_mutex_cond_lock.c pthread_setaffinity.c \ pthread_yield.c sem_post.c sem_timedwait.c \ + pthread_sigqueue.c \ sem_trywait.c sem_wait.c pt-fork.c \ sigtimedwait.c sigwaitinfo.c sigwait.c pt-sleep.c @@ -148,7 +149,10 @@ headers_clean-y += nptl_linux_headers_clean CFLAGS-lowlevelbarrier.c = -S CFLAGS-lowlevelcond.c = -S CFLAGS-lowlevelrwlock.c = -S +CFLAGS-lowlevelrobustlock.c = -S CFLAGS-unwindbuf.c = -S +CFLAGS-structsem.c = -S +CFLAGS-pthread-pi-defines.c = -S $(PTHREAD_LINUX_OUT)/lowlevelbarrier.c: $(PTHREAD_LINUX_DIR)/lowlevelbarrier.sym $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@ @@ -159,9 +163,19 @@ $(PTHREAD_LINUX_OUT)/lowlevelcond.c: $(PTHREAD_LINUX_DIR)/lowlevelcond.sym $(PTHREAD_LINUX_OUT)/lowlevelrwlock.c: $(PTHREAD_LINUX_DIR)/lowlevelrwlock.sym $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@ +$(PTHREAD_LINUX_OUT)/lowlevelrobustlock.c: $(PTHREAD_LINUX_DIR)/lowlevelrobustlock.sym + $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@ + $(PTHREAD_LINUX_OUT)/unwindbuf.c: $(PTHREAD_LINUX_DIR)/unwindbuf.sym $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@ +$(PTHREAD_LINUX_OUT)/structsem.c: $(PTHREAD_LINUX_DIR)/structsem.sym + $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@ + +$(PTHREAD_LINUX_OUT)/pthread-pi-defines.c: $(PTHREAD_LINUX_DIR)/pthread-pi-defines.sym + $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@ + + $(PTHREAD_LINUX_OUT)/lowlevelbarrier.s: $(PTHREAD_LINUX_OUT)/lowlevelbarrier.c $(compile.c) @@ -171,9 +185,19 @@ $(PTHREAD_LINUX_OUT)/lowlevelcond.s: $(PTHREAD_LINUX_OUT)/lowlevelcond.c $(PTHREAD_LINUX_OUT)/lowlevelrwlock.s: $(PTHREAD_LINUX_OUT)/lowlevelrwlock.c $(compile.c) +$(PTHREAD_LINUX_OUT)/lowlevelrobustlock.s: $(PTHREAD_LINUX_OUT)/lowlevelrobustlock.c + $(compile.c) + $(PTHREAD_LINUX_OUT)/unwindbuf.s: $(PTHREAD_LINUX_OUT)/unwindbuf.c $(compile.c) +$(PTHREAD_LINUX_OUT)/structsem.s: $(PTHREAD_LINUX_OUT)/structsem.c + $(compile.c) + +$(PTHREAD_LINUX_OUT)/pthread-pi-defines.s: $(PTHREAD_LINUX_OUT)/pthread-pi-defines.c + $(compile.c) + + $(PTHREAD_LINUX_OUT)/lowlevelbarrier.h: $(PTHREAD_LINUX_OUT)/lowlevelbarrier.s $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@ @@ -183,13 +207,25 @@ $(PTHREAD_LINUX_OUT)/lowlevelcond.h: $(PTHREAD_LINUX_OUT)/lowlevelcond.s $(PTHREAD_LINUX_OUT)/lowlevelrwlock.h: $(PTHREAD_LINUX_OUT)/lowlevelrwlock.s $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@ +$(PTHREAD_LINUX_OUT)/lowlevelrobustlock.h: $(PTHREAD_LINUX_OUT)/lowlevelrobustlock.s + $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@ + $(PTHREAD_LINUX_OUT)/unwindbuf.h: $(PTHREAD_LINUX_OUT)/unwindbuf.s $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@ +$(PTHREAD_LINUX_OUT)/structsem.h: $(PTHREAD_LINUX_OUT)/structsem.s + $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@ + +$(PTHREAD_LINUX_OUT)/pthread-pi-defines.h: $(PTHREAD_LINUX_OUT)/pthread-pi-defines.s + $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@ + nptl_linux_headers: $(PTHREAD_LINUX_OUT)/lowlevelbarrier.h \ $(PTHREAD_LINUX_OUT)/lowlevelcond.h \ $(PTHREAD_LINUX_OUT)/lowlevelrwlock.h \ - $(PTHREAD_LINUX_OUT)/unwindbuf.h + $(PTHREAD_LINUX_OUT)/lowlevelrobustlock.h \ + $(PTHREAD_LINUX_OUT)/unwindbuf.h \ + $(PTHREAD_LINUX_OUT)/structsem.h \ + $(PTHREAD_LINUX_OUT)/pthread-pi-defines.h HEADERS_BITS_PTHREAD := $(notdir $(wildcard $(PTHREAD_LINUX_DIR)/bits/*.h)) ALL_HEADERS_BITS_PTHREAD := $(addprefix include/bits/,$(HEADERS_BITS_PTHREAD)) @@ -201,7 +237,10 @@ nptl_linux_headers_clean: $(do_rm) $(addprefix $(PTHREAD_LINUX_OUT)/lowlevelbarrier., c h s) \ $(addprefix $(PTHREAD_LINUX_OUT)/lowlevelcond., c h s) \ $(addprefix $(PTHREAD_LINUX_OUT)/lowlevelrwlock., c h s) \ - $(addprefix $(PTHREAD_LINUX_OUT)/unwindbuf., c h s) + $(addprefix $(PTHREAD_LINUX_OUT)/lowlevelrobustlock., c h s) \ + $(addprefix $(PTHREAD_LINUX_OUT)/unwindbuf., c h s) \ + $(addprefix $(PTHREAD_LINUX_OUT)/structsem., c h s) \ + $(addprefix $(PTHREAD_LINUX_OUT)/pthread-pi-defines., c h s) nptl_linux_clean: diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/Versions b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/Versions deleted file mode 100644 index 437c4da28..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/Versions +++ /dev/null @@ -1,13 +0,0 @@ -libpthread { - GLIBC_2.3.3 { - # Changed PTHREAD_STACK_MIN. - pthread_attr_setstack; pthread_attr_setstacksize; - } -} -librt { - GLIBC_2.3.3 { - # Changed timer_t. - timer_create; timer_delete; timer_getoverrun; timer_gettime; - timer_settime; - } -} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h index e0718780c..a7c9740a0 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h @@ -1,5 +1,5 @@ /* Minimum guaranteed maximum values for system limits. Linux/Alpha version. - Copyright (C) 1993-1998,2000,2002,2003,2004 Free Software Foundation, Inc. + Copyright (C) 1993-1998,2000,2002-2004,2008 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 @@ -31,6 +31,9 @@ #ifndef OPEN_MAX # define __undef_OPEN_MAX #endif +#ifndef ARG_MAX +# define __undef_ARG_MAX +#endif /* The kernel sources contain a file with all the needed information. */ #include @@ -50,6 +53,11 @@ # undef OPEN_MAX # undef __undef_OPEN_MAX #endif +/* Have to remove ARG_MAX? */ +#ifdef __undef_ARG_MAX +# undef ARG_MAX +# undef __undef_ARG_MAX +#endif /* The number of data keys per process. */ #define _POSIX_THREAD_KEYS_MAX 128 @@ -87,3 +95,6 @@ /* Maximum message queue priority level. */ #define MQ_PRIO_MAX 32768 + +/* Maximum value the semaphore can have. */ +#define SEM_VALUE_MAX (2147483647) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h index 0f3bf838e..41c0be197 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h @@ -1,5 +1,5 @@ /* Machine-specific pthread type layouts. Alpha version. - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, 2007 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 @@ -65,7 +65,7 @@ typedef union int __kind; int __spins; __pthread_list_t __list; -#define __PTHREAD_MUTEX_HAVE_PREV 1 +#define __PTHREAD_MUTEX_HAVE_PREV 1 } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align; @@ -126,9 +126,9 @@ typedef union unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; int __writer; - int __pad1; + int __shared; + unsigned long int __pad1; unsigned long int __pad2; - unsigned long int __pad3; /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ unsigned int __flags; diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h index 6dadfda20..be4469c69 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h @@ -26,9 +26,6 @@ /* Value returned if `sem_open' failed. */ #define SEM_FAILED ((sem_t *) 0) -/* Maximum value the semaphore can have. */ -#define SEM_VALUE_MAX (2147483647) - typedef union { diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h index fd4a7ca4b..b7f4de338 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006, 2007 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 @@ -24,161 +24,250 @@ #include #include #include +#include -#define __NR_futex 394 #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 #define FUTEX_REQUEUE 3 #define FUTEX_CMP_REQUEUE 4 - -/* Initializer for compatibility lock. */ -#define LLL_MUTEX_LOCK_INITIALIZER (0) - -#define lll_futex_wait(futexp, val) \ +#define FUTEX_WAKE_OP 5 +#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1) +#define FUTEX_LOCK_PI 6 +#define FUTEX_UNLOCK_PI 7 +#define FUTEX_TRYLOCK_PI 8 +#define FUTEX_WAIT_BITSET 9 +#define FUTEX_WAKE_BITSET 10 +#define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_CLOCK_REALTIME 256 + +#define FUTEX_BITSET_MATCH_ANY 0xffffffff + +/* Values for 'private' parameter of locking macros. Yes, the + definition seems to be backwards. But it is not. The bit will be + reversed before passing to the system call. */ +#define LLL_PRIVATE 0 +#define LLL_SHARED FUTEX_PRIVATE_FLAG + + +#if !defined NOT_IN_libc || defined IS_IN_rtld +/* In libc.so or ld.so all futexes are private. */ +# ifdef __ASSUME_PRIVATE_FUTEX +# define __lll_private_flag(fl, private) \ + ((fl) | FUTEX_PRIVATE_FLAG) +# else +# define __lll_private_flag(fl, private) \ + ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) +# endif +#else +# ifdef __ASSUME_PRIVATE_FUTEX +# define __lll_private_flag(fl, private) \ + (((fl) | FUTEX_PRIVATE_FLAG) ^ (private)) +# else +# define __lll_private_flag(fl, private) \ + (__builtin_constant_p (private) \ + ? ((private) == 0 \ + ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \ + : (fl)) \ + : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \ + & THREAD_GETMEM (THREAD_SELF, header.private_futex)))) +# endif +#endif + + +#define lll_futex_wait(futexp, val, private) \ + lll_futex_timed_wait (futexp, val, NULL, private) + +#define lll_futex_timed_wait(futexp, val, timespec, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAIT, (val), 0); \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), (timespec)); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret; \ }) -#define lll_futex_timed_wait(futexp, val, timespec) \ +#define lll_futex_wake(futexp, nr, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAIT, (val), (timespec)); \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAKE, private), \ + (nr), 0); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret; \ }) -#define lll_futex_wake(futexp, nr) \ +#define lll_robust_dead(futexv, private) \ + do \ + { \ + int *__futexp = &(futexv); \ + atomic_or (__futexp, FUTEX_OWNER_DIED); \ + lll_futex_wake (__futexp, 1, private); \ + } \ + while (0) + +/* Returns non-zero if error happened, zero if success. */ +#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAKE, (nr), 0); \ - INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE, private),\ + (nr_wake), (nr_move), (mutex), (val)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \ +#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, \ - (futexp), FUTEX_CMP_REQUEUE, (nr_wake), \ - (nr_move), (mutex), (val)); \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_WAKE_OP, private), \ + (nr_wake), (nr_wake2), (futexp2), \ + FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) + + static inline int __attribute__((always_inline)) -__lll_mutex_trylock(int *futex) +__lll_trylock(int *futex) { return atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0; } -#define lll_mutex_trylock(lock) __lll_mutex_trylock (&(lock)) +#define lll_trylock(lock) __lll_trylock (&(lock)) static inline int __attribute__((always_inline)) -__lll_mutex_cond_trylock(int *futex) +__lll_cond_trylock(int *futex) { return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0; } -#define lll_mutex_cond_trylock(lock) __lll_mutex_cond_trylock (&(lock)) +#define lll_cond_trylock(lock) __lll_cond_trylock (&(lock)) -extern void __lll_lock_wait (int *futex) attribute_hidden; +static inline int __attribute__((always_inline)) +__lll_robust_trylock(int *futex, int id) +{ + return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0; +} +#define lll_robust_trylock(lock, id) \ + __lll_robust_trylock (&(lock), id) + +extern void __lll_lock_wait_private (int *futex) attribute_hidden; +extern void __lll_lock_wait (int *futex, int private) attribute_hidden; +extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden; static inline void __attribute__((always_inline)) -__lll_mutex_lock(int *futex) +__lll_lock(int *futex, int private) { if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0) - __lll_lock_wait (futex); + { + if (__builtin_constant_p (private) && private == LLL_PRIVATE) + __lll_lock_wait_private (futex); + else + __lll_lock_wait (futex, private); + } +} +#define lll_lock(futex, private) __lll_lock (&(futex), private) + + +static inline int __attribute__ ((always_inline)) +__lll_robust_lock (int *futex, int id, int private) +{ + int result = 0; + if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) + result = __lll_robust_lock_wait (futex, private); + return result; } -#define lll_mutex_lock(futex) __lll_mutex_lock (&(futex)) +#define lll_robust_lock(futex, id, private) \ + __lll_robust_lock (&(futex), id, private) static inline void __attribute__ ((always_inline)) -__lll_mutex_cond_lock (int *futex) +__lll_cond_lock (int *futex, int private) { if (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0) - __lll_lock_wait (futex); + __lll_lock_wait (futex, private); } -#define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex)) +#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private) + + +#define lll_robust_cond_lock(futex, id, private) \ + __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private) -extern int __lll_timedlock_wait (int *futex, const struct timespec *) - attribute_hidden; +extern int __lll_timedlock_wait (int *futex, const struct timespec *, + int private) attribute_hidden; +extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *, + int private) attribute_hidden; static inline int __attribute__ ((always_inline)) -__lll_mutex_timedlock (int *futex, const struct timespec *abstime) +__lll_timedlock (int *futex, const struct timespec *abstime, int private) { int result = 0; if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0) - result = __lll_timedlock_wait (futex, abstime); + result = __lll_timedlock_wait (futex, abstime, private); return result; } -#define lll_mutex_timedlock(futex, abstime) \ - __lll_mutex_timedlock (&(futex), abstime) +#define lll_timedlock(futex, abstime, private) \ + __lll_timedlock (&(futex), abstime, private) -static inline void __attribute__ ((always_inline)) -__lll_mutex_unlock (int *futex) +static inline int __attribute__ ((always_inline)) +__lll_robust_timedlock (int *futex, const struct timespec *abstime, + int id, int private) { - int val = atomic_exchange_rel (futex, 0); - if (__builtin_expect (val > 1, 0)) - lll_futex_wake (futex, 1); + int result = 0; + if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) + result = __lll_robust_timedlock_wait (futex, abstime, private); + return result; } -#define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex)) - +#define lll_robust_timedlock(futex, abstime, id, private) \ + __lll_robust_timedlock (&(futex), abstime, id, private) -static inline void __attribute__ ((always_inline)) -__lll_mutex_unlock_force (int *futex) -{ - (void) atomic_exchange_rel (futex, 0); - lll_futex_wake (futex, 1); -} -#define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex)) +#define __lll_unlock(futex, private) \ + (void) \ + ({ int *__futex = (futex); \ + int __oldval = atomic_exchange_rel (__futex, 0); \ + if (__builtin_expect (__oldval > 1, 0)) \ + lll_futex_wake (__futex, 1, private); \ + }) +#define lll_unlock(futex, private) __lll_unlock(&(futex), private) -#define lll_mutex_islocked(futex) \ - (futex != 0) +#define __lll_robust_unlock(futex, private) \ + (void) \ + ({ int *__futex = (futex); \ + int __oldval = atomic_exchange_rel (__futex, 0); \ + if (__builtin_expect (__oldval & FUTEX_WAITERS, 0)) \ + lll_futex_wake (__futex, 1, private); \ + }) +#define lll_robust_unlock(futex, private) \ + __lll_robust_unlock(&(futex), private) -/* Our internal lock implementation is identical to the binary-compatible - mutex implementation. */ -/* Type for lock object. */ -typedef int lll_lock_t; +#define lll_islocked(futex) \ + (futex != 0) /* Initializers for lock. */ #define LLL_LOCK_INITIALIZER (0) #define LLL_LOCK_INITIALIZER_LOCKED (1) -extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; - -/* The states of a lock are: - 0 - untaken - 1 - taken by one user - >1 - taken by more users */ - -#define lll_trylock(lock) lll_mutex_trylock (lock) -#define lll_lock(lock) lll_mutex_lock (lock) -#define lll_unlock(lock) lll_mutex_unlock (lock) -#define lll_islocked(lock) lll_mutex_islocked (lock) /* The kernel notifies a process which uses CLONE_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ #define lll_wait_tid(tid) \ - do { \ - __typeof (tid) __tid; \ - while ((__tid = (tid)) != 0) \ - lll_futex_wait (&(tid), __tid); \ + do { \ + __typeof (tid) __tid; \ + while ((__tid = (tid)) != 0) \ + lll_futex_wait (&(tid), __tid, LLL_SHARED); \ } while (0) extern int __lll_timedwait_tid (int *, const struct timespec *) @@ -192,26 +281,4 @@ extern int __lll_timedwait_tid (int *, const struct timespec *) __res; \ }) - -/* Conditional variable handling. */ - -extern void __lll_cond_wait (pthread_cond_t *cond) - attribute_hidden; -extern int __lll_cond_timedwait (pthread_cond_t *cond, - const struct timespec *abstime) - attribute_hidden; -extern void __lll_cond_wake (pthread_cond_t *cond) - attribute_hidden; -extern void __lll_cond_broadcast (pthread_cond_t *cond) - attribute_hidden; - -#define lll_cond_wait(cond) \ - __lll_cond_wait (cond) -#define lll_cond_timedwait(cond, abstime) \ - __lll_cond_timedwait (cond, abstime) -#define lll_cond_wake(cond) \ - __lll_cond_wake (cond) -#define lll_cond_broadcast(cond) \ - __lll_cond_broadcast (cond) - #endif /* lowlevellock.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c index 79a3c47ae..0e7e9790d 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2007 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 @@ -28,7 +28,7 @@ clear_once_control (void *arg) pthread_once_t *once_control = (pthread_once_t *) arg; *once_control = 0; - lll_futex_wake (once_control, INT_MAX); + lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); } int @@ -72,7 +72,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) break; /* Same generation, some other thread was faster. Wait. */ - lll_futex_wait (once_control, oldval); + lll_futex_wait (once_control, oldval, LLL_PRIVATE); } /* This thread is the first here. Do the initialization. @@ -88,7 +88,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) atomic_increment (once_control); /* Wake up all other threads. */ - lll_futex_wake (once_control, INT_MAX); + lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); return 0; } diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h index 49224079e..7049b3607 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2006 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 @@ -55,6 +55,7 @@ __LABEL(name) \ bne a3, SYSCALL_ERROR_LABEL; \ __LABEL($pseudo_ret) \ .subsection 2; \ + cfi_startproc; \ __LABEL($pseudo_cancel) \ subq sp, 64, sp; \ cfi_def_cfa_offset(64); \ @@ -90,12 +91,13 @@ __LABEL($multi_error) \ cfi_def_cfa_offset(0); \ __LABEL($syscall_error) \ SYSCALL_ERROR_HANDLER; \ + cfi_endproc; \ .previous # undef PSEUDO_END # define PSEUDO_END(sym) \ - .subsection 2; \ cfi_endproc; \ + .subsection 2; \ .size sym, .-sym # define SAVE_ARGS_0 /* Nothing. */ @@ -142,7 +144,7 @@ __LABEL($syscall_error) \ extern int __local_multiple_threads attribute_hidden; # define SINGLE_THREAD_P \ __builtin_expect (__local_multiple_threads == 0, 1) -# elif defined(PIC) +# elif defined(__PIC__) # define SINGLE_THREAD_P(reg) ldl reg, __local_multiple_threads(gp) !gprel # else # define SINGLE_THREAD_P(reg) \ @@ -167,3 +169,9 @@ extern int __local_multiple_threads attribute_hidden; # define NO_CANCELLATION 1 #endif + +#ifndef __ASSEMBLER__ +# define RTLD_SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + header.multiple_threads) == 0, 1) +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/vfork.S index f0c39982c..f4ed9311b 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/vfork.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/vfork.S @@ -42,5 +42,5 @@ PSEUDO (__vfork, vfork, 0) 1: ret PSEUDO_END (__vfork) -hidden_def (__vfork) +libc_hidden_def (__vfork) weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h index 49a935a52..b0586ea1e 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h @@ -37,61 +37,21 @@ typedef uintmax_t uatomic_max_t; void __arm_link_error (void); -#ifdef __thumb__ - -/* Note that to allow efficient implementation the arguemtns are reversed - relative to atomic_exchange_acq. */ -int __thumb_swpb (int newvalue, void *mem) - attribute_hidden; -unsigned int __thumb_swp (unsigned int newvalue, void *mem) - attribute_hidden; -unsigned int __thumb_cmpxchg (unsigned int oldval, unsigned int newval, void *mem) - attribute_hidden; - -#define atomic_exchange_acq(mem, newvalue) \ - ({ __typeof (*mem) result; \ - if (sizeof (*mem) == 1) \ - result = __thumb_swpb (newvalue, mem); \ - else if (sizeof (*mem) == 4) \ - result = __thumb_swp (newvalue, mem); \ - else \ - { \ - result = 0; \ - abort (); \ - } \ - result; }) - -#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ - ({ __arm_link_error (); oldval; }) - -#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ - ({ __arm_link_error (); oldval; }) - -#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ - ((__typeof (oldval)) __thumb_cmpxchg (oldval, newval, mem)) - -#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ - ({ __arm_link_error (); oldval; }) - +#ifdef __thumb2__ +#define atomic_full_barrier() \ + __asm__ __volatile__ \ + ("movw\tip, #0x0fa0\n\t" \ + "movt\tip, #0xffff\n\t" \ + "blx\tip" \ + : : : "ip", "lr", "cc", "memory"); #else -/* ARM mode. */ - -#define atomic_exchange_acq(mem, newvalue) \ - ({ __typeof (*mem) _xchg_result; \ - if (sizeof (*mem) == 1) \ - __asm__ __volatile__ ("swpb %0, %1, [%2]" \ - : "=&r,&r" (_xchg_result) \ - : "r,0" (newvalue), "r,r" (mem) : "memory"); \ - else if (sizeof (*mem) == 4) \ - __asm__ __volatile__ ("swp %0, %1, [%2]" \ - : "=&r,&r" (_xchg_result) \ - : "r,0" (newvalue), "r,r" (mem) : "memory"); \ - else \ - { \ - _xchg_result = 0; \ - abort (); \ - } \ - _xchg_result; }) +#define atomic_full_barrier() \ + __asm__ __volatile__ \ + ("mov\tip, #0xffff0fff\n\t" \ + "mov\tlr, pc\n\t" \ + "add\tpc, ip, #(0xffff0fa0 - 0xffff0fff)" \ + : : : "ip", "lr", "cc", "memory"); +#endif /* Atomic compare and exchange. This sequence relies on the kernel to provide a compare and exchange operation which is atomic on the @@ -108,6 +68,9 @@ unsigned int __thumb_cmpxchg (unsigned int oldval, unsigned int newval, void *me specify one to work around GCC PR rtl-optimization/21223. Otherwise it may cause a_oldval or a_tmp to be moved to a different register. */ +#ifdef __thumb2__ +/* Thumb-2 has ldrex/strex. However it does not have barrier instructions, + so we still need to use the kernel helper. */ #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ ({ register __typeof (oldval) a_oldval asm ("r0"); \ register __typeof (oldval) a_newval asm ("r1") = (newval); \ @@ -115,22 +78,45 @@ unsigned int __thumb_cmpxchg (unsigned int oldval, unsigned int newval, void *me register __typeof (oldval) a_tmp asm ("r3"); \ register __typeof (oldval) a_oldval2 asm ("r4") = (oldval); \ __asm__ __volatile__ \ - ("0:\tldr\t%1,[%3]\n\t" \ - "cmp\t%1, %4\n\t" \ + ("0:\tldr\t%[tmp],[%[ptr]]\n\t" \ + "cmp\t%[tmp], %[old2]\n\t" \ "bne\t1f\n\t" \ - "mov\t%0, %4\n\t" \ - "mov\t%1, #0xffff0fff\n\t" \ + "mov\t%[old], %[old2]\n\t" \ + "movw\t%[tmp], #0x0fc0\n\t" \ + "movt\t%[tmp], #0xffff\n\t" \ + "blx\t%[tmp]\n\t" \ + "bcc\t0b\n\t" \ + "mov\t%[tmp], %[old2]\n\t" \ + "1:" \ + : [old] "=&r" (a_oldval), [tmp] "=&r" (a_tmp) \ + : [new] "r" (a_newval), [ptr] "r" (a_ptr), \ + [old2] "r" (a_oldval2) \ + : "ip", "lr", "cc", "memory"); \ + a_tmp; }) +#else +#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ + ({ register __typeof (oldval) a_oldval asm ("r0"); \ + register __typeof (oldval) a_newval asm ("r1") = (newval); \ + register __typeof (mem) a_ptr asm ("r2") = (mem); \ + register __typeof (oldval) a_tmp asm ("r3"); \ + register __typeof (oldval) a_oldval2 asm ("r4") = (oldval); \ + __asm__ __volatile__ \ + ("0:\tldr\t%[tmp],[%[ptr]]\n\t" \ + "cmp\t%[tmp], %[old2]\n\t" \ + "bne\t1f\n\t" \ + "mov\t%[old], %[old2]\n\t" \ + "mov\t%[tmp], #0xffff0fff\n\t" \ "mov\tlr, pc\n\t" \ - "add\tpc, %1, #(0xffff0fc0 - 0xffff0fff)\n\t" \ + "add\tpc, %[tmp], #(0xffff0fc0 - 0xffff0fff)\n\t" \ "bcc\t0b\n\t" \ - "mov\t%1, %4\n\t" \ + "mov\t%[tmp], %[old2]\n\t" \ "1:" \ - : "=&r" (a_oldval), "=&r" (a_tmp) \ - : "r" (a_newval), "r" (a_ptr), "r" (a_oldval2) \ + : [old] "=&r" (a_oldval), [tmp] "=&r" (a_tmp) \ + : [new] "r" (a_newval), [ptr] "r" (a_ptr), \ + [old2] "r" (a_oldval2) \ : "ip", "lr", "cc", "memory"); \ a_tmp; }) +#endif #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ ({ __arm_link_error (); oldval; }) - -#endif /* __thumb__ */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/pthreadtypes.h index ea8d6a2f0..e1b115c8c 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/pthreadtypes.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/pthreadtypes.h @@ -19,6 +19,8 @@ #ifndef _BITS_PTHREADTYPES_H #define _BITS_PTHREADTYPES_H 1 +#include + #define __SIZEOF_PTHREAD_ATTR_T 36 #define __SIZEOF_PTHREAD_MUTEX_T 24 #define __SIZEOF_PTHREAD_MUTEXATTR_T 4 @@ -126,9 +128,21 @@ typedef union unsigned int __writer_wakeup; unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned char __pad1; + unsigned char __pad2; + unsigned char __shared; + /* FLAGS must stay at this position in the structure to maintain + binary compatibility. */ + unsigned char __flags; +#else /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ - unsigned int __flags; + unsigned char __flags; + unsigned char __shared; + unsigned char __pad1; + unsigned char __pad2; +#endif int __writer; } __data; char __size[__SIZEOF_PTHREAD_RWLOCK_T]; diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h index 3fc647d31..dadfac2af 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2005, 2007 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 @@ -27,9 +27,6 @@ /* Value returned if `sem_open' failed. */ #define SEM_FAILED ((sem_t *) 0) -/* Maximum value the semaphore can have. */ -#define SEM_VALUE_MAX ((int) ((~0u) >> 1)) - typedef union { diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.c index 74be18855..60ccf7700 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.c @@ -1,5 +1,5 @@ /* low level locking for pthread library. Generic futex-using version. - Copyright (C) 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2005, 2007 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 @@ -22,8 +22,36 @@ #include #include +void +__lll_lock_wait_private (int *futex) +{ + do + { + int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1); + if (oldval != 0) + lll_futex_wait (futex, 2, LLL_PRIVATE); + } + while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0); +} + + +/* These functions don't get included in libc.so */ +#ifdef IS_IN_libpthread +void +__lll_lock_wait (int *futex, int private) +{ + do + { + int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1); + if (oldval != 0) + lll_futex_wait (futex, 2, private); + } + while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0); +} + + int -__lll_timedlock_wait (int *futex, const struct timespec *abstime) +__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private) { struct timespec rt; @@ -55,23 +83,10 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime) if (rt.tv_sec < 0) return ETIMEDOUT; - lll_futex_timed_wait (futex, 2, &rt); + // XYZ: Lost the lock to check whether it was private. + lll_futex_timed_wait (futex, 2, &rt, private); } - while (atomic_exchange_acq (futex, 2) != 0); - - return 0; -} - - -/* These don't get included in libc.so */ -#ifdef IS_IN_libpthread -int -lll_unlock_wake_cb (int *futex) -{ - int val = atomic_exchange_rel (futex, 0); - - if (__builtin_expect (val > 1, 0)) - lll_futex_wake (futex, 1); + while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0); return 0; } @@ -108,11 +123,11 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime) return ETIMEDOUT; /* Wait until thread terminates. */ - if (lll_futex_timed_wait (tidp, tid, &rt) == -ETIMEDOUT) + // XYZ: Lost the lock to check whether it was private. + if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT) return ETIMEDOUT; } return 0; } - #endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h index 79f3ddeca..4c7d08c92 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2006, 2007, 2008, 2009 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 @@ -12,7 +12,7 @@ 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 Libr \ary; if not, write to the Free + License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ @@ -24,6 +24,7 @@ #include #include #include +#include #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 @@ -31,267 +32,231 @@ #define FUTEX_CMP_REQUEUE 4 #define FUTEX_WAKE_OP 5 #define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1) +#define FUTEX_LOCK_PI 6 +#define FUTEX_UNLOCK_PI 7 +#define FUTEX_TRYLOCK_PI 8 +#define FUTEX_WAIT_BITSET 9 +#define FUTEX_WAKE_BITSET 10 +#define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_CLOCK_REALTIME 256 + +#define FUTEX_BITSET_MATCH_ANY 0xffffffff + +/* Values for 'private' parameter of locking macros. Yes, the + definition seems to be backwards. But it is not. The bit will be + reversed before passing to the system call. */ +#define LLL_PRIVATE 0 +#define LLL_SHARED FUTEX_PRIVATE_FLAG + + +#if !defined NOT_IN_libc || defined IS_IN_rtld +/* In libc.so or ld.so all futexes are private. */ +# ifdef __ASSUME_PRIVATE_FUTEX +# define __lll_private_flag(fl, private) \ + ((fl) | FUTEX_PRIVATE_FLAG) +# else +# define __lll_private_flag(fl, private) \ + ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) +# endif +#else +# ifdef __ASSUME_PRIVATE_FUTEX +# define __lll_private_flag(fl, private) \ + (((fl) | FUTEX_PRIVATE_FLAG) ^ (private)) +# else +# define __lll_private_flag(fl, private) \ + (__builtin_constant_p (private) \ + ? ((private) == 0 \ + ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \ + : (fl)) \ + : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \ + & THREAD_GETMEM (THREAD_SELF, header.private_futex)))) +# endif +#endif -/* Initializer for compatibility lock. */ -#define LLL_MUTEX_LOCK_INITIALIZER (0) -#define lll_futex_wait(futexp, val) \ - ({ \ - INTERNAL_SYSCALL_DECL (__err); \ - long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAIT, (val), 0); \ - __ret; \ - }) +#define lll_futex_wait(futexp, val, private) \ + lll_futex_timed_wait(futexp, val, NULL, private) -#define lll_futex_timed_wait(futexp, val, timespec) \ +#define lll_futex_timed_wait(futexp, val, timespec, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAIT, (val), (timespec)); \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), (timespec)); \ __ret; \ }) -#define lll_futex_wake(futexp, nr) \ +#define lll_futex_wake(futexp, nr, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAKE, (nr), 0); \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAKE, private), \ + (nr), 0); \ __ret; \ }) -#define lll_robust_mutex_dead(futexv) \ +#define lll_robust_dead(futexv, private) \ do \ { \ int *__futexp = &(futexv); \ atomic_or (__futexp, FUTEX_OWNER_DIED); \ - lll_futex_wake (__futexp, 1); \ + lll_futex_wake (__futexp, 1, private); \ } \ while (0) /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \ +#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, \ - (futexp), FUTEX_CMP_REQUEUE, (nr_wake), \ - (nr_move), (mutex), (val)); \ - __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE, private),\ + (nr_wake), (nr_move), (mutex), (val)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \ +#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, \ - (futexp), FUTEX_WAKE_OP, (nr_wake), \ - (nr_wake2), (futexp2), \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_WAKE_OP, private), \ + (nr_wake), (nr_wake2), (futexp2), \ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ - __ret; \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) -static inline int __attribute__((always_inline)) -__lll_mutex_trylock (int *futex) -{ - int flag = 1, old; -#ifdef __thumb__ - old = atomic_exchange_acq (futex, flag); - if (old < 1) - flag = 0; - else if (old > 1) - flag = atomic_exchange_acq (futex, old); -#else - __asm__ __volatile__ ( - "\tswp %[old], %[flag], [%[futex]] @ try to take the lock\n" - "\tcmp %[old], #1 @ check old lock value\n" - "\tmovlo %[flag], #0 @ if we got it, return 0\n" - "\tswphi %[flag], %[old], [%[futex]] @ if it was contested,\n" - " @ restore the contested flag,\n" - " @ and check whether that won." - : [futex] "+&r" (futex), [flag] "+&r" (flag), [old] "=&r" (old) - : : "memory" ); -#endif +#define lll_trylock(lock) \ + atomic_compare_and_exchange_val_acq(&(lock), 1, 0) + +#define lll_cond_trylock(lock) \ + atomic_compare_and_exchange_val_acq(&(lock), 2, 0) + +#define __lll_robust_trylock(futex, id) \ + (atomic_compare_and_exchange_val_acq (futex, id, 0) != 0) +#define lll_robust_trylock(lock, id) \ + __lll_robust_trylock (&(lock), id) + +extern void __lll_lock_wait_private (int *futex) attribute_hidden; +extern void __lll_lock_wait (int *futex, int private) attribute_hidden; +extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden; + +#define __lll_lock(futex, private) \ + ((void) ({ \ + int *__futex = (futex); \ + if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex, \ + 1, 0), 0)) \ + { \ + if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \ + __lll_lock_wait_private (__futex); \ + else \ + __lll_lock_wait (__futex, private); \ + } \ + })) +#define lll_lock(futex, private) __lll_lock (&(futex), private) + + +#define __lll_robust_lock(futex, id, private) \ + ({ \ + int *__futex = (futex); \ + int __val = 0; \ + \ + if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \ + 0), 0)) \ + __val = __lll_robust_lock_wait (__futex, private); \ + __val; \ + }) +#define lll_robust_lock(futex, id, private) \ + __lll_robust_lock (&(futex), id, private) + + +#define __lll_cond_lock(futex, private) \ + ((void) ({ \ + int *__futex = (futex); \ + if (__builtin_expect (atomic_exchange_acq (__futex, 2), 0)) \ + __lll_lock_wait (__futex, private); \ + })) +#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private) + + +#define lll_robust_cond_lock(futex, id, private) \ + __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private) - return flag; -} -#define lll_mutex_trylock(lock) __lll_mutex_trylock (&(lock)) - - -static inline int __attribute__((always_inline)) -__lll_mutex_cond_trylock (int *futex) -{ - int flag = 2, old; -#ifdef __thumb__ - old = atomic_exchange_acq (futex, flag); - if (old < 1) - flag = 0; - else if (old > 1) - flag = atomic_exchange_acq (futex, old); -#else - __asm__ __volatile__ ( - "\tswp %[old], %[flag], [%[futex]] @ try to take the lock\n" - "\tcmp %[old], #1 @ check old lock value\n" - "\tmovlo %[flag], #0 @ if we got it, return 0\n" - "\tswphi %[flag], %[old], [%[futex]] @ if it was contested,\n" - " @ restore the contested flag,\n" - " @ and check whether that won." - : [futex] "+&r" (futex), [flag] "+&r" (flag), [old] "=&r" (old) - : : "memory" ); -#endif - return flag; -} -#define lll_mutex_cond_trylock(lock) __lll_mutex_cond_trylock (&(lock)) - - -static inline int __attribute__((always_inline)) -__lll_robust_mutex_trylock(int *futex, int id) -{ - return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0; -} -#define lll_robust_mutex_trylock(lock, id) \ - __lll_robust_mutex_trylock (&(lock), id) - -extern int __lll_robust_lock_wait (int *futex) attribute_hidden; - -static inline void __attribute__((always_inline)) -__lll_mutex_lock (int *futex) -{ - int val = atomic_exchange_acq (futex, 1); - - if (__builtin_expect (val != 0, 0)) - { - while (atomic_exchange_acq (futex, 2) != 0) - lll_futex_wait (futex, 2); - } -} -#define lll_mutex_lock(futex) __lll_mutex_lock (&(futex)) - - -static inline int __attribute__ ((always_inline)) -__lll_robust_mutex_lock (int *futex, int id) -{ - int result = 0; - if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) - result = __lll_robust_lock_wait (futex); - return result; -} -#define lll_robust_mutex_lock(futex, id) \ - __lll_robust_mutex_lock (&(futex), id) - - -static inline void __attribute__ ((always_inline)) -__lll_mutex_cond_lock (int *futex) -{ - int val = atomic_exchange_acq (futex, 2); - - if (__builtin_expect (val != 0, 0)) - { - while (atomic_exchange_acq (futex, 2) != 0) - lll_futex_wait (futex, 2); - } -} -#define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex)) - - -#define lll_robust_mutex_cond_lock(futex, id) \ - __lll_robust_mutex_lock (&(futex), (id) | FUTEX_WAITERS) - - -extern int __lll_timedlock_wait (int *futex, const struct timespec *) - attribute_hidden; -extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *) - attribute_hidden; - -static inline int __attribute__ ((always_inline)) -__lll_mutex_timedlock (int *futex, const struct timespec *abstime) -{ - int result = 0; - int val = atomic_exchange_acq (futex, 1); - - if (__builtin_expect (val != 0, 0)) - result = __lll_timedlock_wait (futex, abstime); - return result; -} -#define lll_mutex_timedlock(futex, abstime) \ - __lll_mutex_timedlock (&(futex), abstime) - - -static inline int __attribute__ ((always_inline)) -__lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime, - int id) -{ - int result = 0; - if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) - result = __lll_robust_timedlock_wait (futex, abstime); - return result; -} -#define lll_robust_mutex_timedlock(futex, abstime, id) \ - __lll_robust_mutex_timedlock (&(futex), abstime, id) - - -static inline void __attribute__ ((always_inline)) -__lll_mutex_unlock (int *futex) -{ - int val = atomic_exchange_rel (futex, 0); - if (__builtin_expect (val > 1, 0)) - lll_futex_wake (futex, 1); -} -#define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex)) - - -static inline void __attribute__ ((always_inline)) -__lll_robust_mutex_unlock (int *futex, int mask) -{ - int val = atomic_exchange_rel (futex, 0); - if (__builtin_expect (val & mask, 0)) - lll_futex_wake (futex, 1); -} -#define lll_robust_mutex_unlock(futex) \ - __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS) - - -static inline void __attribute__ ((always_inline)) -__lll_mutex_unlock_force (int *futex) -{ - (void) atomic_exchange_rel (futex, 0); - lll_futex_wake (futex, 1); -} -#define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex)) - - -#define lll_mutex_islocked(futex) \ +extern int __lll_timedlock_wait (int *futex, const struct timespec *, + int private) attribute_hidden; +extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *, + int private) attribute_hidden; + +#define __lll_timedlock(futex, abstime, private) \ + ({ \ + int *__futex = (futex); \ + int __val = 0; \ + \ + if (__builtin_expect (atomic_exchange_acq (__futex, 1), 0)) \ + __val = __lll_timedlock_wait (__futex, abstime, private); \ + __val; \ + }) +#define lll_timedlock(futex, abstime, private) \ + __lll_timedlock (&(futex), abstime, private) + + +#define __lll_robust_timedlock(futex, abstime, id, private) \ + ({ \ + int *__futex = (futex); \ + int __val = 0; \ + \ + if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \ + 0), 0)) \ + __val = __lll_robust_timedlock_wait (__futex, abstime, private); \ + __val; \ + }) +#define lll_robust_timedlock(futex, abstime, id, private) \ + __lll_robust_timedlock (&(futex), abstime, id, private) + + +#define __lll_unlock(futex, private) \ + (void) \ + ({ int *__futex = (futex); \ + int __oldval = atomic_exchange_rel (__futex, 0); \ + if (__builtin_expect (__oldval > 1, 0)) \ + lll_futex_wake (__futex, 1, private); \ + }) +#define lll_unlock(futex, private) __lll_unlock(&(futex), private) + + +#define __lll_robust_unlock(futex, private) \ + (void) \ + ({ int *__futex = (futex); \ + int __oldval = atomic_exchange_rel (__futex, 0); \ + if (__builtin_expect (__oldval & FUTEX_WAITERS, 0)) \ + lll_futex_wake (__futex, 1, private); \ + }) +#define lll_robust_unlock(futex, private) \ + __lll_robust_unlock(&(futex), private) + + +#define lll_islocked(futex) \ (futex != 0) /* Our internal lock implementation is identical to the binary-compatible mutex implementation. */ -/* Type for lock object. */ -typedef int lll_lock_t; - /* Initializers for lock. */ #define LLL_LOCK_INITIALIZER (0) #define LLL_LOCK_INITIALIZER_LOCKED (1) -extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; - /* The states of a lock are: 0 - untaken 1 - taken by one user >1 - taken by more users */ -#define lll_trylock(lock) lll_mutex_trylock (lock) -#define lll_lock(lock) lll_mutex_lock (lock) -#define lll_unlock(lock) lll_mutex_unlock (lock) -#define lll_islocked(lock) lll_mutex_islocked (lock) - /* The kernel notifies a process which uses CLONE_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and