summary refs log tree commit diff
path: root/nptl
diff options
context:
space:
mode:
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog498
-rw-r--r--nptl/Makefile2
-rw-r--r--nptl/allocatestack.c18
-rw-r--r--nptl/descr.h4
-rw-r--r--nptl/init.c43
-rw-r--r--nptl/lowlevellock.h20
-rw-r--r--nptl/pthreadP.h8
-rw-r--r--nptl/pthread_barrier_init.c36
-rw-r--r--nptl/pthread_barrier_wait.c10
-rw-r--r--nptl/pthread_cond_broadcast.c6
-rw-r--r--nptl/pthread_cond_destroy.c14
-rw-r--r--nptl/pthread_cond_init.c6
-rw-r--r--nptl/pthread_cond_signal.c10
-rw-r--r--nptl/pthread_cond_timedwait.c18
-rw-r--r--nptl/pthread_cond_wait.c28
-rw-r--r--nptl/pthread_condattr_getclock.c4
-rw-r--r--nptl/pthread_condattr_setclock.c7
-rw-r--r--nptl/pthread_create.c4
-rw-r--r--nptl/pthread_getattr_np.c6
-rw-r--r--nptl/pthread_getschedparam.c8
-rw-r--r--nptl/pthread_mutex_lock.c7
-rw-r--r--nptl/pthread_mutex_setprioceiling.c10
-rw-r--r--nptl/pthread_mutex_timedlock.c7
-rw-r--r--nptl/pthread_mutex_trylock.c3
-rw-r--r--nptl/pthread_mutex_unlock.c9
-rw-r--r--nptl/pthread_rwlock_init.c39
-rw-r--r--nptl/pthread_rwlock_rdlock.c8
-rw-r--r--nptl/pthread_rwlock_timedrdlock.c8
-rw-r--r--nptl/pthread_rwlock_timedwrlock.c6
-rw-r--r--nptl/pthread_rwlock_tryrdlock.c4
-rw-r--r--nptl/pthread_rwlock_unlock.c10
-rw-r--r--nptl/pthread_rwlock_wrlock.c6
-rw-r--r--nptl/pthread_setschedparam.c8
-rw-r--r--nptl/pthread_setschedprio.c8
-rw-r--r--nptl/sem_getvalue.c6
-rw-r--r--nptl/sem_init.c47
-rw-r--r--nptl/sem_open.c12
-rw-r--r--nptl/semaphoreP.h4
-rw-r--r--nptl/sysdeps/alpha/tls.h2
-rw-r--r--nptl/sysdeps/i386/tcb-offsets.sym3
-rw-r--r--nptl/sysdeps/i386/tls.h7
-rw-r--r--nptl/sysdeps/ia64/tls.h2
-rw-r--r--nptl/sysdeps/powerpc/tcb-offsets.sym1
-rw-r--r--nptl/sysdeps/powerpc/tls.h2
-rw-r--r--nptl/sysdeps/pthread/aio_misc.h7
-rw-r--r--nptl/sysdeps/pthread/bits/stdio-lock.h10
-rw-r--r--nptl/sysdeps/pthread/gai_misc.h7
-rw-r--r--nptl/sysdeps/pthread/pt-initfini.c4
-rw-r--r--nptl/sysdeps/pthread/pthread-functions.h1
-rw-r--r--nptl/sysdeps/pthread/pthread.h19
-rw-r--r--nptl/sysdeps/s390/tls.h6
-rw-r--r--nptl/sysdeps/sh/tcb-offsets.sym3
-rw-r--r--nptl/sysdeps/sh/tls.h6
-rw-r--r--nptl/sysdeps/sparc/tls.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/Makefile5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h77
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.c2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h7
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S23
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S57
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S14
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S14
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S21
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S241
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S291
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h82
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S31
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h71
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/internaltypes.h22
-rw-r--r--nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevellock.c30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h77
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h115
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h74
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sem_post.c33
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sem_timedwait.c60
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sem_wait.c69
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h19
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S61
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h72
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S14
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S72
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S33
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S32
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S29
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S27
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S29
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sem_post.S15
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S254
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S256
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h83
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c17
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/structsem.sym10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/unregister-atfork.c4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S23
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S55
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h63
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S15
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S15
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S228
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S227
-rw-r--r--nptl/sysdeps/x86_64/tcb-offsets.sym3
-rw-r--r--nptl/sysdeps/x86_64/tls.h7
-rw-r--r--nptl/tst-initializers1.c12
-rw-r--r--nptl/tst-locale2.c1
-rw-r--r--nptl/tst-sem11.c76
-rw-r--r--nptl/tst-sem12.c14
-rw-r--r--nptl/tst-typesizes.c5
141 files changed, 3416 insertions, 1183 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 2294c9567e..a4740c958d 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,10 +1,347 @@
+2007-07-26  Jakub Jelinek  <jakub@redhat.com>
+
+	* tst-locale2.c (useless): Add return statement.
+
+2007-07-24  Jakub Jelinek  <jakub@redhat.com>
+
+	* allocatestack.c (__nptl_setxid, __wait_lookup_done): Replace
+	lll_private_futex_* (*) with lll_futex_* (*, LLL_PRIVATE).
+	* pthread_create.c (start_thread): Likewise.
+	* init.c (sighandler_setxid): Likewise.
+	* sysdeps/alpha/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/ia64/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/i386/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/s390/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/powerpc/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/x86_64/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/sparc/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/sh/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/pthread/aio_misc.h (AIO_MISC_NOTIFY, AIO_MISC_WAIT):
+	Likewise.
+	* sysdeps/pthread/gai_misc.h (GAI_MISC_NOTIFY, GAI_MISC_WAIT):
+	Likewise.
+	* sysdeps/unix/sysv/linux/unregister-atfork.c (__unregister_atfork):
+	Likewise.
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h (__rtld_waitzero,
+	__rtld_notify): Likewise.
+	* sysdeps/unix/sysv/linux/fork.c (__libc_fork): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/pthread_once.c (clear_once_control,
+	__pthread_once): Likewise.
+	* sysdeps/unix/sysv/linux/alpha/pthread_once.c (clear_once_control,
+	__pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+	LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+	(lll_futex_wait): Add private argument, define as wrapper around
+	lll_futex_timed_wait.
+	(lll_futex_timed_wait, lll_futex_wake): Add private argument,
+	use __lll_private_flag macro.
+	(lll_robust_mutex_dead, __lll_mutex_unlock, __lll_robust_mutex_unlock,
+	__lll_mutex_unlock_force): Pass LLL_SHARED as last arg to lll_futex_*.
+	* sysdeps/unix/sysv/linux/ia64/pthread_once.c (clear_once_control,
+	__pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+	LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+	(lll_futex_wait): Add private argument, define as wrapper around
+	lll_futex_timed_wait.
+	(lll_futex_timed_wait, lll_futex_wake): Add private argument,
+	use __lll_private_flag macro.
+	(__lll_mutex_unlock, __lll_robust_mutex_unlock, lll_wait_tid,
+	__lll_mutex_unlock_force): Pass LLL_SHARED as last arg to lll_futex_*.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h (__lll_private_flag):
+	Define.
+	(lll_futex_timed_wait, lll_futex_wake): Use it.
+	(lll_private_futex_wait, lll_private_futex_timed_wait,
+	lll_private_futex_wake): Removed.
+	* sysdeps/unix/sysv/linux/s390/pthread_once.c (clear_once_control,
+	__pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+	LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+	(lll_futex_wait): Add private argument, define as wrapper around
+	lll_futex_timed_wait.
+	(lll_futex_timed_wait, lll_futex_wake): Add private argument,
+	use __lll_private_flag macro.
+	(lll_robust_mutex_dead, __lll_mutex_unlock, __lll_robust_mutex_unlock,
+	lll_wait_tid, __lll_mutex_unlock_force): Pass LLL_SHARED as last arg
+	to lll_futex_*.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+	(lll_private_futex_wait, lll_private_futex_timed_wait,
+	lll_private_futex_wake): Removed.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (__lll_private_flag):
+	Fix !__ASSUME_PRIVATE_FUTEX non-constant private case.
+	(lll_private_futex_wait, lll_private_futex_timed_wait,
+	lll_private_futex_wake): Removed.
+	* sysdeps/unix/sysv/linux/sparc/pthread_once.c (clear_once_control,
+	__pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+	LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+	(lll_futex_wait): Add private argument, define as wrapper around
+	lll_futex_timed_wait.
+	(lll_futex_timed_wait, lll_futex_wake): Add private argument,
+	use __lll_private_flag macro.
+	(lll_robust_mutex_dead, __lll_mutex_unlock, __lll_robust_mutex_unlock,
+	lll_wait_tid, __lll_mutex_unlock_force): Pass LLL_SHARED as last arg
+	to lll_futex_*.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h (__lll_private_flag):
+	Define.
+	(lll_futex_timed_wait, lll_futex_wake): Use it.
+	(lll_private_futex_wait, lll_private_futex_timed_wait,
+	lll_private_futex_wake): Removed.
+
+2007-07-27  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/sparc/tls.h (tcbhead_t): Move gscope_flag to the end
+	of the structure for sparc32.
+
+2007-07-26  Aurelien Jarno  <aurelien@aurel32.net>
+
+	* sysdeps/sparc/tls.h (tcbhead_t): Add gscope_flag.
+
+2007-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S: Fix
+	code used when private futexes are assumed.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+	Likewise.
+
+2007-07-23  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+	(__lll_private_flag): Define.
+	(lll_futex_wait): Define as a wrapper around lll_futex_timed_wait.
+	(lll_futex_timed_wait, lll_futex_wake, lll_futex_wake_unlock): Use
+	__lll_private_flag.
+	(lll_private_futex_wait, lll_private_futex_timedwait,
+	lll_private_futex_wake): Define as wrapper around non-_private
+	macros.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+	(__lll_private_flag): Define.
+	(lll_futex_timed_wait, lll_futex_wake): Use __lll_private_flag.
+	(lll_private_futex_wait, lll_private_futex_timedwait,
+	lll_private_futex_wake): Define as wrapper around non-_private
+	macros.
+
+2007-07-10  Steven Munroe  <sjmunroe@us.ibm.com>
+
+	* pthread_rwlock_rdlock.c (__pthread_rwlock_rdlock): Add LLL_SHARED
+	parameter to lll_futex_wait call.
+	* pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock): Likewise.
+
+	* sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once):
+	Replace lll_futex_wait with lll_private_futex_wait.
+	* sysdeps/unix/sysv/linux/powerpc/sem_post.c (__new_sem_post):
+	Add LLL_SHARED parameter to lll_futex_wake().
+
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Define LLL_PRIVATE
+	LLL_SHARED, lll_private_futex_wait, lll_private_futex_timed_wait and
+	lll_private_futex_wake.
+	(lll_futex_wait): Add private parameter. Adjust FUTEX_PRIVATE_FLAG
+	bit from private parm before syscall.
+	(lll_futex_timed_wait): Likewise.
+	(lll_futex_wake): Likewise.
+	(lll_futex_wake_unlock): Likewise.
+	(lll_mutex_unlock): Add LLL_SHARED parm to lll_futex_wake call.
+	(lll_robust_mutex_unlock): Likewise.
+	(lll_mutex_unlock_force): Likewise.
+	(lll_wait_tid): Add LLL_SHARED parm to lll_futex_wait call.
+
+2007-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S: Fix
+	compilation when unconditionally using private futexes.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+
+2007-07-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/pthread/bits/stdio-lock.h (_IO_acquire_lock_clear_flags2):
+	Define.
+
+2007-07-06  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/sh/tls.h: Include stdlib.h, list.h, sysdep.h and
+	kernel-features.h.
+
+2007-05-16  Roland McGrath  <roland@redhat.com>
+
+	* init.c (__nptl_initial_report_events): New variable.
+	(__pthread_initialize_minimal_internal): Initialize pd->report_events
+	to that.
+
 2007-06-22  Jakub Jelinek  <jakub@redhat.com>
 
 	* pthread_getattr_np.c (pthread_getattr_np): Clear cpuset and
 	cpusetsize if pthread_getaffinity_np failed with ENOSYS.
 
+2007-06-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h: Remove mrlock
+	implementation.
+
+2007-06-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthreadP.h: Define PTHREAD_MUTEX_TYPE.
+	* phtread_mutex_lock.c: Use PTHREAD_MUTEX_TYPE.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise.
+
+2007-06-17  Andreas Schwab  <schwab@suse.de>
+
+	* sysdeps/pthread/pt-initfini.c: Tell gcc about the nonstandard
+	sections.
+
+2007-06-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* allocatestack.c (allocate_stack): Make code compile if
+	__ASSUME_PRIVATE_FUTEX is set.
+
+2007-06-17  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S:
+	(__pthread_rwlock_rdlock): Don't use non SH-3/4 instruction.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S:
+	(__pthread_rwlock_wrlock): Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S:
+	(pthread_rwlock_timedrdlock): Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S:
+	(pthread_rwlock_timedwrlock): Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S:
+	(__pthread_rwlock_unlock): Likewise.
+
+2007-06-10  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/sh/tcb-offsets.sym: Add PRIVATE_FUTEX.
+	* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Include endian.h.
+	Split __flags into __flags, __shared, __pad1 and __pad2.
+	* sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: Use private
+        futexes if they are available.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S: Adjust so that change
+        in libc-lowlevellock.S allow using private futexes.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Define
+	FUTEX_PRIVATE_FLAG.  Add additional parameter to lll_futex_wait,
+	lll_futex_timed_wait and lll_futex_wake.  Change lll_futex_wait
+	to call lll_futex_timed_wait.  Add lll_private_futex_wait,
+	lll_private_futex_timed_wait and lll_private_futex_wake.
+	(lll_robust_mutex_unlock): Fix typo.
+	* sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: Use private
+        field in futex command setup.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Use
+	COND_NWAITERS_SHIFT instead of COND_CLOCK_BITS.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_once.S: Use private futexes
+        if they are available.  Remove clear_once_control.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Use private
+	futexes if they are available.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/sem_post.S: Add private futex support.
+	Wake only when there are waiters.
+	* sysdeps/unix/sysv/linux/sh/sem_wait.S: Add private futex
+	support.  Indicate that there are waiters.  Remove unnecessary
+        extra cancellation test.
+	* sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Likewise.  Removed
+	left-over duplication of __sem_wait_cleanup.
+
+2007-06-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Add additional
+	parameter to lll_futex_wait, lll_futex_timed_wait, and
+	lll_futex_wake.  Change lll_futex_wait to call lll_futex_timed_wait.
+	Add lll_private_futex_wait, lll_private_futex_timed_wait, and
+	lll_private_futex_wake.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise.
+	* allocatestack.c: Adjust use of lll_futex_* macros.
+	* init.c: Likewise.
+	* lowlevellock.h: Likewise.
+	* pthread_barrier_wait.c: Likewise.
+	* pthread_cond_broadcast.c: Likewise.
+	* pthread_cond_destroy.c: Likewise.
+	* pthread_cond_signal.c: Likewise.
+	* pthread_cond_timedwait.c: Likewise.
+	* pthread_cond_wait.c: Likewise.
+	* pthread_create.c: Likewise.
+	* pthread_mutex_lock.c: Likewise.
+	* pthread_mutex_setprioceiling.c: Likewise.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise.
+	* pthread_rwlock_timedrdlock.c: Likewise.
+	* pthread_rwlock_timedwrlock.c: Likewise.
+	* pthread_rwlock_unlock.c: Likewise.
+	* sysdeps/alpha/tls.h: Likewise.
+	* sysdeps/i386/tls.h: Likewise.
+	* sysdeps/ia64/tls.h: Likewise.
+	* sysdeps/powerpc/tls.h: Likewise.
+	* sysdeps/pthread/aio_misc.h: Likewise.
+	* sysdeps/pthread/gai_misc.h: Likewise.
+	* sysdeps/s390/tls.h: Likewise.
+	* sysdeps/sh/tls.h: Likewise.
+	* sysdeps/sparc/tls.h: Likewise.
+	* sysdeps/unix/sysv/linux/fork.c: Likewise.
+	* sysdeps/unix/sysv/linux/lowlevellock.c: Likewise.
+	* sysdeps/unix/sysv/linux/lowlevelrobustlock.c: Likewise.
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h: Likewise.
+	* sysdeps/unix/sysv/linux/sem_post.c: Likewise.
+	* sysdeps/unix/sysv/linux/sem_timedwait.c: Likewise.
+	* sysdeps/unix/sysv/linux/sem_wait.c: Likewise.
+	* sysdeps/unix/sysv/linux/unregister-atfork.c: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/pthread_once.c: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c:
+	Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c: Likewise.
+	* sysdeps/x86_64/tls.h: Likewise.
+
+2007-05-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_getattr_np.c: No need to install a cancellation handler,
+	this is no cancellation point.
+	* pthread_getschedparam.c: Likewise.
+	* pthread_setschedparam.c: Likewise.
+	* pthread_setschedprio.c: Likewise.
+	* sysdeps/unix/sysv/linux/lowlevellock.c: Remove all traces of
+	lll_unlock_wake_cb.
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+
+	* sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Checking
+	whether there are more than one thread makes no sense here since
+	we only call the slow path if the locks are taken.
+	* sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S: Likewise.
+
+	* sysdeps/unix/sysv/linux/internaltypes.h: Introduce
+	COND_NWAITERS_SHIFT.
+	* pthread_cond_destroy.c: Use COND_NWAITERS_SHIFT instead of
+	COND_CLOCK_BITS.
+	* pthread_cond_init.c: Likewise.
+	* pthread_cond_timedwait.c: Likewise.
+	* pthread_cond_wait.c: Likewise.
+	* pthread_condattr_getclock.c: Likewise.
+	* pthread_condattr_setclock.c: Likewise.
+	* sysdeps/unix/sysv/linux/lowlevelcond.sym: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+
 2007-05-28  Jakub Jelinek  <jakub@redhat.com>
 
+	* sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c: Include
+	unistd.h.
+
 	* sysdeps/i386/tls.h (THREAD_GSCOPE_RESET_FLAG): Use explicit
 	insn suffix.
 	(THREAD_GSCOPE_GET_FLAG): Remove.
@@ -42,15 +379,127 @@
 	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
 	THREAD_GSCOPE_WAIT): Define.
 
+2007-05-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* init.c: Make it compile with older kernel headers.
+
+	* tst-initializers1.c: Show through exit code which test failed.
+
+	* pthread_rwlock_init.c: Also initialize __shared field.
+	* sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Split __flags
+	element in rwlock structure into four byte elements.  One of them is
+	the new __shared element.
+	* sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h [__WORDSIZE=32]:
+	Likewise.
+	[__WORDSIZE=64]: Renamed __pad1 element int rwlock structure to
+	__shared, adjust names of other padding elements.
+	* sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+	* sysdeps/pthread/pthread.h: Adjust rwlock initializers.
+	* sysdeps/unix/sysv/linux/lowlevelrwlock.sym: Add PSHARED.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Define
+	FUTEX_PRIVATE_FLAG.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Change main
+	futex to use private operations if possible.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+
 2007-05-26  Ulrich Drepper  <drepper@redhat.com>
 
+	* pthreadP.h (PTHREAD_RWLOCK_PREFER_READER_P): Define.
+	* pthread_rwlock_rdlock.c: Use PTHREAD_RWLOCK_PREFER_READER_P.
+	* pthread_rwlock_timedrdlock.c: Likewise.
+	* pthread_rwlock_tryrdlock.c: Likewise.
+
+	* sysdeps/unix/sysv/linux/x86_64/sem_trywait.S (sem_trywait): Tiny
+	optimization.
+
+	* sysdeps/unix/sysv/linux/sem_wait.c: Add missing break.
+	* sysdeps/unix/sysv/linux/sem_timedwait.c: Removed left-over
+	duplication of __sem_wait_cleanup.
+
 	* allocatestack.c: Revert last change.
 	* init.c: Likewise.
 	* sysdeps/i386/tls.h: Likewise.
 	* sysdeps/x86_64/tls.h: Likewise.
+	* descr.h [TLS_DTV_AT_TP] (struct pthread): Add private_futex field to
+	header structure.
+	* sysdeps/powerpc/tcb-offsets.sym: Add PRIVATE_FUTEX_OFFSET.
+
+	* sysdeps/unix/sysv/linux/internaltypes.h (struct pthread_barrier):
+	Add private field.
+	* sysdeps/unix/sysv/linux/lowlevelbarrier.sym: Add PRIVATE definition.
+	* pthread_barrier_init.c: Set private flag if pshared and private
+	futexes are supported.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S: Use
+	private field in futex command setup.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S: Likewise.
+
+2007-05-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Add private futex
+	support.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+
+	* semaphoreP.h: Declare __old_sem_init and __old_sem_wait.
+	* sem_init.c (__new_sem_init): Rewrite to initialize all three
+	fields in the structure.
+	(__old_sem_init): New function.
+	* sem_open.c: Initialize all fields of the structure.
+	* sem_getvalue.c: Adjust for renamed element.
+	* sysdeps/unix/sysv/linux/Makefile [subdir=nptl]
+	(gen-as-const-headers): Add structsem.sym.
+	* sysdeps/unix/sysv/linux/structsem.sym: New file.
+	* sysdeps/unix/sysv/linux/internaltypes.h: Rename struct sem to
+	struct new_sem.  Add struct old_sem.
+	* sysdeps/unix/sysv/linux/sem_post.c: Wake only when there are waiters.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+	* sysdeps/unix/sysv/linux/sem_wait.c: Indicate that there are waiters.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/sem_timedwait.c: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+	* Makefile (tests): Add tst-sem10, tst-sem11, tst-sem12.
+	* tst-sem10.c: New file.
+	* tst-sem11.c: New file.
+	* tst-sem12.c: New file.
+	* tst-typesizes.c: Test struct new_sem and struct old_sem instead
+	of struct sem.
+
+2007-05-25  Ulrich Drepper  <drepper@redhat.com>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (sem_timedwait):
+	Move __pthread_enable_asynccancel right before futex syscall.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait):
+	Likewise.
 
 2007-05-24  Jakub Jelinek  <jakub@redhat.com>
 
+	* sysdeps/i386/tls.h (THREAD_SET_PRIVATE_FUTEX,
+	THREAD_COPY_PRIVATE_FUTEX): Define.
+	* sysdeps/x86_64/tls.h (THREAD_SET_PRIVATE_FUTEX,
+	THREAD_COPY_PRIVATE_FUTEX): Define.
+	* allocatestack.c (allocate_stack): Use THREAD_COPY_PRIVATE_FUTEX.
+	* init.c (__pthread_initialize_minimal_internal): Use
+	THREAD_SET_PRIVATE_FUTEX.
+
 	* sysdeps/powerpc/tls.h (tcbhead_t): Add gscope_flag.
 	(THREAD_GSCOPE_FLAG_UNUSED, THREAD_GSCOPE_FLAG_USED,
 	THREAD_GSCOPE_FLAG_WAIT): Define.
@@ -63,6 +512,29 @@
 	* allocatestack.c (__wait_lookup_done): Use THREAD_GSCOPE_GET_FLAG
 	instead of ->header.gscope_flag directly.
 
+2007-05-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* init.c (__pthread_initialize_minimal_internal): Check whether
+	private futexes are available.
+	* allocatestack.c (allocate_stack): Copy private_futex field from
+	current thread into the new stack.
+	* sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S: Use private
+	futexes if they are available.
+	* sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Likewise
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Adjust so that change
+	in libc-lowlevellock.S allow using private futexes.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Define
+	FUTEX_PRIVATE_FLAG.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Use private futexes
+	if they are available.
+	* sysdeps/unix/sysv/linux/i386/pthread_once.S: Likewise.
+	* sysdeps/x86_64/tcb-offsets.sym: Add PRIVATE_FUTEX.
+	* sysdeps/i386/tcb-offsets.sym: Likewise.
+	* sysdeps/x86_64/tls.h (tcbhead_t): Add private_futex field.
+	* sysdeps/i386/tls.h (tcbhead_t): Likewise.
+
 2007-05-21  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/pthread/pthread-functions.h (struct pthread_functions):
@@ -75,6 +547,11 @@
 	* sysdeps/x86_64/tls.h (THREAD_GSCOPE_WAIT): The pointer is not
 	encrypted for now.
 
+2007-05-21  Jakub Jelinek  <jakub@redhat.com>
+
+	* tst-robust9.c (do_test): Don't fail if ENABLE_PI and
+	pthread_mutex_init failed with ENOTSUP.
+
 2007-05-19  Ulrich Drepper  <drepper@redhat.com>
 
 	* allocatestack.c (__wait_lookup_done): New function.
@@ -88,24 +565,6 @@
 	* sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init):
 	Initialize GL(dl_wait_lookup_done).
 
-2007-05-25  Ulrich Drepper  <drepper@redhat.com>
-
-	* Makefile (tests): Add tst-sem10.
-	* tst-sem10.c: New file.
-
-2007-05-25  Ulrich Drepper  <drepper@redhat.com>
-	    Jakub Jelinek  <jakub@redhat.com>
-
-	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (sem_timedwait):
-	Move __pthread_enable_asynccancel right before futex syscall.
-	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait):
-	Likewise.
-
-2007-05-21  Jakub Jelinek  <jakub@redhat.com>
-
-	* tst-robust9.c (do_test): Don't fail if ENABLE_PI and
-	pthread_mutex_init failed with ENOTSUP.
-
 2007-05-17  Ulrich Drepper  <drepper@redhat.com>
 
 	[BZ #4512]
@@ -119,6 +578,9 @@
 	* tst-robust9.c: New file.
 	* tst-robustpi9.c: New file.
 
+	* sysdeps/unix/sysv/linux/sem_wait.c (__new_sem_wait): Remove
+	unnecessary extra cancellation test.
+
 2007-05-14  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Remove unnecessary
diff --git a/nptl/Makefile b/nptl/Makefile
index 95f72154e2..4d1a9bcfea 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -218,7 +218,7 @@ tests = tst-typesizes \
 	tst-once1 tst-once2 tst-once3 tst-once4 \
 	tst-key1 tst-key2 tst-key3 tst-key4 \
 	tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
-	tst-sem8 tst-sem9 tst-sem10 \
+	tst-sem8 tst-sem9 tst-sem10 tst-sem11 tst-sem12 \
 	tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
 	tst-align tst-align2 tst-align3 \
 	tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index e556dbac08..ddf91e5c10 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -376,6 +376,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
       __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
 #endif
 
+#ifndef __ASSUME_PRIVATE_FUTEX
+      /* The thread must know when private futexes are supported.  */
+      pd->header.private_futex = THREAD_GETMEM (THREAD_SELF,
+						header.private_futex);
+#endif
+
 #ifdef NEED_DL_SYSINFO
       /* Copy the sysinfo value from the parent.  */
       THREAD_SYSINFO(pd) = THREAD_SELF_SYSINFO;
@@ -510,6 +516,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	  __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
 #endif
 
+#ifndef __ASSUME_PRIVATE_FUTEX
+	  /* The thread must know when private futexes are supported.  */
+	  pd->header.private_futex = THREAD_GETMEM (THREAD_SELF,
+                                                    header.private_futex);
+#endif
+
 #ifdef NEED_DL_SYSINFO
 	  /* Copy the sysinfo value from the parent.  */
 	  THREAD_SYSINFO(pd) = THREAD_SELF_SYSINFO;
@@ -939,7 +951,7 @@ __nptl_setxid (struct xid_command *cmdp)
   int cur = cmdp->cntr;
   while (cur != 0)
     {
-      lll_futex_wait (&cmdp->cntr, cur);
+      lll_futex_wait (&cmdp->cntr, cur, LLL_PRIVATE);
       cur = cmdp->cntr;
     }
 
@@ -1025,7 +1037,7 @@ __wait_lookup_done (void)
 	continue;
 
       do
-	lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT);
+	lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT, LLL_PRIVATE);
       while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
     }
 
@@ -1047,7 +1059,7 @@ __wait_lookup_done (void)
 	continue;
 
       do
-	lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT);
+	lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT, LLL_PRIVATE);
       while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
     }
 
diff --git a/nptl/descr.h b/nptl/descr.h
index 74d8c44140..3a3361d9e3 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -37,6 +37,7 @@
 #endif
 #define __need_res_state
 #include <resolv.h>
+#include <kernel-features.h>
 
 #ifndef TCB_ALIGNMENT
 # define TCB_ALIGNMENT	sizeof (double)
@@ -132,6 +133,9 @@ struct pthread
     {
       int multiple_threads;
       int gscope_flag;
+# ifndef __ASSUME_PRIVATE_FUTEX
+      int private_futex;
+# endif
     } header;
 #endif
 
diff --git a/nptl/init.c b/nptl/init.c
index 4449a9dbc0..95b9c7be5d 100644
--- a/nptl/init.c
+++ b/nptl/init.c
@@ -35,27 +35,6 @@
 #include <lowlevellock.h>
 
 
-#ifndef __NR_set_tid_address
-/* XXX For the time being...  Once we can rely on the kernel headers
-   having the definition remove these lines.  */
-#if defined __s390__
-# define __NR_set_tid_address	252
-#elif defined __ia64__
-# define __NR_set_tid_address	1233
-#elif defined __i386__
-# define __NR_set_tid_address	258
-#elif defined __x86_64__
-# define __NR_set_tid_address	218
-#elif defined __powerpc__
-# define __NR_set_tid_address	232
-#elif defined __sparc__
-# define __NR_set_tid_address	166
-#else
-# error "define __NR_set_tid_address"
-#endif
-#endif
-
-
 /* Size and alignment of static TLS block.  */
 size_t __static_tls_size;
 size_t __static_tls_align_m1;
@@ -237,7 +216,7 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
 			__xidcmd->id[1], __xidcmd->id[2]);
 
   if (atomic_decrement_val (&__xidcmd->cntr) == 0)
-    lll_futex_wake (&__xidcmd->cntr, 1);
+    lll_futex_wake (&__xidcmd->cntr, 1, LLL_PRIVATE);
 
   /* Reset the SETXID flag.  */
   struct pthread *self = THREAD_SELF;
@@ -246,7 +225,7 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
 
   /* And release the futex.  */
   self->setxid_futex = 1;
-  lll_futex_wake (&self->setxid_futex, 1);
+  lll_futex_wake (&self->setxid_futex, 1, LLL_PRIVATE);
 }
 
 
@@ -255,6 +234,9 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
 extern void **__libc_dl_error_tsd (void) __attribute__ ((const));
 
 
+/* This can be set by the debugger before initialization is complete.  */
+static bool __nptl_initial_report_events;
+
 void
 __pthread_initialize_minimal_internal (void)
 {
@@ -297,6 +279,18 @@ __pthread_initialize_minimal_internal (void)
 #endif
     set_robust_list_not_avail ();
 
+#ifndef __ASSUME_PRIVATE_FUTEX
+  /* Private futexes are always used (at least internally) so that
+     doing the test once this early is beneficial.  */
+  {
+    int word;
+    word = INTERNAL_SYSCALL (futex, err, 3, &word,
+			    FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1);
+    if (!INTERNAL_SYSCALL_ERROR_P (word, err))
+      THREAD_SETMEM (pd, header.private_futex, FUTEX_PRIVATE_FLAG);
+  }
+#endif
+
   /* Set initial thread's stack block from 0 up to __libc_stack_end.
      It will be bigger than it actually is, but for unwind.c/pt-longjmp.c
      purposes this is good enough.  */
@@ -306,6 +300,9 @@ __pthread_initialize_minimal_internal (void)
   INIT_LIST_HEAD (&__stack_user);
   list_add (&pd->list, &__stack_user);
 
+  /* Before initializing __stack_user, the debugger could not find us and
+     had to set __nptl_initial_report_events.  Propagate its setting.  */
+  THREAD_SETMEM (pd, report_events, __nptl_initial_report_events);
 
   /* Install the cancellation signal handler.  If for some reason we
      cannot install the handler we do not abort.  Maybe we should, but
diff --git a/nptl/lowlevellock.h b/nptl/lowlevellock.h
index 338da39990..0600e1794d 100644
--- a/nptl/lowlevellock.h
+++ b/nptl/lowlevellock.h
@@ -1,5 +1,5 @@
 /* Low level locking macros used in NPTL implementation.  Stub version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -21,16 +21,6 @@
 #include <atomic.h>
 
 
-/* Implement generic mutex.  Basic futex syscall support is required:
-
-     lll_futex_wait(futex, value) - call sys_futex with FUTEX_WAIT
-				    and third parameter VALUE
-
-     lll_futex_wake(futex, value) - call sys_futex with FUTEX_WAKE
-				    and third parameter VALUE
-*/
-
-
 /* Mutex lock counter:
    bit 31 clear means unlocked;
    bit 31 set means locked.
@@ -66,7 +56,9 @@ __generic_mutex_lock (int *mutex)
       if (v >= 0)
 	continue;
 
-      lll_futex_wait (mutex, v);
+      lll_futex_wait (mutex, v,
+		      // XYZ check mutex flag
+		      LLL_SHARED);
     }
 }
 
@@ -82,7 +74,9 @@ __generic_mutex_unlock (int *mutex)
 
   /* There are other threads waiting for this mutex, wake one of them
      up.  */
-  lll_futex_wake (mutex, 1);
+  lll_futex_wake (mutex, 1,
+		  // XYZ check mutex flag
+		  LLL_SHARED);
 }
 
 
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 21ce6fe0b7..85fb9b8e48 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -97,6 +97,9 @@ enum
   = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ADAPTIVE_NP
 };
 
+#define PTHREAD_MUTEX_TYPE(m) \
+  ((m)->__data.__kind)
+
 /* Ceiling in __data.__lock.  __data.__lock is signed, so don't
    use the MSB bit in there, but in the mask also include that bit,
    so that the compiler can optimize & PTHREAD_MUTEX_PRIO_CEILING_MASK
@@ -118,6 +121,11 @@ enum
    | PTHREAD_MUTEXATTR_PROTOCOL_MASK | PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
 
 
+/* Check whether rwlock prefers readers.   */
+#define PTHREAD_RWLOCK_PREFER_READER_P(rwlock) \
+  ((rwlock)->__data.__flags == 0)
+
+
 /* Bits used in robust mutex implementation.  */
 #define FUTEX_WAITERS		0x80000000
 #define FUTEX_OWNER_DIED	0x40000000
diff --git a/nptl/pthread_barrier_init.c b/nptl/pthread_barrier_init.c
index 19e82fa38d..8dfc444965 100644
--- a/nptl/pthread_barrier_init.c
+++ b/nptl/pthread_barrier_init.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,6 +20,13 @@
 #include <errno.h>
 #include "pthreadP.h"
 #include <lowlevellock.h>
+#include <kernel-features.h>
+
+
+static const struct pthread_barrierattr default_attr =
+  {
+    .pshared = PTHREAD_PROCESS_PRIVATE
+  };
 
 
 int
@@ -33,17 +40,15 @@ pthread_barrier_init (barrier, attr, count)
   if (__builtin_expect (count == 0, 0))
     return EINVAL;
 
-  if (attr != NULL)
-    {
-      struct pthread_barrierattr *iattr;
-
-      iattr = (struct pthread_barrierattr *) attr;
+  struct pthread_barrierattr *iattr
+    = (attr != NULL
+       ? iattr = (struct pthread_barrierattr *) attr
+       : &default_attr);
 
-      if (iattr->pshared != PTHREAD_PROCESS_PRIVATE
-	  && __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0))
-	/* Invalid attribute.  */
-	return EINVAL;
-    }
+  if (iattr->pshared != PTHREAD_PROCESS_PRIVATE
+      && __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0))
+    /* Invalid attribute.  */
+    return EINVAL;
 
   ibarrier = (struct pthread_barrier *) barrier;
 
@@ -53,5 +58,14 @@ pthread_barrier_init (barrier, attr, count)
   ibarrier->init_count = count;
   ibarrier->curr_event = 0;
 
+#ifdef __ASSUME_PRIVATE_FUTEX
+  ibarrier->private = (iattr->pshared != PTHREAD_PROCESS_PRIVATE
+		       ? 0 : FUTEX_PRIVATE_FLAG);
+#else
+  ibarrier->private = (iattr->pshared != PTHREAD_PROCESS_PRIVATE
+		       ? 0 : THREAD_GETMEM (THREAD_SELF,
+					    header.private_futex));
+#endif
+
   return 0;
 }
diff --git a/nptl/pthread_barrier_wait.c b/nptl/pthread_barrier_wait.c
index c6b563f242..e96a3e5473 100644
--- a/nptl/pthread_barrier_wait.c
+++ b/nptl/pthread_barrier_wait.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.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -45,7 +45,9 @@ pthread_barrier_wait (barrier)
       ++ibarrier->curr_event;
 
       /* Wake up everybody.  */
-      lll_futex_wake (&ibarrier->curr_event, INT_MAX);
+      lll_futex_wake (&ibarrier->curr_event, INT_MAX,
+		      // XYZ check mutex flag
+		      LLL_SHARED);
 
       /* This is the thread which finished the serialization.  */
       result = PTHREAD_BARRIER_SERIAL_THREAD;
@@ -61,7 +63,9 @@ pthread_barrier_wait (barrier)
 
       /* Wait for the event counter of the barrier to change.  */
       do
-	lll_futex_wait (&ibarrier->curr_event, event);
+	lll_futex_wait (&ibarrier->curr_event, event,
+			// XYZ check mutex flag
+			LLL_SHARED);
       while (event == ibarrier->curr_event);
     }
 
diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
index 2b8b5460f4..aec33f3bd8 100644
--- a/nptl/pthread_cond_broadcast.c
+++ b/nptl/pthread_cond_broadcast.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -69,7 +69,9 @@ __pthread_cond_broadcast (cond)
 	{
 	  /* The requeue functionality is not available.  */
 	wake_all:
-	  lll_futex_wake (&cond->__data.__futex, INT_MAX);
+	  lll_futex_wake (&cond->__data.__futex, INT_MAX,
+			  // XYZ check mutex flag
+			  LLL_SHARED);
 	}
 
       /* That's all.  */
diff --git a/nptl/pthread_cond_destroy.c b/nptl/pthread_cond_destroy.c
index 3e4ec8d0e4..8574b6118f 100644
--- a/nptl/pthread_cond_destroy.c
+++ b/nptl/pthread_cond_destroy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -45,7 +45,7 @@ __pthread_cond_destroy (cond)
      pthread_cond_destroy needs to wait for them.  */
   unsigned int nwaiters = cond->__data.__nwaiters;
 
-  if (nwaiters >= (1 << COND_CLOCK_BITS))
+  if (nwaiters >= (1 << COND_NWAITERS_SHIFT))
     {
       /* Wake everybody on the associated mutex in case there are
          threads that have been requeued to it.
@@ -59,20 +59,24 @@ __pthread_cond_destroy (cond)
 	  && cond->__data.__mutex != (void *) ~0l)
 	{
 	  pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
-	  lll_futex_wake (&mut->__data.__lock, INT_MAX);
+	  lll_futex_wake (&mut->__data.__lock, INT_MAX,
+			  // XYZ check mutex flag
+			  LLL_SHARED);
 	}
 
       do
 	{
 	  lll_mutex_unlock (cond->__data.__lock);
 
-	  lll_futex_wait (&cond->__data.__nwaiters, nwaiters);
+	  lll_futex_wait (&cond->__data.__nwaiters, nwaiters,
+			  // XYZ check mutex flag
+			  LLL_SHARED);
 
 	  lll_mutex_lock (cond->__data.__lock);
 
 	  nwaiters = cond->__data.__nwaiters;
 	}
-      while (nwaiters >= (1 << COND_CLOCK_BITS));
+      while (nwaiters >= (1 << COND_NWAITERS_SHIFT));
     }
 
   return 0;
diff --git a/nptl/pthread_cond_init.c b/nptl/pthread_cond_init.c
index 5e2e6704a9..7c6d4c18f1 100644
--- a/nptl/pthread_cond_init.c
+++ b/nptl/pthread_cond_init.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -31,8 +31,8 @@ __pthread_cond_init (cond, cond_attr)
   cond->__data.__lock = LLL_MUTEX_LOCK_INITIALIZER;
   cond->__data.__futex = 0;
   cond->__data.__nwaiters = (icond_attr != NULL
-			     && ((icond_attr->value & (COND_CLOCK_BITS << 1))
-				 >> 1));
+			     && ((icond_attr->value
+				  & (COND_NWAITERS_SHIFT << 1)) >> 1));
   cond->__data.__total_seq = 0;
   cond->__data.__wakeup_seq = 0;
   cond->__data.__woken_seq = 0;
diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
index 5a9bbcad91..a4faf41854 100644
--- a/nptl/pthread_cond_signal.c
+++ b/nptl/pthread_cond_signal.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.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -44,11 +44,15 @@ __pthread_cond_signal (cond)
 
       /* Wake one.  */
       if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
-						     1, &cond->__data.__lock),
+						     1, &cond->__data.__lock,
+						     // XYZ check mutex flag
+						     LLL_SHARED),
 						     0))
 	return 0;
 
-      lll_futex_wake (&cond->__data.__futex, 1);
+      lll_futex_wake (&cond->__data.__futex, 1,
+		      // XYZ check mutex flag
+		      LLL_SHARED);
     }
 
   /* We are done.  */
diff --git a/nptl/pthread_cond_timedwait.c b/nptl/pthread_cond_timedwait.c
index fdbf43eae8..d1c29d2377 100644
--- a/nptl/pthread_cond_timedwait.c
+++ b/nptl/pthread_cond_timedwait.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.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -67,7 +67,7 @@ __pthread_cond_timedwait (cond, mutex, abstime)
   /* We have one new user of the condvar.  */
   ++cond->__data.__total_seq;
   ++cond->__data.__futex;
-  cond->__data.__nwaiters += 1 << COND_CLOCK_BITS;
+  cond->__data.__nwaiters += 1 << COND_NWAITERS_SHIFT;
 
   /* Remember the mutex we are using here.  If there is already a
      different address store this is a bad user bug.  Do not store
@@ -100,7 +100,7 @@ __pthread_cond_timedwait (cond, mutex, abstime)
 	int ret;
 	ret = INTERNAL_SYSCALL (clock_gettime, err, 2,
 				(cond->__data.__nwaiters
-				 & ((1 << COND_CLOCK_BITS) - 1)),
+				 & ((1 << COND_NWAITERS_SHIFT) - 1)),
 				&rt);
 # ifndef __ASSUME_POSIX_TIMERS
 	if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (ret, err), 0))
@@ -153,7 +153,9 @@ __pthread_cond_timedwait (cond, mutex, abstime)
 
       /* Wait until woken by signal or broadcast.  */
       err = lll_futex_timed_wait (&cond->__data.__futex,
-				  futex_val, &rt);
+				  futex_val, &rt,
+				  // XYZ check mutex flag
+				  LLL_SHARED);
 
       /* Disable asynchronous cancellation.  */
       __pthread_disable_asynccancel (cbuffer.oldtype);
@@ -189,14 +191,16 @@ __pthread_cond_timedwait (cond, mutex, abstime)
 
  bc_out:
 
-  cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;
+  cond->__data.__nwaiters -= 1 << COND_NWAITERS_SHIFT;
 
   /* If pthread_cond_destroy was called on this variable already,
      notify the pthread_cond_destroy caller all waiters have left
      and it can be successfully destroyed.  */
   if (cond->__data.__total_seq == -1ULL
-      && cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
-    lll_futex_wake (&cond->__data.__nwaiters, 1);
+      && cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
+    lll_futex_wake (&cond->__data.__nwaiters, 1,
+		    // XYZ check mutex flag
+		    LLL_SHARED);
 
   /* We are done with the condvar.  */
   lll_mutex_unlock (cond->__data.__lock);
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
index f5f5cec5a8..e524aa6c94 100644
--- a/nptl/pthread_cond_wait.c
+++ b/nptl/pthread_cond_wait.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -62,16 +62,18 @@ __condvar_cleanup (void *arg)
       ++cbuffer->cond->__data.__woken_seq;
     }
 
-  cbuffer->cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;
+  cbuffer->cond->__data.__nwaiters -= 1 << COND_NWAITERS_SHIFT;
 
   /* If pthread_cond_destroy was called on this variable already,
      notify the pthread_cond_destroy caller all waiters have left
      and it can be successfully destroyed.  */
   destroying = 0;
   if (cbuffer->cond->__data.__total_seq == -1ULL
-      && cbuffer->cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
+      && cbuffer->cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
     {
-      lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1);
+      lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1,
+		      // XYZ check mutex flag
+		      LLL_SHARED);
       destroying = 1;
     }
 
@@ -80,7 +82,9 @@ __condvar_cleanup (void *arg)
 
   /* Wake everybody to make sure no condvar signal gets lost.  */
   if (! destroying)
-    lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX);
+    lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX,
+		    // XYZ check mutex flag
+		    LLL_SHARED);
 
   /* Get the mutex before returning unless asynchronous cancellation
      is in effect.  */
@@ -111,7 +115,7 @@ __pthread_cond_wait (cond, mutex)
   /* We have one new user of the condvar.  */
   ++cond->__data.__total_seq;
   ++cond->__data.__futex;
-  cond->__data.__nwaiters += 1 << COND_CLOCK_BITS;
+  cond->__data.__nwaiters += 1 << COND_NWAITERS_SHIFT;
 
   /* Remember the mutex we are using here.  If there is already a
      different address store this is a bad user bug.  Do not store
@@ -146,7 +150,9 @@ __pthread_cond_wait (cond, mutex)
       cbuffer.oldtype = __pthread_enable_asynccancel ();
 
       /* Wait until woken by signal or broadcast.  */
-      lll_futex_wait (&cond->__data.__futex, futex_val);
+      lll_futex_wait (&cond->__data.__futex, futex_val,
+		      // XYZ check mutex flag
+		      LLL_SHARED);
 
       /* Disable asynchronous cancellation.  */
       __pthread_disable_asynccancel (cbuffer.oldtype);
@@ -168,14 +174,16 @@ __pthread_cond_wait (cond, mutex)
 
  bc_out:
 
-  cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;
+  cond->__data.__nwaiters -= 1 << COND_NWAITERS_SHIFT;
 
   /* If pthread_cond_destroy was called on this varaible already,
      notify the pthread_cond_destroy caller all waiters have left
      and it can be successfully destroyed.  */
   if (cond->__data.__total_seq == -1ULL
-      && cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
-    lll_futex_wake (&cond->__data.__nwaiters, 1);
+      && cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
+    lll_futex_wake (&cond->__data.__nwaiters, 1,
+		    // XYZ check mutex flag
+		    LLL_SHARED);
 
   /* We are done with the condvar.  */
   lll_mutex_unlock (cond->__data.__lock);
diff --git a/nptl/pthread_condattr_getclock.c b/nptl/pthread_condattr_getclock.c
index 84de918a54..3eedeb17ef 100644
--- a/nptl/pthread_condattr_getclock.c
+++ b/nptl/pthread_condattr_getclock.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.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -26,6 +26,6 @@ pthread_condattr_getclock (attr, clock_id)
      clockid_t *clock_id;
 {
   *clock_id = (((((const struct pthread_condattr *) attr)->value) >> 1)
-	       & ((1 << COND_CLOCK_BITS) - 1));
+	       & ((1 << COND_NWAITERS_SHIFT) - 1));
   return 0;
 }
diff --git a/nptl/pthread_condattr_setclock.c b/nptl/pthread_condattr_setclock.c
index 04e246b74d..9c03bce9fc 100644
--- a/nptl/pthread_condattr_setclock.c
+++ b/nptl/pthread_condattr_setclock.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.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -62,11 +62,12 @@ pthread_condattr_setclock (attr, clock_id)
     return EINVAL;
 
   /* Make sure the value fits in the bits we reserved.  */
-  assert (clock_id < (1 << COND_CLOCK_BITS));
+  assert (clock_id < (1 << COND_NWAITERS_SHIFT));
 
   int *valuep = &((struct pthread_condattr *) attr)->value;
 
-  *valuep = (*valuep & ~(1 << (COND_CLOCK_BITS + 1)) & ~1) | (clock_id << 1);
+  *valuep = ((*valuep & ~(1 << (COND_NWAITERS_SHIFT + 1)) & ~1)
+	     | (clock_id << 1));
 
   return 0;
 }
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 79729ced03..ca55903c22 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -385,7 +385,7 @@ start_thread (void *arg)
       /* Some other thread might call any of the setXid functions and expect
 	 us to reply.  In this case wait until we did that.  */
       do
-	lll_futex_wait (&pd->setxid_futex, 0);
+	lll_futex_wait (&pd->setxid_futex, 0, LLL_PRIVATE);
       while (pd->cancelhandling & SETXID_BITMASK);
 
       /* Reset the value so that the stack can be reused.  */
diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c
index f6cd8899d8..87cf56482f 100644
--- a/nptl/pthread_getattr_np.c
+++ b/nptl/pthread_getattr_np.c
@@ -39,10 +39,6 @@ pthread_getattr_np (thread_id, attr)
   struct pthread_attr *iattr = (struct pthread_attr *) attr;
   int ret = 0;
 
-  /* We have to handle cancellation in the following code since we are
-     locking another threads desriptor.  */
-  pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &thread->lock);
-
   lll_lock (thread->lock);
 
   /* The thread library is responsible for keeping the values in the
@@ -179,7 +175,5 @@ pthread_getattr_np (thread_id, attr)
 
   lll_unlock (thread->lock);
 
-  pthread_cleanup_pop (0);
-
   return ret;
 }
diff --git a/nptl/pthread_getschedparam.c b/nptl/pthread_getschedparam.c
index 434d867779..5e8713016e 100644
--- a/nptl/pthread_getschedparam.c
+++ b/nptl/pthread_getschedparam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -38,10 +38,6 @@ __pthread_getschedparam (threadid, policy, param)
 
   int result = 0;
 
-  /* We have to handle cancellation in the following code since we are
-     locking another threads descriptor.  */
-  pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &pd->lock);
-
   lll_lock (pd->lock);
 
   /* The library is responsible for maintaining the values at all
@@ -74,8 +70,6 @@ __pthread_getschedparam (threadid, policy, param)
 
   lll_unlock (pd->lock);
 
-  pthread_cleanup_pop (0);
-
   return result;
 }
 strong_alias (__pthread_getschedparam, pthread_getschedparam)
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index 1c3ee4fe25..d0d6805aea 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.c
@@ -43,7 +43,8 @@ __pthread_mutex_lock (mutex)
   pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
 
   int retval = 0;
-  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
+  switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex),
+			    PTHREAD_MUTEX_TIMED_NP))
     {
       /* Recursive mutex.  */
     case PTHREAD_MUTEX_RECURSIVE_NP:
@@ -408,7 +409,9 @@ __pthread_mutex_lock (mutex)
 		  break;
 
 		if (oldval != ceilval)
-		  lll_futex_wait (&mutex->__data.__lock, ceilval | 2);
+		  lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
+				  // XYZ check mutex flag
+				  LLL_SHARED);
 	      }
 	    while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 							ceilval | 2, ceilval)
diff --git a/nptl/pthread_mutex_setprioceiling.c b/nptl/pthread_mutex_setprioceiling.c
index cd13d1c14c..301fb63d21 100644
--- a/nptl/pthread_mutex_setprioceiling.c
+++ b/nptl/pthread_mutex_setprioceiling.c
@@ -1,5 +1,5 @@
 /* Set current priority ceiling of pthread_mutex_t.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
 
@@ -80,7 +80,9 @@ pthread_mutex_setprioceiling (mutex, prioceiling, old_ceiling)
 	      break;
 
 	    if (oldval != ceilval)
-	      lll_futex_wait (&mutex->__data.__lock, ceilval | 2);
+	      lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
+			      // XYZ check mutex flag
+			      LLL_SHARED);
 	  }
 	while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
 						    ceilval | 2, ceilval)
@@ -110,7 +112,9 @@ pthread_mutex_setprioceiling (mutex, prioceiling, old_ceiling)
 			 | (prioceiling << PTHREAD_MUTEX_PRIO_CEILING_SHIFT);
   atomic_full_barrier ();
 
-  lll_futex_wake (&mutex->__data.__lock, INT_MAX);
+  lll_futex_wake (&mutex->__data.__lock, INT_MAX,
+		  // XYZ check mutex flag
+		  LLL_SHARED);
 
   return 0;
 }
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index 8fd681c6ef..825a9849b8 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -37,7 +37,8 @@ pthread_mutex_timedlock (mutex, abstime)
   /* We must not check ABSTIME here.  If the thread does not block
      abstime must not be checked for a valid value.  */
 
-  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
+  switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex),
+			    PTHREAD_MUTEX_TIMED_NP))
     {
       /* Recursive mutex.  */
     case PTHREAD_MUTEX_RECURSIVE_NP:
@@ -441,7 +442,9 @@ pthread_mutex_timedlock (mutex, abstime)
 		      }
 
 		    lll_futex_timed_wait (&mutex->__data.__lock,
-					  ceilval | 2, &rt);
+					  ceilval | 2, &rt,
+					  // XYZ check mutex flag
+					  LLL_SHARED);
 		  }
 	      }
 	    while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 9db904c60b..9a97a6cf81 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -31,7 +31,8 @@ __pthread_mutex_trylock (mutex)
   int oldval;
   pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
 
-  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
+  switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex),
+			    PTHREAD_MUTEX_TIMED_NP))
     {
       /* Recursive mutex.  */
     case PTHREAD_MUTEX_RECURSIVE_NP:
diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
index 33919d60af..642e3a4442 100644
--- a/nptl/pthread_mutex_unlock.c
+++ b/nptl/pthread_mutex_unlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -31,7 +31,8 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
 {
   int newowner = 0;
 
-  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
+  switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex),
+			    PTHREAD_MUTEX_TIMED_NP))
     {
     case PTHREAD_MUTEX_RECURSIVE_NP:
       /* Recursive mutex.  */
@@ -240,7 +241,9 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
 						   newval, oldval));
 
       if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1)
-	lll_futex_wake (&mutex->__data.__lock, 1);
+	lll_futex_wake (&mutex->__data.__lock, 1,
+			// XYZ check mutex flag
+			LLL_SHARED);
 
       int oldprio = newval >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
       return __pthread_tpp_change_priority (oldprio, -1);
diff --git a/nptl/pthread_rwlock_init.c b/nptl/pthread_rwlock_init.c
index f664dd8104..27f25ac2ab 100644
--- a/nptl/pthread_rwlock_init.c
+++ b/nptl/pthread_rwlock_init.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include "pthreadP.h"
+#include <kernel-features.h>
 
 
 static const struct pthread_rwlockattr default_attr =
@@ -37,14 +38,44 @@ __pthread_rwlock_init (rwlock, attr)
   iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_attr;
 
   rwlock->__data.__lock = 0;
-  rwlock->__data.__flags
-    = iattr->lockkind == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP;
   rwlock->__data.__nr_readers = 0;
-  rwlock->__data.__writer = 0;
   rwlock->__data.__readers_wakeup = 0;
   rwlock->__data.__writer_wakeup = 0;
   rwlock->__data.__nr_readers_queued = 0;
   rwlock->__data.__nr_writers_queued = 0;
+  rwlock->__data.__writer = 0;
+
+  rwlock->__data.__flags
+    = iattr->lockkind == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP;
+
+  /* The __SHARED field is computed to minimize the work that needs to
+     be done while handling the futex.  There are two inputs: the
+     availability of private futexes and whether the rwlock is shared
+     or private.  Unfortunately the value of a private rwlock is
+     fixed: it must be zero.  The PRIVATE_FUTEX flag has the value
+     0x80 in case private futexes are available and zero otherwise.
+     This leads to the following table:
+
+                 |     pshared     |     result
+                 | shared  private | shared  private |
+     ------------+-----------------+-----------------+
+     !avail 0    |     0       0   |     0       0   |
+      avail 0x80 |  0x80       0   |     0    0x80   |
+
+     If the pshared value is in locking functions XORed with avail
+     we get the expected result.  */
+#ifdef __ASSUME_PRIVATE_FUTEX
+  rwlock->__data.__shared = (iattr->pshared == PTHREAD_PROCESS_PRIVATE
+			     ? 0 : FUTEX_PRIVATE_FLAG);
+#else
+  rwlock->__data.__shared = (iattr->pshared == PTHREAD_PROCESS_PRIVATE
+			     ? 0
+			     : THREAD_GETMEM (THREAD_SELF,
+					      header.private_futex));
+#endif
+
+  rwlock->__data.__pad1 = 0;
+  rwlock->__data.__pad2 = 0;
 
   return 0;
 }
diff --git a/nptl/pthread_rwlock_rdlock.c b/nptl/pthread_rwlock_rdlock.c
index e225d7030d..b8f9d41d6a 100644
--- a/nptl/pthread_rwlock_rdlock.c
+++ b/nptl/pthread_rwlock_rdlock.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.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -40,7 +40,7 @@ __pthread_rwlock_rdlock (rwlock)
       if (rwlock->__data.__writer == 0
 	  /* ...and if either no writer is waiting or we prefer readers.  */
 	  && (!rwlock->__data.__nr_writers_queued
-	      || rwlock->__data.__flags == 0))
+	      || PTHREAD_RWLOCK_PREFER_READER_P (rwlock)))
 	{
 	  /* Increment the reader counter.  Avoid overflow.  */
 	  if (__builtin_expect (++rwlock->__data.__nr_readers == 0, 0))
@@ -77,7 +77,9 @@ __pthread_rwlock_rdlock (rwlock)
       lll_mutex_unlock (rwlock->__data.__lock);
 
       /* Wait for the writer to finish.  */
-      lll_futex_wait (&rwlock->__data.__readers_wakeup, waitval);
+      lll_futex_wait (&rwlock->__data.__readers_wakeup, waitval, 
+		      // XYZ check mutex flag
+		      LLL_SHARED);
 
       /* Get the lock.  */
       lll_mutex_lock (rwlock->__data.__lock);
diff --git a/nptl/pthread_rwlock_timedrdlock.c b/nptl/pthread_rwlock_timedrdlock.c
index 80ea83a3dd..654d628b2f 100644
--- a/nptl/pthread_rwlock_timedrdlock.c
+++ b/nptl/pthread_rwlock_timedrdlock.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.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -43,7 +43,7 @@ pthread_rwlock_timedrdlock (rwlock, abstime)
       if (rwlock->__data.__writer == 0
 	  /* ...and if either no writer is waiting or we prefer readers.  */
 	  && (!rwlock->__data.__nr_writers_queued
-	      || rwlock->__data.__flags == 0))
+	      || PTHREAD_RWLOCK_PREFER_READER_P (rwlock)))
 	{
 	  /* Increment the reader counter.  Avoid overflow.  */
 	  if (++rwlock->__data.__nr_readers == 0)
@@ -114,7 +114,9 @@ pthread_rwlock_timedrdlock (rwlock, abstime)
 
       /* Wait for the writer to finish.  */
       err = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup,
-				  waitval, &rt);
+				  waitval, &rt,
+				  // XYZ check mutex flag
+				  LLL_SHARED);
 
       /* Get the lock.  */
       lll_mutex_lock (rwlock->__data.__lock);
diff --git a/nptl/pthread_rwlock_timedwrlock.c b/nptl/pthread_rwlock_timedwrlock.c
index 97c0598f96..354beb0846 100644
--- a/nptl/pthread_rwlock_timedwrlock.c
+++ b/nptl/pthread_rwlock_timedwrlock.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.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -104,7 +104,9 @@ pthread_rwlock_timedwrlock (rwlock, abstime)
 
       /* Wait for the writer or reader(s) to finish.  */
       err = lll_futex_timed_wait (&rwlock->__data.__writer_wakeup,
-				  waitval, &rt);
+				  waitval, &rt,
+				  // XYZ check mutex flag
+				  LLL_SHARED);
 
       /* Get the lock.  */
       lll_mutex_lock (rwlock->__data.__lock);
diff --git a/nptl/pthread_rwlock_tryrdlock.c b/nptl/pthread_rwlock_tryrdlock.c
index 446af05969..df8863bcf8 100644
--- a/nptl/pthread_rwlock_tryrdlock.c
+++ b/nptl/pthread_rwlock_tryrdlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -32,7 +32,7 @@ __pthread_rwlock_tryrdlock (rwlock)
 
   if (rwlock->__data.__writer == 0
       && (rwlock->__data.__nr_writers_queued == 0
-	  || rwlock->__data.__flags == 0))
+	  || PTHREAD_RWLOCK_PREFER_READER_P (rwlock)))
     {
       if (__builtin_expect (++rwlock->__data.__nr_readers == 0, 0))
 	{
diff --git a/nptl/pthread_rwlock_unlock.c b/nptl/pthread_rwlock_unlock.c
index 9cae8b6c22..87a77a94ab 100644
--- a/nptl/pthread_rwlock_unlock.c
+++ b/nptl/pthread_rwlock_unlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -38,14 +38,18 @@ __pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
 	{
 	  ++rwlock->__data.__writer_wakeup;
 	  lll_mutex_unlock (rwlock->__data.__lock);
-	  lll_futex_wake (&rwlock->__data.__writer_wakeup, 1);
+	  lll_futex_wake (&rwlock->__data.__writer_wakeup, 1,
+			  // XYZ check mutex flag
+			  LLL_SHARED);
 	  return 0;
 	}
       else if (rwlock->__data.__nr_readers_queued)
 	{
 	  ++rwlock->__data.__readers_wakeup;
 	  lll_mutex_unlock (rwlock->__data.__lock);
-	  lll_futex_wake (&rwlock->__data.__readers_wakeup, INT_MAX);
+	  lll_futex_wake (&rwlock->__data.__readers_wakeup, INT_MAX,
+			  // XYZ check mutex flag
+			  LLL_SHARED);
 	  return 0;
 	}
     }
diff --git a/nptl/pthread_rwlock_wrlock.c b/nptl/pthread_rwlock_wrlock.c
index 822aeed79c..134b3e95d0 100644
--- a/nptl/pthread_rwlock_wrlock.c
+++ b/nptl/pthread_rwlock_wrlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -68,7 +68,9 @@ __pthread_rwlock_wrlock (rwlock)
       lll_mutex_unlock (rwlock->__data.__lock);
 
       /* Wait for the writer or reader(s) to finish.  */
-      lll_futex_wait (&rwlock->__data.__writer_wakeup, waitval);
+      lll_futex_wait (&rwlock->__data.__writer_wakeup, waitval,
+		      // XYZ check mutex flag
+		      LLL_SHARED);
 
       /* Get the lock.  */
       lll_mutex_lock (rwlock->__data.__lock);
diff --git a/nptl/pthread_setschedparam.c b/nptl/pthread_setschedparam.c
index 30ac6b3e89..8129dec82c 100644
--- a/nptl/pthread_setschedparam.c
+++ b/nptl/pthread_setschedparam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -39,10 +39,6 @@ __pthread_setschedparam (threadid, policy, param)
 
   int result = 0;
 
-  /* We have to handle cancellation in the following code since we are
-     locking another threads desriptor.  */
-  pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &pd->lock);
-
   lll_lock (pd->lock);
 
   struct sched_param p;
@@ -73,8 +69,6 @@ __pthread_setschedparam (threadid, policy, param)
 
   lll_unlock (pd->lock);
 
-  pthread_cleanup_pop (0);
-
   return result;
 }
 strong_alias (__pthread_setschedparam, pthread_setschedparam)
diff --git a/nptl/pthread_setschedprio.c b/nptl/pthread_setschedprio.c
index 4a71f6c7b3..59462ec2a1 100644
--- a/nptl/pthread_setschedprio.c
+++ b/nptl/pthread_setschedprio.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -41,10 +41,6 @@ pthread_setschedprio (threadid, prio)
   struct sched_param param;
   param.sched_priority = prio;
 
-  /* We have to handle cancellation in the following code since we are
-     locking another threads desriptor.  */
-  pthread_cleanup_push ((void (*) (void *)) lll_unlock_wake_cb, &pd->lock);
-
   lll_lock (pd->lock);
 
   /* If the thread should have higher priority because of some
@@ -66,7 +62,5 @@ pthread_setschedprio (threadid, prio)
 
   lll_unlock (pd->lock);
 
-  pthread_cleanup_pop (0);
-
   return result;
 }
diff --git a/nptl/sem_getvalue.c b/nptl/sem_getvalue.c
index 6bc7ea82b4..3b17e59629 100644
--- a/nptl/sem_getvalue.c
+++ b/nptl/sem_getvalue.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -27,11 +27,11 @@ __new_sem_getvalue (sem, sval)
      sem_t *sem;
      int *sval;
 {
-  struct sem *isem = (struct sem *) sem;
+  struct new_sem *isem = (struct new_sem *) sem;
 
   /* XXX Check for valid SEM parameter.  */
 
-  *sval = isem->count;
+  *sval = isem->value;
 
   return 0;
 }
diff --git a/nptl/sem_init.c b/nptl/sem_init.c
index 8709911ac3..e29d900588 100644
--- a/nptl/sem_init.c
+++ b/nptl/sem_init.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -22,6 +22,7 @@
 #include <lowlevellock.h>
 #include <shlib-compat.h>
 #include "semaphoreP.h"
+#include <kernel-features.h>
 
 
 int
@@ -38,18 +39,50 @@ __new_sem_init (sem, pshared, value)
     }
 
   /* Map to the internal type.  */
-  struct sem *isem = (struct sem *) sem;
+  struct new_sem *isem = (struct new_sem *) sem;
 
-  /* Use the value the user provided.  */
-  isem->count = value;
+  /* Use the values the user provided.  */
+  isem->value = value;
+#ifdef __ASSUME_PRIVATE_FUTEX
+  isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG;
+#else
+  isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF,
+					       header.private_futex);
+#endif
 
-  /* We can completely ignore the PSHARED parameter since inter-process
-     use needs no special preparation.  */
+  isem->nwaiters = 0;
 
   return 0;
 }
 versioned_symbol (libpthread, __new_sem_init, sem_init, GLIBC_2_1);
+
+
+
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_init, __old_sem_init)
+int
+attribute_compat_text_section
+__old_sem_init (sem, pshared, value)
+     sem_t *sem;
+     int pshared;
+     unsigned int value;
+{
+  /* Parameter sanity check.  */
+  if (__builtin_expect (value > SEM_VALUE_MAX, 0))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  /* Map to the internal type.  */
+  struct old_sem *isem = (struct old_sem *) sem;
+
+  /* Use the value the user provided.  */
+  isem->value = value;
+
+  /* We cannot store the PSHARED attribute.  So we always use the
+     operations needed for shared semaphores.  */
+
+  return 0;
+}
 compat_symbol (libpthread, __old_sem_init, sem_init, GLIBC_2_0);
 #endif
diff --git a/nptl/sem_open.c b/nptl/sem_open.c
index 66bcb13aec..27d308e920 100644
--- a/nptl/sem_open.c
+++ b/nptl/sem_open.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -304,12 +304,14 @@ sem_open (const char *name, int oflag, ...)
       /* Create the initial file content.  */
       sem_t initsem;
 
-      struct sem *iinitsem = (struct sem *) &initsem;
-      iinitsem->count = value;
+      struct new_sem *iinitsem = (struct new_sem *) &initsem;
+      iinitsem->value = value;
+      iinitsem->private = 0;
+      iinitsem->nwaiters = 0;
 
       /* Initialize the remaining bytes as well.  */
-      memset ((char *) &initsem + sizeof (struct sem), '\0',
-	      sizeof (sem_t) - sizeof (struct sem));
+      memset ((char *) &initsem + sizeof (struct new_sem), '\0',
+	      sizeof (sem_t) - sizeof (struct new_sem));
 
       tmpfname = (char *) alloca (mountpoint.dirlen + 6 + 1);
       char *xxxxxx = __mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen);
diff --git a/nptl/semaphoreP.h b/nptl/semaphoreP.h
index 754609a1a8..9659059900 100644
--- a/nptl/semaphoreP.h
+++ b/nptl/semaphoreP.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -60,8 +60,10 @@ extern int __sem_search (const void *a, const void *b) attribute_hidden;
 
 /* Prototypes of functions with multiple interfaces.  */
 extern int __new_sem_init (sem_t *sem, int pshared, unsigned int value);
+extern int __old_sem_init (sem_t *sem, int pshared, unsigned int value);
 extern int __new_sem_destroy (sem_t *sem);
 extern int __new_sem_post (sem_t *sem);
 extern int __new_sem_wait (sem_t *sem);
+extern int __old_sem_wait (sem_t *sem);
 extern int __new_sem_trywait (sem_t *sem);
 extern int __new_sem_getvalue (sem_t *sem, int *sval);
diff --git a/nptl/sysdeps/alpha/tls.h b/nptl/sysdeps/alpha/tls.h
index 64ddcd5c01..e77b1ffca9 100644
--- a/nptl/sysdeps/alpha/tls.h
+++ b/nptl/sysdeps/alpha/tls.h
@@ -131,7 +131,7 @@ typedef struct
 	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
 			       THREAD_GSCOPE_FLAG_UNUSED);		     \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
-	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);   \
     }									     \
   while (0)
 #define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/i386/tcb-offsets.sym b/nptl/sysdeps/i386/tcb-offsets.sym
index 7c8d9a5ca5..69f9deb368 100644
--- a/nptl/sysdeps/i386/tcb-offsets.sym
+++ b/nptl/sysdeps/i386/tcb-offsets.sym
@@ -12,3 +12,6 @@ CLEANUP			offsetof (struct pthread, cleanup)
 CLEANUP_PREV		offsetof (struct _pthread_cleanup_buffer, __prev)
 MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
 POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
+#ifndef __ASSUME_PRIVATE_FUTEX
+PRIVATE_FUTEX		offsetof (tcbhead_t, private_futex)
+#endif
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h
index b97729ce4b..b5127420cf 100644
--- a/nptl/sysdeps/i386/tls.h
+++ b/nptl/sysdeps/i386/tls.h
@@ -27,6 +27,8 @@
 # include <stdint.h>
 # include <stdlib.h>
 # include <list.h>
+# include <sysdep.h>
+# include <kernel-features.h>
 
 
 /* Type for the dtv.  */
@@ -52,6 +54,9 @@ typedef struct
   uintptr_t stack_guard;
   uintptr_t pointer_guard;
   int gscope_flag;
+#ifndef __ASSUME_PRIVATE_FUTEX
+  int private_futex;
+#endif
 } tcbhead_t;
 
 # define TLS_MULTIPLE_THREADS_IN_TCB 1
@@ -444,7 +449,7 @@ union user_desc_init
 		    : "i" (offsetof (struct pthread, header.gscope_flag)),    \
 		      "0" (THREAD_GSCOPE_FLAG_UNUSED));			      \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)				      \
-	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		      \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);    \
     }									      \
   while (0)
 #define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/ia64/tls.h b/nptl/sysdeps/ia64/tls.h
index a144c28b09..936ff01a72 100644
--- a/nptl/sysdeps/ia64/tls.h
+++ b/nptl/sysdeps/ia64/tls.h
@@ -173,7 +173,7 @@ register struct pthread *__thread_self __asm__("r13");
 	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
 			       THREAD_GSCOPE_FLAG_UNUSED);		     \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
-	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);   \
     }									     \
   while (0)
 #define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/powerpc/tcb-offsets.sym b/nptl/sysdeps/powerpc/tcb-offsets.sym
index 4a8671e802..eda43dce8e 100644
--- a/nptl/sysdeps/powerpc/tcb-offsets.sym
+++ b/nptl/sysdeps/powerpc/tcb-offsets.sym
@@ -15,3 +15,4 @@ MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
 PID				thread_offsetof (pid)
 TID				thread_offsetof (tid)
 POINTER_GUARD			(offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
+PRIVATE_FUTEX_OFFSET		thread_offsetof (header.private_futex)
diff --git a/nptl/sysdeps/powerpc/tls.h b/nptl/sysdeps/powerpc/tls.h
index bd9c99e06e..0f4d5290dd 100644
--- a/nptl/sysdeps/powerpc/tls.h
+++ b/nptl/sysdeps/powerpc/tls.h
@@ -190,7 +190,7 @@ register void *__thread_register __asm__ ("r13");
 	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
 			       THREAD_GSCOPE_FLAG_UNUSED);		     \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
-	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);   \
     }									     \
   while (0)
 #define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/pthread/aio_misc.h b/nptl/sysdeps/pthread/aio_misc.h
index c5a11f4550..f36825e06f 100644
--- a/nptl/sysdeps/pthread/aio_misc.h
+++ b/nptl/sysdeps/pthread/aio_misc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 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
@@ -30,7 +30,7 @@
 #define AIO_MISC_NOTIFY(waitlist) \
   do {									      \
     if (*waitlist->counterp > 0 && --*waitlist->counterp == 0)		      \
-      lll_futex_wake (waitlist->counterp, 1);				      \
+      lll_futex_wake (waitlist->counterp, 1, LLL_PRIVATE);		      \
   } while (0)
 
 #define AIO_MISC_WAIT(result, futex, timeout, cancel)			      \
@@ -49,7 +49,8 @@
 	int status;							      \
 	do								      \
 	  {								      \
-	    status = lll_futex_timed_wait (futexaddr, oldval, timeout);	      \
+	    status = lll_futex_timed_wait (futexaddr, oldval, timeout,	      \
+					   LLL_PRIVATE);		      \
 	    if (status != -EWOULDBLOCK)					      \
 	      break;							      \
 									      \
diff --git a/nptl/sysdeps/pthread/bits/stdio-lock.h b/nptl/sysdeps/pthread/bits/stdio-lock.h
index cd64bc37e2..5f2382104b 100644
--- a/nptl/sysdeps/pthread/bits/stdio-lock.h
+++ b/nptl/sysdeps/pthread/bits/stdio-lock.h
@@ -1,5 +1,5 @@
 /* Thread package specific definitions of stream lock type.  NPTL version.
-   Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 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
@@ -94,9 +94,15 @@ typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
 	__attribute__((cleanup (_IO_acquire_lock_fct)))			      \
 	= (_fp);							      \
     _IO_flockfile (_IO_acquire_lock_file);
-
+#  define _IO_acquire_lock_clear_flags2(_fp) \
+  do {									      \
+    _IO_FILE *_IO_acquire_lock_file					      \
+	__attribute__((cleanup (_IO_acquire_lock_clear_flags2_fct)))	      \
+	= (_fp);							      \
+    _IO_flockfile (_IO_acquire_lock_file);
 # else
 #  define _IO_acquire_lock(_fp) _IO_acquire_lock_needs_exceptions_enabled
+#  define _IO_acquire_lock_clear_flags2(_fp) _IO_acquire_lock (_fp)
 # endif
 # define _IO_release_lock(_fp) ; } while (0)
 
diff --git a/nptl/sysdeps/pthread/gai_misc.h b/nptl/sysdeps/pthread/gai_misc.h
index 9f6a73dad1..0a2686cb27 100644
--- a/nptl/sysdeps/pthread/gai_misc.h
+++ b/nptl/sysdeps/pthread/gai_misc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 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
@@ -31,7 +31,7 @@
 #define GAI_MISC_NOTIFY(waitlist) \
   do {									      \
     if (*waitlist->counterp > 0 && --*waitlist->counterp == 0)		      \
-      lll_futex_wake (waitlist->counterp, 1);				      \
+      lll_futex_wake (waitlist->counterp, 1, LLL_PRIVATE);		      \
   } while (0)
 
 #define GAI_MISC_WAIT(result, futex, timeout, cancel) \
@@ -50,7 +50,8 @@
 	int status;							      \
 	do								      \
 	  {								      \
-	    status = lll_futex_timed_wait (futexaddr, oldval, timeout);	      \
+	    status = lll_futex_timed_wait (futexaddr, oldval, timeout,	      \
+					   LLL_PRIVATE);		      \
 	    if (status != -EWOULDBLOCK)					      \
 	      break;							      \
 									      \
diff --git a/nptl/sysdeps/pthread/pt-initfini.c b/nptl/sysdeps/pthread/pt-initfini.c
index 1e35edd3eb..9c00dc0b7d 100644
--- a/nptl/sysdeps/pthread/pt-initfini.c
+++ b/nptl/sysdeps/pthread/pt-initfini.c
@@ -72,7 +72,7 @@ call_initialize_minimal (void)
 }
 
 SECTION (".init");
-extern void _init (void);
+extern void __attribute__ ((section (".init"))) _init (void);
 void
 _init (void)
 {
@@ -93,7 +93,7 @@ asm ("\n/*@_init_EPILOG_ENDS*/");
 asm ("\n/*@_fini_PROLOG_BEGINS*/");
 
 SECTION (".fini");
-extern void _fini (void);
+extern void __attribute__ ((section (".fini"))) _fini (void);
 void
 _fini (void)
 {
diff --git a/nptl/sysdeps/pthread/pthread-functions.h b/nptl/sysdeps/pthread/pthread-functions.h
index a13b937032..0c404fcbb3 100644
--- a/nptl/sysdeps/pthread/pthread-functions.h
+++ b/nptl/sysdeps/pthread/pthread-functions.h
@@ -97,7 +97,6 @@ struct pthread_functions
   void (*ptr__nptl_deallocate_tsd) (void);
   int (*ptr__nptl_setxid) (struct xid_command *);
   void (*ptr_freeres) (void);
-  void (*ptr_wait_lookup_done) (int);
 };
 
 /* Variable in libc.so.  */
diff --git a/nptl/sysdeps/pthread/pthread.h b/nptl/sysdeps/pthread/pthread.h
index 4dc0b2272b..d175f312ee 100644
--- a/nptl/sysdeps/pthread/pthread.h
+++ b/nptl/sysdeps/pthread/pthread.h
@@ -21,6 +21,7 @@
 #define _PTHREAD_H	1
 
 #include <features.h>
+#include <endian.h>
 #include <sched.h>
 #include <time.h>
 
@@ -120,21 +121,23 @@ enum
 };
 
 /* Read-write lock initializers.  */
-# if __WORDSIZE == 64
-#  define PTHREAD_RWLOCK_INITIALIZER \
+# define PTHREAD_RWLOCK_INITIALIZER \
   { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
-# else
-#  define PTHREAD_RWLOCK_INITIALIZER \
-  { { 0, 0, 0, 0, 0, 0, 0, 0 } }
-# endif
 # ifdef __USE_GNU
 #  if __WORDSIZE == 64
 #   define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
   { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,					      \
       PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
 #  else
-#   define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
-  { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 0 } }
+#   if __BYTE_ORDER == __LITTLE_ENDIAN
+#    define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+  { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, \
+      0, 0, 0, 0 } }
+#   else
+#    define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+  { { 0, 0, 0, 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,\
+      0 } }
+#   endif
 #  endif
 # endif
 #endif  /* Unix98 or XOpen2K */
diff --git a/nptl/sysdeps/s390/tls.h b/nptl/sysdeps/s390/tls.h
index 251dfd4a46..3be459e32c 100644
--- a/nptl/sysdeps/s390/tls.h
+++ b/nptl/sysdeps/s390/tls.h
@@ -27,6 +27,7 @@
 # include <stdint.h>
 # include <stdlib.h>
 # include <list.h>
+# include <kernel-features.h>
 
 
 /* Type for the dtv.  */
@@ -51,6 +52,9 @@ typedef struct
   uintptr_t sysinfo;
   uintptr_t stack_guard;
   int gscope_flag;
+#ifndef __ASSUME_PRIVATE_FUTEX
+  int private_futex;
+#endif
 } tcbhead_t;
 
 # ifndef __s390x__
@@ -179,7 +183,7 @@ typedef struct
 	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
 			       THREAD_GSCOPE_FLAG_UNUSED);		     \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
-	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);   \
     }									     \
   while (0)
 #define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/sh/tcb-offsets.sym b/nptl/sysdeps/sh/tcb-offsets.sym
index 4ad866335b..753b72b2dd 100644
--- a/nptl/sysdeps/sh/tcb-offsets.sym
+++ b/nptl/sysdeps/sh/tcb-offsets.sym
@@ -10,3 +10,6 @@ MULTIPLE_THREADS_OFFSET	offsetof (struct pthread, header.multiple_threads)
 TLS_PRE_TCB_SIZE	sizeof (struct pthread)
 MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
 POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
+#ifndef __ASSUME_PRIVATE_FUTEX
+PRIVATE_FUTEX		offsetof (struct pthread, header.private_futex)
+#endif
diff --git a/nptl/sysdeps/sh/tls.h b/nptl/sysdeps/sh/tls.h
index 6d6eff665f..a2d4d565ff 100644
--- a/nptl/sysdeps/sh/tls.h
+++ b/nptl/sysdeps/sh/tls.h
@@ -26,6 +26,10 @@
 # include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
+# include <stdlib.h>
+# include <list.h>
+# include <sysdep.h>
+# include <kernel-features.h>
 
 /* Type for the dtv.  */
 typedef union dtv
@@ -160,7 +164,7 @@ typedef struct
 	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
 			       THREAD_GSCOPE_FLAG_UNUSED);		     \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
-	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);   \
     }									     \
   while (0)
 #define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/sparc/tls.h b/nptl/sysdeps/sparc/tls.h
index 60e52fd4ea..601b53732b 100644
--- a/nptl/sysdeps/sparc/tls.h
+++ b/nptl/sysdeps/sparc/tls.h
@@ -46,9 +46,15 @@ typedef struct
   dtv_t *dtv;
   void *self;
   int multiple_threads;
+#if __WORDSIZE == 64
+  int gscope_flag;
+#endif
   uintptr_t sysinfo;
   uintptr_t stack_guard;
   uintptr_t pointer_guard;
+#if __WORDSIZE != 64
+  int gscope_flag;
+#endif
 } tcbhead_t;
 
 #else /* __ASSEMBLER__ */
@@ -151,7 +157,7 @@ register struct pthread *__thread_self __asm__("%g7");
 	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
 			       THREAD_GSCOPE_FLAG_UNUSED);		     \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
-	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);   \
     }									     \
   while (0)
 #define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/unix/sysv/linux/Makefile b/nptl/sysdeps/unix/sysv/linux/Makefile
index cfcdb6d97f..ad5ae6ad12 100644
--- a/nptl/sysdeps/unix/sysv/linux/Makefile
+++ b/nptl/sysdeps/unix/sysv/linux/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -25,7 +25,8 @@ 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
+			lowlevelrobustlock.sym pthread-pi-defines.sym \
+			structsem.sym
 endif
 
 ifeq ($(subdir),posix)
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
index 58b4806eb2..5f08673c43 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 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
@@ -36,34 +36,63 @@
 #define FUTEX_LOCK_PI		6
 #define FUTEX_UNLOCK_PI		7
 #define FUTEX_TRYLOCK_PI	8
+#define FUTEX_PRIVATE_FLAG	128
+
+/* 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);		      \
-    INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __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));			      \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __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);					      \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret;		      \
   })
 
@@ -72,7 +101,7 @@
     {									      \
       int *__futexp = &(futexv);					      \
       atomic_or (__futexp, FUTEX_OWNER_DIED);				      \
-      lll_futex_wake (__futexp, 1);					      \
+      lll_futex_wake (__futexp, 1, LLL_SHARED);				      \
     }									      \
   while (0)
 
@@ -198,7 +227,7 @@ __lll_mutex_unlock (int *futex)
 {
   int val = atomic_exchange_rel (futex, 0);
   if (__builtin_expect (val > 1, 0))
-    lll_futex_wake (futex, 1);
+    lll_futex_wake (futex, 1, LLL_SHARED);
 }
 #define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex))
 
@@ -208,7 +237,7 @@ __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);
+    lll_futex_wake (futex, 1, LLL_SHARED);
 }
 #define lll_robust_mutex_unlock(futex) \
   __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS)
@@ -218,7 +247,7 @@ static inline void __attribute__ ((always_inline))
 __lll_mutex_unlock_force (int *futex)
 {
   (void) atomic_exchange_rel (futex, 0);
-  lll_futex_wake (futex, 1);
+  lll_futex_wake (futex, 1, LLL_SHARED);
 }
 #define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex))
 
@@ -237,8 +266,6 @@ typedef int lll_lock_t;
 #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
@@ -254,10 +281,10 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
    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 *)
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c
index 79a3c47aed..0e7e9790dd 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c
+++ b/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/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c
index 98bb237c06..f9913c343e 100644
--- a/nptl/sysdeps/unix/sysv/linux/fork.c
+++ b/nptl/sysdeps/unix/sysv/linux/fork.c
@@ -203,7 +203,7 @@ __libc_fork (void)
 
 	  if (atomic_decrement_and_test (&allp->handler->refcntr)
 	      && allp->handler->need_signal)
-	    lll_futex_wake (allp->handler->refcntr, 1);
+	    lll_futex_wake (allp->handler->refcntr, 1, LLL_PRIVATE);
 
 	  allp = allp->next;
 	}
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
index f53d0e5a72..9e3e016fb8 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002,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
@@ -128,7 +128,10 @@ typedef union
     unsigned int __nr_writers_queued;
     /* 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;
     int __writer;
   } __data;
   char __size[__SIZEOF_PTHREAD_RWLOCK_T];
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
index 88885b735d..830f628578 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -17,14 +17,19 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* In libc.so we do not unconditionally use the lock prefix.  Only if
-   the application is using threads.  */
-#ifndef UP
-# define LOCK \
-	cmpl	$0, %gs:MULTIPLE_THREADS_OFFSET; 			      \
-	je	0f;							      \
-	lock;								      \
-0:
+#include <kernel-features.h>
+
+/* All locks in libc are private.  Use the kernel feature if possible.  */
+#define FUTEX_PRIVATE_FLAG	128
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define FUTEX_WAIT		(0 | FUTEX_PRIVATE_FLAG)
+# define FUTEX_WAKE		(1 | FUTEX_PRIVATE_FLAG)
+#else
+# define LOAD_FUTEX_WAIT(reg) \
+	movl	%gs:PRIVATE_FUTEX, reg
+# define LOAD_FUTEX_WAKE(reg) \
+	movl	%gs:PRIVATE_FUTEX, reg ; \
+	orl	$FUTEX_WAKE, reg
 #endif
 
 #include "lowlevellock.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
index e2da5b04cf..cfcc7dafc4 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -32,8 +32,22 @@
 
 #define SYS_gettimeofday	__NR_gettimeofday
 #define SYS_futex		240
-#define FUTEX_WAIT		0
-#define FUTEX_WAKE		1
+#ifndef FUTEX_WAIT
+# define FUTEX_WAIT		0
+# define FUTEX_WAKE		1
+#endif
+
+#ifndef LOAD_FUTEX_WAIT
+# if FUTEX_WAIT == 0
+#  define LOAD_FUTEX_WAIT(reg) \
+	xorl	reg, reg
+# else
+#  define LOAD_FUTEX_WAIT(reg) \
+	movl	$FUTEX_WAIT, reg
+# endif
+# define LOAD_FUTEX_WAKE(reg) \
+	movl	$FUTEX_WAKE, reg
+#endif
 
 
 	.globl	__lll_mutex_lock_wait
@@ -55,7 +69,7 @@ __lll_mutex_lock_wait:
 	movl	$2, %edx
 	movl	%ecx, %ebx
 	xorl	%esi, %esi	/* No timeout.  */
-	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */
+	LOAD_FUTEX_WAIT (%ecx)
 
 	cmpl	%edx, %eax	/* NB:	 %edx == 2 */
 	jne 2f
@@ -151,7 +165,7 @@ __lll_mutex_timedlock_wait:
 
 	/* Futex call.  */
 	movl	%esp, %esi
-	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */
+	LOAD_FUTEX_WAIT (%ecx)
 	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 	movl	%eax, %ecx
@@ -205,35 +219,6 @@ __lll_mutex_timedlock_wait:
 #endif
 
 
-#ifdef NOT_IN_libc
-	.globl	lll_unlock_wake_cb
-	.type	lll_unlock_wake_cb,@function
-	.hidden	lll_unlock_wake_cb
-	.align	16
-lll_unlock_wake_cb:
-	pushl	%ebx
-	pushl	%ecx
-	pushl	%edx
-
-	movl	20(%esp), %ebx
-	LOCK
-	subl	$1, (%ebx)
-	je	1f
-
-	movl	$FUTEX_WAKE, %ecx
-	movl	$1, %edx	/* Wake one thread.  */
-	movl	$SYS_futex, %eax
-	movl	$0, (%ebx)
-	ENTER_KERNEL
-
-1:	popl	%edx
-	popl	%ecx
-	popl	%ebx
-	ret
-	.size	lll_unlock_wake_cb,.-lll_unlock_wake_cb
-#endif
-
-
 	.globl	__lll_mutex_unlock_wake
 	.type	__lll_mutex_unlock_wake,@function
 	.hidden	__lll_mutex_unlock_wake
@@ -252,7 +237,7 @@ __lll_mutex_unlock_wake:
 
 	movl	%eax, %ebx
 	movl	$0, (%eax)
-	movl	$FUTEX_WAKE, %ecx
+	LOAD_FUTEX_WAKE (%ecx)
 	movl	$1, %edx	/* Wake one thread.  */
 	movl	$SYS_futex, %eax
 	ENTER_KERNEL
@@ -314,6 +299,8 @@ __lll_timedwait_tid:
 	jz	4f
 
 	movl	%esp, %esi
+	/* XXX The kernel so far uses global futex for the wakeup at
+	   all times.  */
 	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */
 	movl	%ebp, %ebx
 	movl	$SYS_futex, %eax
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
index fe7a8b9c66..29857195f0 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -69,7 +69,13 @@ pthread_barrier_wait:
 
 	/* Wait for the remaining threads.  The call will return immediately
 	   if the CURR_EVENT memory has meanwhile been changed.  */
-7:	xorl	%ecx, %ecx		/* movl $FUTEX_WAIT, %ecx */
+7:
+#if FUTEX_WAIT == 0
+	movl	PRIVATE(%ebx), %ecx
+#else
+	movl	$FUTEX_WAIT, %ecx
+	orl	PRIVATE(%ebx), %ecx
+#endif
 	xorl	%esi, %esi
 8:	movl	$SYS_futex, %eax
 	ENTER_KERNEL
@@ -120,6 +126,7 @@ pthread_barrier_wait:
 	   so 0x7fffffff is the highest value.  */
 	movl	$0x7fffffff, %edx
 	movl	$FUTEX_WAKE, %ecx
+	orl	PRIVATE(%ebx), %ecx
 	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
index f481a8e43c..93f4d56b32 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -87,7 +87,7 @@ __pthread_cond_timedwait:
 	addl	$1, total_seq(%ebx)
 	adcl	$0, total_seq+4(%ebx)
 	addl	$1, cond_futex(%ebx)
-	addl	$(1 << clock_bits), cond_nwaiters(%ebx)
+	addl	$(1 << nwaiters_shift), cond_nwaiters(%ebx)
 
 #define FRAME_SIZE 24
 	subl	$FRAME_SIZE, %esp
@@ -106,7 +106,7 @@ __pthread_cond_timedwait:
 #ifdef __NR_clock_gettime
 	/* Get the clock number.  */
 	movl	cond_nwaiters(%ebx), %ebx
-	andl	$((1 << clock_bits) - 1), %ebx
+	andl	$((1 << nwaiters_shift) - 1), %ebx
 	/* Only clocks 0 and 1 are allowed so far.  Both are handled in the
 	   kernel.  */
 	leal	4(%esp), %ecx
@@ -228,7 +228,7 @@ __pthread_cond_timedwait:
 14:	addl	$1, woken_seq(%ebx)
 	adcl	$0, woken_seq+4(%ebx)
 
-24:	subl	$(1 << clock_bits), cond_nwaiters(%ebx)
+24:	subl	$(1 << nwaiters_shift), cond_nwaiters(%ebx)
 
 	/* Wake up a thread which wants to destroy the condvar object.  */
 	movl	total_seq(%ebx), %eax
@@ -236,7 +236,7 @@ __pthread_cond_timedwait:
 	cmpl	$0xffffffff, %eax
 	jne	25f
 	movl	cond_nwaiters(%ebx), %eax
-	andl	$~((1 << clock_bits) - 1), %eax
+	andl	$~((1 << nwaiters_shift) - 1), %eax
 	jne	25f
 
 	addl	$cond_nwaiters, %ebx
@@ -424,7 +424,7 @@ __condvar_tw_cleanup:
 7:	addl	$1, woken_seq(%ebx)
 	adcl	$0, woken_seq+4(%ebx)
 
-3:	subl	$(1 << clock_bits), cond_nwaiters(%ebx)
+3:	subl	$(1 << nwaiters_shift), cond_nwaiters(%ebx)
 
 	/* Wake up a thread which wants to destroy the condvar object.  */
 	xorl	%edi, %edi
@@ -433,7 +433,7 @@ __condvar_tw_cleanup:
 	cmpl	$0xffffffff, %eax
 	jne	4f
 	movl	cond_nwaiters(%ebx), %eax
-	andl	$~((1 << clock_bits) - 1), %eax
+	andl	$~((1 << nwaiters_shift) - 1), %eax
 	jne	4f
 
 	addl	$cond_nwaiters, %ebx
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
index f16c7d9198..c92cfbc718 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -80,7 +80,7 @@ __pthread_cond_wait:
 	addl	$1, total_seq(%ebx)
 	adcl	$0, total_seq+4(%ebx)
 	addl	$1, cond_futex(%ebx)
-	addl	$(1 << clock_bits), cond_nwaiters(%ebx)
+	addl	$(1 << nwaiters_shift), cond_nwaiters(%ebx)
 
 #define FRAME_SIZE 16
 	subl	$FRAME_SIZE, %esp
@@ -157,7 +157,7 @@ __pthread_cond_wait:
 	adcl	$0, woken_seq+4(%ebx)
 
 	/* Unlock */
-16:	subl	$(1 << clock_bits), cond_nwaiters(%ebx)
+16:	subl	$(1 << nwaiters_shift), cond_nwaiters(%ebx)
 
 	/* Wake up a thread which wants to destroy the condvar object.  */
 	movl	total_seq(%ebx), %eax
@@ -165,7 +165,7 @@ __pthread_cond_wait:
 	cmpl	$0xffffffff, %eax
 	jne	17f
 	movl	cond_nwaiters(%ebx), %eax
-	andl	$~((1 << clock_bits) - 1), %eax
+	andl	$~((1 << nwaiters_shift) - 1), %eax
 	jne	17f
 
 	addl	$cond_nwaiters, %ebx
@@ -315,7 +315,7 @@ __condvar_w_cleanup:
 7:	addl	$1, woken_seq(%ebx)
 	adcl	$0, woken_seq+4(%ebx)
 
-3:	subl	$(1 << clock_bits), cond_nwaiters(%ebx)
+3:	subl	$(1 << nwaiters_shift), cond_nwaiters(%ebx)
 
 	/* Wake up a thread which wants to destroy the condvar object.  */
 	xorl	%edi, %edi
@@ -324,7 +324,7 @@ __condvar_w_cleanup:
 	cmpl	$0xffffffff, %eax
 	jne	4f
 	movl	cond_nwaiters(%ebx), %eax
-	andl	$~((1 << clock_bits) - 1), %eax
+	andl	$~((1 << nwaiters_shift) - 1), %eax
 	jne	4f
 
 	addl	$cond_nwaiters, %ebx
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
index db0639d21c..c61c697985 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -61,7 +61,7 @@ __pthread_rwlock_rdlock:
 	jne	14f
 	cmpl	$0, WRITERS_QUEUED(%ebx)
 	je	5f
-	cmpl	$0, FLAGS(%ebx)
+	cmpb	$0, FLAGS(%ebx)
 	je	5f
 
 3:	addl	$1, READERS_QUEUED(%ebx)
@@ -77,8 +77,18 @@ __pthread_rwlock_rdlock:
 #endif
 	jne	10f
 
-11:	addl	$READERS_WAKEUP, %ebx
-	movl	%esi, %ecx	/* movl $FUTEX_WAIT, %ecx */
+11:
+#if __ASSUME_PRIVATE_FUTEX
+	movzbl	PSHARED(%ebx), %ecx
+	xorl	$FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
+#else
+	movzbl	PSHARED(%ebx), %ecx
+# if FUTEX_WAIT != 0
+	orl	$FUTEX_WAIT, %ecx
+# endif
+	xorl	%gs:PRIVATE_FUTEX, %ecx
+#endif
+	addl	$READERS_WAKEUP, %ebx
 	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
index eb5665b432..c6a584fed0 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -65,7 +65,7 @@ pthread_rwlock_timedrdlock:
 	jne	14f
 	cmpl	$0, WRITERS_QUEUED(%ebp)
 	je	5f
-	cmpl	$0, FLAGS(%ebp)
+	cmpb	$0, FLAGS(%ebp)
 	je	5f
 
 	/* Check the value of the timeout parameter.  */
@@ -108,8 +108,18 @@ pthread_rwlock_timedrdlock:
 	/* Futex call.  */
 	movl	%ecx, (%esp)	/* Store relative timeout.  */
 	movl	%edx, 4(%esp)
+
 	movl	%esi, %edx
-	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */
+#if __ASSUME_PRIVATE_FUTEX
+	movzbl	PSHARED(%ebp), %ecx
+	xorl	$FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
+#else
+	movzbl	PSHARED(%ebp), %ecx
+# if FUTEX_WAIT != 0
+	orl	$FUTEX_WAIT, %ecx
+# endif
+	xorl	%gs:PRIVATE_FUTEX, %ecx
+#endif
 	movl	%esp, %esi
 	leal	READERS_WAKEUP(%ebp), %ebx
 	movl	$SYS_futex, %eax
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
index d9db77ba05..5e9faf93fb 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -106,8 +106,18 @@ pthread_rwlock_timedwrlock:
 	/* Futex call.  */
 	movl	%ecx, (%esp)	/* Store relative timeout.  */
 	movl	%edx, 4(%esp)
+
 	movl	%esi, %edx
-	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */
+#if __ASSUME_PRIVATE_FUTEX
+	movzbl	PSHARED(%ebp), %ecx
+	xorl	$FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
+#else
+	movzbl	PSHARED(%ebp), %ecx
+# if FUTEX_WAIT != 0
+	orl	$FUTEX_WAIT, %ecx
+# endif
+	xorl	%gs:PRIVATE_FUTEX, %ecx
+#endif
 	movl	%esp, %esi
 	leal	WRITERS_WAKEUP(%ebp), %ebx
 	movl	$SYS_futex, %eax
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
index 64aac3255a..35c40c2c1c 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -61,9 +61,8 @@ __pthread_rwlock_unlock:
 
 5:	movl	$0, WRITER(%edi)
 
-	movl	$1, %ecx
+	movl	$1, %edx
 	leal	WRITERS_WAKEUP(%edi), %ebx
-	movl	%ecx, %edx
 	cmpl	$0, WRITERS_QUEUED(%edi)
 	jne	0f
 
@@ -83,7 +82,16 @@ __pthread_rwlock_unlock:
 #endif
 	jne	7f
 
-8:	movl	$SYS_futex, %eax
+8:
+#if __ASSUME_PRIVATE_FUTEX
+	movzbl	PSHARED(%edi), %ecx
+	xorl	$FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %ecx
+#else
+	movzbl	PSHARED(%edi), %ecx
+	orl	$FUTEX_WAKE, %ecx
+	xorl	%gs:PRIVATE_FUTEX, %ecx
+#endif
+	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 
 	xorl	%eax, %eax
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
index ea9cc170db..88044c040b 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -75,8 +75,18 @@ __pthread_rwlock_wrlock:
 #endif
 	jne	10f
 
-11:	addl	$WRITERS_WAKEUP, %ebx
-	movl	%esi, %ecx	/* movl $FUTEX_WAIT, %ecx */
+11:
+#if __ASSUME_PRIVATE_FUTEX
+	movzbl	PSHARED(%ebx), %ecx
+	xorl	$FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
+#else
+	movzbl	PSHARED(%ebx), %ecx
+# if FUTEX_WAIT != 0
+	orl	$FUTEX_WAIT, %ecx
+# endif
+	xorl	%gs:PRIVATE_FUTEX, %ecx
+#endif
+	addl	$WRITERS_WAKEUP, %ebx
 	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
index 71e96d2228..280dc2fe27 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -40,19 +41,27 @@ __new_sem_post:
 	pushl	%ebx
 
 	movl	8(%esp), %ebx
-	movl	$1, %edx
+
 	LOCK
-	xaddl	%edx, (%ebx)
+#if VALUE == 0
+	addl	$1, (%ebx)
+#else
+	addl	$1, VALUE(%ebx)
+#endif
+
+	cmpl	$0, NWAITERS(%ebx)
+	je	2f
 
-	movl	$SYS_futex, %eax
 	movl	$FUTEX_WAKE, %ecx
-	addl	$1, %edx
+	orl	PRIVATE(%ebx), %ecx
+	movl	$1, %edx
+	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 
 	testl	%eax, %eax
 	js	1f
 
-	xorl	%eax, %eax
+2:	xorl	%eax, %eax
 	popl	%ebx
 	ret
 
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
index bf70e17fca..57b5b58186 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -29,7 +30,12 @@
 
 #define SYS_gettimeofday	__NR_gettimeofday
 #define SYS_futex		240
-#define FUTEX_WAKE		1
+#define FUTEX_WAIT		0
+
+
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
 
 
 	.text
@@ -37,14 +43,8 @@
 	.globl	sem_timedwait
 	.type	sem_timedwait,@function
 	.align	16
-	cfi_startproc
 sem_timedwait:
-	/* First check for cancellation.  */
-	movl	%gs:CANCELHANDLING, %eax
-	andl	$0xfffffff9, %eax
-	cmpl	$8, %eax
-	je	10f
-
+.LSTARTCODE:
 	movl	4(%esp), %ecx
 
 	movl	(%ecx), %eax
@@ -61,24 +61,24 @@ sem_timedwait:
 
 	/* Check whether the timeout value is valid.  */
 1:	pushl	%esi
-	cfi_adjust_cfa_offset(4)
+.Lpush_esi:
 	pushl	%edi
-	cfi_adjust_cfa_offset(4)
+.Lpush_edi:
 	pushl	%ebx
-	cfi_adjust_cfa_offset(4)
+.Lpush_ebx:
 	subl	$12, %esp
-	cfi_adjust_cfa_offset(12)
+.Lsub_esp:
 
 	movl	32(%esp), %edi
-	cfi_offset(7, -12)		/* %edi */
 
 	/* Check for invalid nanosecond field.  */
 	cmpl	$1000000000, 4(%edi)
 	movl	$EINVAL, %esi
-	cfi_offset(6, -8)		/* %esi */
 	jae	6f
 
-	cfi_offset(3, -16)		/* %ebx */
+	LOCK
+	incl	NWAITERS(%ecx)
+
 7:	xorl	%ecx, %ecx
 	movl	%esp, %ebx
 	movl	%ecx, %edx
@@ -103,19 +103,26 @@ sem_timedwait:
 	movl	%ecx, (%esp)	/* Store relative timeout.  */
 	movl	%edx, 4(%esp)
 
+.LcleanupSTART:
 	call	__pthread_enable_asynccancel
 	movl	%eax, 8(%esp)
 
-	movl	28(%esp), %ebx
-	xorl	%ecx, %ecx
+	movl	28(%esp), %ebx	/* Load semaphore address.  */
+#if FUTEX_WAIT == 0
+	movl	PRIVATE(%ebx), %ecx
+#else
+	movl	$FUTEX_WAIT, %ecx
+	orl	PRIVATE(%ebx), %ecx
+#endif
 	movl	%esp, %esi
-	movl	$SYS_futex, %eax
 	xorl	%edx, %edx
+	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 	movl	%eax, %esi
 
 	movl	8(%esp), %eax
 	call	__pthread_disable_asynccancel
+.LcleanupEND:
 
 	testl	%esi, %esi
 	je	9f
@@ -131,24 +138,22 @@ sem_timedwait:
 	cmpxchgl %ecx, (%ebx)
 	jne	8b
 
-	addl	$12, %esp
-	cfi_adjust_cfa_offset(-12)
 	xorl	%eax, %eax
+
+10:	LOCK
+	decl	NWAITERS(%ebx)
+
+	addl	$12, %esp
+.Ladd_esp:
 	popl	%ebx
-	cfi_adjust_cfa_offset(-4)
-	cfi_restore(3)
+.Lpop_ebx:
 	popl	%edi
-	cfi_adjust_cfa_offset(-4)
-	cfi_restore(7)
+.Lpop_edi:
 	popl	%esi
-	cfi_adjust_cfa_offset(-4)
-	cfi_restore(6)
+.Lpop_esi:
 	ret
 
-	cfi_adjust_cfa_offset(24)
-	cfi_offset(6, -8)		/* %esi */
-	cfi_offset(7, -12)	 	/* %edi */
-	cfi_offset(3, -16)		/* %ebx */
+.Lafter_ret:
 3:	negl	%esi
 6:
 #ifdef PIC
@@ -172,25 +177,163 @@ sem_timedwait:
 	movl	%esi, (%eax)
 #endif
 
-	addl	$12, %esp
-	cfi_adjust_cfa_offset(-12)
+	movl	28(%esp), %ebx	/* Load semaphore address.  */
 	orl	$-1, %eax
-	popl	%ebx
-	cfi_adjust_cfa_offset(-4)
-	cfi_restore(3)
-	popl	%edi
-	cfi_adjust_cfa_offset(-4)
-	cfi_restore(7)
-	popl	%esi
-	cfi_adjust_cfa_offset(-4)
-	cfi_restore(6)
-	ret
+	jmp	10b
+	.size	sem_timedwait,.-sem_timedwait
 
-10:	/* Canceled.  */
-	movl	$0xffffffff, %gs:RESULT
+
+	.type	sem_wait_cleanup,@function
+sem_wait_cleanup:
 	LOCK
-	orl	$0x10, %gs:CANCELHANDLING
-	movl	%gs:CLEANUP_JMP_BUF, %eax
-	jmp	HIDDEN_JUMPTARGET (__pthread_unwind)
-	cfi_endproc
-	.size	sem_timedwait,.-sem_timedwait
+	decl	NWAITERS(%ebx)
+	movl	%eax, (%esp)
+.LcallUR:
+	call	_Unwind_Resume@PLT
+	hlt
+.LENDCODE:
+	.size	sem_wait_cleanup,.-sem_wait_cleanup
+
+
+	.section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+	.byte	0xff				# @LPStart format (omit)
+	.byte	0xff				# @TType format (omit)
+	.byte	0x01				# call-site format
+						# DW_EH_PE_uleb128
+	.uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+	.uleb128 .LcleanupSTART-.LSTARTCODE
+	.uleb128 .LcleanupEND-.LcleanupSTART
+	.uleb128 sem_wait_cleanup-.LSTARTCODE
+	.uleb128  0
+	.uleb128 .LcallUR-.LSTARTCODE
+	.uleb128 .LENDCODE-.LcallUR
+	.uleb128 0
+	.uleb128  0
+.Lcstend:
+
+
+	.section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+	.long	.LENDCIE-.LSTARTCIE		# Length of the CIE.
+.LSTARTCIE:
+	.long	0				# CIE ID.
+	.byte	1				# Version number.
+#ifdef SHARED
+	.string	"zPLR"				# NUL-terminated augmentation
+						# string.
+#else
+	.string	"zPL"				# NUL-terminated augmentation
+						# string.
+#endif
+	.uleb128 1				# Code alignment factor.
+	.sleb128 -4				# Data alignment factor.
+	.byte	8				# Return address register
+						# column.
+#ifdef SHARED
+	.uleb128 7				# Augmentation value length.
+	.byte	0x9b				# Personality: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4
+						# + DW_EH_PE_indirect
+	.long	DW.ref.__gcc_personality_v0-.
+	.byte	0x1b				# LSDA Encoding: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4.
+	.byte	0x1b				# FDE Encoding: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4.
+#else
+	.uleb128 6				# Augmentation value length.
+	.byte	0x0				# Personality: absolute
+	.long	__gcc_personality_v0
+	.byte	0x0				# LSDA Encoding: absolute
+#endif
+	.byte 0x0c				# DW_CFA_def_cfa
+	.uleb128 4
+	.uleb128 4
+	.byte	0x88				# DW_CFA_offset, column 0x10
+	.uleb128 1
+	.align 4
+.LENDCIE:
+
+	.long	.LENDFDE-.LSTARTFDE		# Length of the FDE.
+.LSTARTFDE:
+	.long	.LSTARTFDE-.LSTARTFRAME		# CIE pointer.
+#ifdef SHARED
+	.long	.LSTARTCODE-.			# PC-relative start address
+						# of the code.
+#else
+	.long	.LSTARTCODE			# Start address of the code.
+#endif
+	.long	.LENDCODE-.LSTARTCODE		# Length of the code.
+	.uleb128 4				# Augmentation size
+#ifdef SHARED
+	.long	.LexceptSTART-.
+#else
+	.long	.LexceptSTART
+#endif
+
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpush_esi-.LSTARTCODE
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 8
+	.byte   0x86				# DW_CFA_offset %esi
+        .uleb128 2
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpush_edi-.Lpush_esi
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 12
+	.byte   0x87				# DW_CFA_offset %edi
+        .uleb128 3
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpush_ebx-.Lpush_edi
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 16
+	.byte   0x83				# DW_CFA_offset %ebx
+        .uleb128 4
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lsub_esp-.Lpush_ebx
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 28
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Ladd_esp-.Lsub_esp
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 16
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpop_ebx-.Ladd_esp
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 12
+	.byte	0xc3				# DW_CFA_restore %ebx
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpop_edi-.Lpop_ebx
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 8
+	.byte	0xc7				# DW_CFA_restore %edi
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpop_esi-.Lpop_edi
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 4
+	.byte	0xc6				# DW_CFA_restore %esi
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lafter_ret-.Lpop_esi
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 28
+	.byte   0x86				# DW_CFA_offset %esi
+        .uleb128 2
+	.byte   0x87				# DW_CFA_offset %edi
+        .uleb128 3
+	.byte   0x83				# DW_CFA_offset %ebx
+        .uleb128 4
+	.align	4
+.LENDFDE:
+
+
+#ifdef SHARED
+	.hidden	DW.ref.__gcc_personality_v0
+	.weak	DW.ref.__gcc_personality_v0
+	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+	.align	4
+	.type	DW.ref.__gcc_personality_v0, @object
+	.size	DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+	.long	__gcc_personality_v0
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
index b1296275d0..d0eef75144 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -28,22 +29,261 @@
 #endif
 
 #define SYS_futex		240
-#define FUTEX_WAKE		1
+#define FUTEX_WAIT		0
 
 
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
+
 	.text
 
 	.globl	__new_sem_wait
 	.type	__new_sem_wait,@function
 	.align	16
-	cfi_startproc
 __new_sem_wait:
-	/* First check for cancellation.  */
-	movl	%gs:CANCELHANDLING, %eax
-	andl	$0xfffffff9, %eax
-	cmpl	$8, %eax
-	je	5f
+.LSTARTCODE:
+	pushl	%ebx
+.Lpush_ebx:
+	pushl	%esi
+.Lpush_esi:
+	subl	$4, %esp
+.Lsub_esp:
+
+	movl	16(%esp), %ebx
+
+	movl	(%ebx), %eax
+2:	testl	%eax, %eax
+	je	1f
+
+	leal	-1(%eax), %edx
+	LOCK
+	cmpxchgl %edx, (%ebx)
+	jne	2b
+7:	xorl	%eax, %eax
+
+9:	movl	4(%esp), %esi
+	movl	8(%esp), %ebx
+	addl	$12, %esp
+.Ladd_esp:
+	ret
+
+.Lafter_ret:
+1:	LOCK
+	incl	NWAITERS(%ebx)
+
+.LcleanupSTART:
+6:	call	__pthread_enable_asynccancel
+	movl	%eax, (%esp)
+
+#if FUTEX_WAIT == 0
+	movl	PRIVATE(%ebx), %ecx
+#else
+	movl	$FUTEX_WAIT, %ecx
+	orl	PRIVATE(%ebx), %ecx
+#endif
+	xorl	%esi, %esi
+	xorl	%edx, %edx
+	movl	$SYS_futex, %eax
+	ENTER_KERNEL
+	movl	%eax, %esi
+
+	movl	(%esp), %eax
+	call	__pthread_disable_asynccancel
+.LcleanupEND:
+
+	testl	%esi, %esi
+	je	3f
+	cmpl	$-EWOULDBLOCK, %esi
+	jne	4f
+
+3:
+	movl	(%ebx), %eax
+5:	testl	%eax, %eax
+	je	6b
+
+	leal	-1(%eax), %edx
+	LOCK
+	cmpxchgl %edx, (%ebx)
+	jne	5b
+
+	LOCK
+	decl	NWAITERS(%ebx)
+	jmp	7b
+
+4:	LOCK
+	decl	NWAITERS(%ebx)
+
+	negl	%esi
+#ifdef PIC
+	call	__i686.get_pc_thunk.bx
+#else
+	movl	$8f, %ebx
+8:
+#endif
+	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+	movl	errno@gotntpoff(%ebx), %edx
+	addl	%gs:0, %edx
+	movl	%esi, (%edx)
+# else
+	movl	errno@gotntpoff(%ebx), %edx
+	movl	%esi, %gs:(%edx)
+# endif
+#else
+	call	__errno_location@plt
+	movl	%esi, (%eax)
+#endif
+	orl	$-1, %eax
+
+	jmp	9b
+	.size	__new_sem_wait,.-__new_sem_wait
+	versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
+
+
+	.type	sem_wait_cleanup,@function
+sem_wait_cleanup:
+	LOCK
+	decl	NWAITERS(%ebx)
+	movl	%eax, (%esp)
+.LcallUR:
+	call	_Unwind_Resume@PLT
+	hlt
+.LENDCODE:
+	.size	sem_wait_cleanup,.-sem_wait_cleanup
+
+
+	.section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+	.byte	0xff				# @LPStart format (omit)
+	.byte	0xff				# @TType format (omit)
+	.byte	0x01				# call-site format
+						# DW_EH_PE_uleb128
+	.uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+	.uleb128 .LcleanupSTART-.LSTARTCODE
+	.uleb128 .LcleanupEND-.LcleanupSTART
+	.uleb128 sem_wait_cleanup-.LSTARTCODE
+	.uleb128  0
+	.uleb128 .LcallUR-.LSTARTCODE
+	.uleb128 .LENDCODE-.LcallUR
+	.uleb128 0
+	.uleb128  0
+.Lcstend:
+
+
+	.section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+	.long	.LENDCIE-.LSTARTCIE		# Length of the CIE.
+.LSTARTCIE:
+	.long	0				# CIE ID.
+	.byte	1				# Version number.
+#ifdef SHARED
+	.string	"zPLR"				# NUL-terminated augmentation
+						# string.
+#else
+	.string	"zPL"				# NUL-terminated augmentation
+						# string.
+#endif
+	.uleb128 1				# Code alignment factor.
+	.sleb128 -4				# Data alignment factor.
+	.byte	8				# Return address register
+						# column.
+#ifdef SHARED
+	.uleb128 7				# Augmentation value length.
+	.byte	0x9b				# Personality: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4
+						# + DW_EH_PE_indirect
+	.long	DW.ref.__gcc_personality_v0-.
+	.byte	0x1b				# LSDA Encoding: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4.
+	.byte	0x1b				# FDE Encoding: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4.
+#else
+	.uleb128 6				# Augmentation value length.
+	.byte	0x0				# Personality: absolute
+	.long	__gcc_personality_v0
+	.byte	0x0				# LSDA Encoding: absolute
+#endif
+	.byte 0x0c				# DW_CFA_def_cfa
+	.uleb128 4
+	.uleb128 4
+	.byte	0x88				# DW_CFA_offset, column 0x10
+	.uleb128 1
+	.align 4
+.LENDCIE:
+
+	.long	.LENDFDE-.LSTARTFDE		# Length of the FDE.
+.LSTARTFDE:
+	.long	.LSTARTFDE-.LSTARTFRAME		# CIE pointer.
+#ifdef SHARED
+	.long	.LSTARTCODE-.			# PC-relative start address
+						# of the code.
+#else
+	.long	.LSTARTCODE			# Start address of the code.
+#endif
+	.long	.LENDCODE-.LSTARTCODE		# Length of the code.
+	.uleb128 4				# Augmentation size
+#ifdef SHARED
+	.long	.LexceptSTART-.
+#else
+	.long	.LexceptSTART
+#endif
 
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpush_ebx-.LSTARTCODE
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 8
+	.byte   0x83				# DW_CFA_offset %ebx
+        .uleb128 2
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpush_esi-.Lpush_ebx
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 12
+	.byte   0x86				# DW_CFA_offset %esi
+        .uleb128 3
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lsub_esp-.Lpush_esi
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 16
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Ladd_esp-.Lsub_esp
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 4
+	.byte	0xc3				# DW_CFA_restore %ebx
+	.byte	0xc6				# DW_CFA_restore %esi
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lafter_ret-.Ladd_esp
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 16
+	.byte   0x83				# DW_CFA_offset %ebx
+        .uleb128 2
+	.byte   0x86				# DW_CFA_offset %esi
+        .uleb128 3
+	.align	4
+.LENDFDE:
+
+
+#ifdef SHARED
+	.hidden	DW.ref.__gcc_personality_v0
+	.weak	DW.ref.__gcc_personality_v0
+	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+	.align	4
+	.type	DW.ref.__gcc_personality_v0, @object
+	.size	DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+	.long	__gcc_personality_v0
+#endif
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+	.section ".text.compat", "ax"
+	.global	__old_sem_wait
+	.type	__old_sem_wait,@function
+	.align	16
+	cfi_startproc
+__old_sem_wait:
 	pushl	%ebx
 	cfi_adjust_cfa_offset(4)
 	pushl	%esi
@@ -52,9 +292,9 @@ __new_sem_wait:
 	cfi_adjust_cfa_offset(4)
 
 	movl	16(%esp), %ebx
-	cfi_offset(3, -8)		/* %ebx */
+	cfi_offset(ebx, -8)
 
-	cfi_offset(6, -12)		/* %esi */
+	cfi_offset(esi, -12)
 3:	movl	(%ebx), %eax
 2:	testl	%eax, %eax
 	je	1f
@@ -65,17 +305,17 @@ __new_sem_wait:
 	jne	2b
 	xorl	%eax, %eax
 
-	movl	4(%esp), %esi
-	cfi_restore(6)
+5:	movl	4(%esp), %esi
 	movl	8(%esp), %ebx
-	cfi_restore(3)
 	addl	$12, %esp
+	cfi_restore(ebx)
+	cfi_restore(esi)
 	cfi_adjust_cfa_offset(-12)
 	ret
 
 	cfi_adjust_cfa_offset(12)
-	cfi_offset(3, -8)		/* %ebx */
-	cfi_offset(6, -12)		/* %esi */
+	cfi_offset(ebx, -8)
+	cfi_offset(esi, -12)
 1:	call	__pthread_enable_asynccancel
 	movl	%eax, (%esp)
 
@@ -115,25 +355,8 @@ __new_sem_wait:
 	movl	%esi, (%eax)
 #endif
 	orl	$-1, %eax
-	movl	4(%esp), %esi
-	cfi_restore(6)
-	movl	8(%esp), %ebx
-	cfi_restore(3)
-	addl	$12, %esp
-	cfi_adjust_cfa_offset(-12)
-	ret
-
-5:	/* Canceled.  */
-	movl	$0xffffffff, %gs:RESULT
-	LOCK
-	orl	$0x10, %gs:CANCELHANDLING
-	movl	%gs:CLEANUP_JMP_BUF, %eax
-	jmp	HIDDEN_JUMPTARGET (__pthread_unwind)
+	jmp	5b
 	cfi_endproc
-	.size	__new_sem_wait,.-__new_sem_wait
-	versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
-	.global	__old_sem_wait
-__old_sem_wait = __new_sem_wait
+	.size	__old_sem_wait,.-__old_sem_wait
 	compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0)
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
index 21de09fe91..56f63a4623 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -23,6 +23,8 @@
 #include <time.h>
 #include <sys/param.h>
 #include <bits/pthreadtypes.h>
+#include <kernel-features.h>
+#include <tcb-offsets.h>
 
 #ifndef LOCK_INSTR
 # ifdef UP
@@ -38,6 +40,41 @@
 #define FUTEX_LOCK_PI		6
 #define FUTEX_UNLOCK_PI		7
 #define FUTEX_TRYLOCK_PI	8
+#define FUTEX_PRIVATE_FLAG	128
+
+
+/* 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))								      \
+   : ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG);		      \
+	asm ("andl %%fs:%P1, %0" : "+r" (__fl)				      \
+	     : "i" (offsetof (struct pthread, header.private_futex)));	      \
+	__fl | (fl); }))
+# endif	      
+#endif
 
 
 /* Initializer for compatibility lock.  */
@@ -144,23 +181,11 @@ LLL_STUB_UNWIND_INFO_START					\
 LLL_STUB_UNWIND_INFO_END
 
 
-#define lll_futex_wait(futex, val) \
-  ({									      \
-    int __status;							      \
-    register __typeof (val) _val asm ("edx") = (val);			      \
-    __asm __volatile (LLL_EBX_LOAD					      \
-		      LLL_ENTER_KERNEL					      \
-		      LLL_EBX_LOAD					      \
-		      : "=a" (__status)					      \
-		      : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (0),	      \
-			"c" (FUTEX_WAIT), "d" (_val),			      \
-			"i" (offsetof (tcbhead_t, sysinfo))		      \
-		      : "memory");					      \
-    __status;								      \
-  })
+#define lll_futex_wait(futex, val, private) \
+  lll_futex_timed_wait (futex, val, NULL, private)
 
 
-#define lll_futex_timed_wait(futex, val, timeout)			      \
+#define lll_futex_timed_wait(futex, val, timeout, private) \
   ({									      \
     int __status;							      \
     register __typeof (val) _val asm ("edx") = (val);			      \
@@ -169,14 +194,14 @@ LLL_STUB_UNWIND_INFO_END
 		      LLL_EBX_LOAD					      \
 		      : "=a" (__status)					      \
 		      : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (timeout),  \
-			"c" (FUTEX_WAIT), "d" (_val),			      \
-			"i" (offsetof (tcbhead_t, sysinfo))		      \
+			"c" (__lll_private_flag (FUTEX_WAIT, private)),	      \
+			"d" (_val), "i" (offsetof (tcbhead_t, sysinfo))	      \
 		      : "memory");					      \
     __status;								      \
   })
 
 
-#define lll_futex_wake(futex, nr) \
+#define lll_futex_wake(futex, nr, private) \
   do {									      \
     int __ignore;							      \
     register __typeof (nr) _nr asm ("edx") = (nr);			      \
@@ -185,7 +210,8 @@ LLL_STUB_UNWIND_INFO_END
 		      LLL_EBX_LOAD					      \
 		      : "=a" (__ignore)					      \
 		      : "0" (SYS_futex), LLL_EBX_REG (futex),		      \
-			"c" (FUTEX_WAKE), "d" (_nr),			      \
+			"c" (__lll_private_flag (FUTEX_WAKE, private)),	      \
+			"d" (_nr),					      \
 			"i" (0) /* phony, to align next arg's number */,      \
 			"i" (offsetof (tcbhead_t, sysinfo)));		      \
   } while (0)
@@ -414,21 +440,6 @@ extern int __lll_mutex_unlock_wake (int *__futex)
 				"i" (offsetof (tcbhead_t, sysinfo))); })
 
 
-#define lll_futex_wake(futex, nr) \
-  do {									      \
-    int __ignore;							      \
-    register __typeof (nr) _nr asm ("edx") = (nr);			      \
-    __asm __volatile (LLL_EBX_LOAD					      \
-		      LLL_ENTER_KERNEL					      \
-		      LLL_EBX_LOAD					      \
-		      : "=a" (__ignore)					      \
-		      : "0" (SYS_futex), LLL_EBX_REG (futex),		      \
-			"c" (FUTEX_WAKE), "d" (_nr),			      \
-			"i" (0) /* phony, to align next arg's number */,      \
-			"i" (offsetof (tcbhead_t, sysinfo)));		      \
-  } while (0)
-
-
 #define lll_mutex_islocked(futex) \
   (futex != 0)
 
@@ -448,7 +459,6 @@ extern int __lll_lock_wait (int val, int *__futex)
      __attribute ((regparm (2))) attribute_hidden;
 extern int __lll_unlock_wake (int *__futex)
      __attribute ((regparm (1))) attribute_hidden;
-extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
 
 
 /* The states of a lock are:
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S
index 312933c5e4..8ff0dad27f 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -19,6 +19,8 @@
 
 #include <unwindbuf.h>
 #include <sysdep.h>
+#include <kernel-features.h>
+
 
 #ifndef UP
 # define LOCK lock
@@ -26,8 +28,10 @@
 # define LOCK
 #endif
 
-#define SYS_futex	240
-#define FUTEX_WAKE	1
+#define SYS_futex		240
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 	.comm	__fork_generation, 4, 4
 
@@ -90,7 +94,16 @@ __pthread_once:
 	jnz	3f	/* Different for generation -> run initializer.  */
 
 	/* Somebody else got here first.  Wait.  */
-	movl	%esi, %ecx		/* movl $FUTEX_WAIT, %ecx */
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_WAIT|FUTEX_PRIVATE_FLAG, %ecx
+#else
+# if FUTEX_WAIT == 0
+	movl	%gs:PRIVATE_FUTEX, %ecx
+# else
+	movl	$FUTEX_WAIT, %ecx
+	orl	%gs:PRIVATE_FUTEX, %ecx
+# endif
+#endif
 	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 	jmp	6b
@@ -131,7 +144,12 @@ __pthread_once:
 
 	/* Wake up all other threads.  */
 	movl	$0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %ecx
+#else
 	movl	$FUTEX_WAKE, %ecx
+	orl	%gs:PRIVATE_FUTEX, %ecx
+#endif
 	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 
@@ -152,7 +170,12 @@ __pthread_once:
 	movl	$0, (%ebx)
 
 	movl	$0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %ecx
+#else
 	movl	$FUTEX_WAKE, %ecx
+	orl	%gs:PRIVATE_FUTEX, %ecx
+#endif
 	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
index 8df997a262..095f0e8aca 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -36,6 +36,39 @@
 #define FUTEX_LOCK_PI		6
 #define FUTEX_UNLOCK_PI		7
 #define FUTEX_TRYLOCK_PI	8
+#define FUTEX_PRIVATE_FLAG	128
+
+/* 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
+
 
 /* Delay in spinlock loop.  */
 #define BUSY_WAIT_NOP          asm ("hint @pause")
@@ -43,18 +76,22 @@
 /* Initializer for compatibility lock.	*/
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
 
-#define lll_futex_wait(futex, val) lll_futex_timed_wait (futex, val, 0)
+#define lll_futex_wait(futex, val, private) \
+  lll_futex_timed_wait (futex, val, NULL, private)
 
-#define lll_futex_timed_wait(ftx, val, timespec)			\
+#define lll_futex_timed_wait(ftx, val, timespec, private)		\
 ({									\
-   DO_INLINE_SYSCALL(futex, 4, (long) (ftx), FUTEX_WAIT, (int) (val),	\
-		     (long) (timespec));				\
+   DO_INLINE_SYSCALL(futex, 4, (long) (ftx),				\
+		     __lll_private_flag (FUTEX_WAIT, private),		\
+		     (int) (val), (long) (timespec));			\
    _r10 == -1 ? -_retval : _retval;					\
 })
 
-#define lll_futex_wake(ftx, nr)						\
+#define lll_futex_wake(ftx, nr, private)				\
 ({									\
-   DO_INLINE_SYSCALL(futex, 3, (long) (ftx), FUTEX_WAKE, (int) (nr));	\
+   DO_INLINE_SYSCALL(futex, 3, (long) (ftx),				\
+		     __lll_private_flag (FUTEX_WAKE, private),		\
+		     (int) (nr));					\
    _r10 == -1 ? -_retval : _retval;					\
 })
 
@@ -188,7 +225,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
     int __val = atomic_exchange_rel (__futex, 0);	\
 							\
     if (__builtin_expect (__val > 1, 0))		\
-      lll_futex_wake (__futex, 1);			\
+      lll_futex_wake (__futex, 1, LLL_SHARED);		\
   }))
 #define lll_mutex_unlock(futex) \
   __lll_mutex_unlock(&(futex))
@@ -200,7 +237,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
     int __val = atomic_exchange_rel (__futex, 0);	\
 							\
     if (__builtin_expect (__val & FUTEX_WAITERS, 0))	\
-      lll_futex_wake (__futex, 1);			\
+      lll_futex_wake (__futex, 1, LLL_SHARED);		\
   }))
 #define lll_robust_mutex_unlock(futex) \
   __lll_robust_mutex_unlock(&(futex))
@@ -210,7 +247,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
   ((void) ({					\
     int *__futex = (futex);			\
     (void) atomic_exchange_rel (__futex, 0);	\
-    lll_futex_wake (__futex, 1);		\
+    lll_futex_wake (__futex, 1, LLL_SHARED);	\
   }))
 #define lll_mutex_unlock_force(futex) \
   __lll_mutex_unlock_force(&(futex))
@@ -226,8 +263,6 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
 /* Type for lock object.  */
 typedef int lll_lock_t;
 
-extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
-
 /* Initializers for lock.  */
 #define LLL_LOCK_INITIALIZER		(0)
 #define LLL_LOCK_INITIALIZER_LOCKED	(1)
@@ -243,12 +278,12 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
    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 *)
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c
index 3b07cc127d..22e2dd3c0c 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/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.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -30,7 +30,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);
 }
 
 
@@ -65,7 +65,7 @@ __pthread_once (once_control, init_routine)
 	  if (((oldval ^ newval) & -4) == 0)
 	    {
 	      /* Same generation, some other thread was faster. Wait.  */
-	      lll_futex_wait (once_control, newval);
+	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
 	      continue;
 	    }
 	}
@@ -84,7 +84,7 @@ __pthread_once (once_control, init_routine)
       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);
       break;
     }
 
diff --git a/nptl/sysdeps/unix/sysv/linux/internaltypes.h b/nptl/sysdeps/unix/sysv/linux/internaltypes.h
index 1dec19e57d..add20b6f72 100644
--- a/nptl/sysdeps/unix/sysv/linux/internaltypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/internaltypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -76,9 +76,11 @@ struct pthread_condattr
 
 
 /* The __NWAITERS field is used as a counter and to house the number
-   of bits which represent the clock.  COND_CLOCK_BITS is the number
-   of bits reserved for the clock.  */
-#define COND_CLOCK_BITS	1
+   of bits for other purposes.  COND_CLOCK_BITS is the number
+   of bits needed to represent the ID of the clock.  COND_NWAITERS_SHIFT
+   is the number of bits reserved for other purposes like the clock.  */
+#define COND_CLOCK_BITS		1
+#define COND_NWAITERS_SHIFT	1
 
 
 /* Read-write lock variable attribute data structure.  */
@@ -96,6 +98,7 @@ struct pthread_barrier
   int lock;
   unsigned int left;
   unsigned int init_count;
+  int private;
 };
 
 
@@ -137,9 +140,16 @@ struct pthread_key_struct
 
 
 /* Semaphore variable structure.  */
-struct sem
+struct new_sem
 {
-  unsigned int count;
+  unsigned int value;
+  int private;
+  unsigned long int nwaiters;
+};
+
+struct old_sem
+{
+  unsigned int value;
 };
 
 
diff --git a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
index 92a188a2f3..4b614bd1a6 100644
--- a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
+++ b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
@@ -26,6 +26,7 @@
 #include <pthreadP.h>
 #include <bits/libc-lock.h>
 #include <sysdep.h>
+#include <ldsodefs.h>
 
 
 #ifdef TLS_MULTIPLE_THREADS_IN_TCB
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym b/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym
index 36e28eb2a6..cfe22b0892 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym
@@ -9,3 +9,4 @@ CURR_EVENT		offsetof (struct pthread_barrier, curr_event)
 MUTEX			offsetof (struct pthread_barrier, lock)
 LEFT			offsetof (struct pthread_barrier, left)
 INIT_COUNT		offsetof (struct pthread_barrier, init_count)
+PRIVATE			offsetof (struct pthread_barrier, private)
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym b/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym
index c5e7978069..18e1adad43 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym
@@ -13,4 +13,4 @@ wakeup_seq	offsetof (pthread_cond_t, __data.__wakeup_seq)
 woken_seq	offsetof (pthread_cond_t, __data.__woken_seq)
 dep_mutex	offsetof (pthread_cond_t, __data.__mutex)
 broadcast_seq	offsetof (pthread_cond_t, __data.__broadcast_seq)
-clock_bits	COND_CLOCK_BITS
+nwaiters_shift	COND_NWAITERS_SHIFT
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
index 932e27300f..ab7f605f0c 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
@@ -1,5 +1,5 @@
 /* low level locking for pthread library.  Generic futex-using version.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
 
@@ -31,7 +31,9 @@ __lll_lock_wait (int *futex)
     {
       int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1);
       if (oldval != 0)
-	lll_futex_wait (futex, 2);
+	lll_futex_wait (futex, 2,
+			// XYZ check mutex flag
+			LLL_SHARED);
     }
   while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0);
 }
@@ -68,7 +70,9 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime)
       /* Wait.  */
       int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1);
       if (oldval != 0)
-	lll_futex_timed_wait (futex, 2, &rt);
+	lll_futex_timed_wait (futex, 2, &rt,
+			      // XYZ check mutex flag
+			      LLL_SHARED);
     }
   while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0);
 
@@ -76,21 +80,9 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime)
 }
 
 
-/* These don't get included in libc.so  */
+/* This function doesn'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);
-
-  return 0;
-}
-
-
-int
 __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
 {
   int tid;
@@ -120,12 +112,12 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
       if (rt.tv_sec < 0)
 	return ETIMEDOUT;
 
-      /* Wait until thread terminates.  */
-      if (lll_futex_timed_wait (tidp, tid, &rt) == -ETIMEDOUT)
+      /* Wait until thread terminates.  The kernel so far does not use
+	 the private futex operations for this.  */
+      if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
 	return ETIMEDOUT;
     }
 
   return 0;
 }
-
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
index 30ef991bd0..54cee0859b 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
@@ -44,7 +44,9 @@ __lll_robust_lock_wait (int *futex)
 	  && atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
 	continue;
 
-      lll_futex_wait (futex, newval);
+      lll_futex_wait (futex, newval,
+		      // XYZ check mutex flag
+		      LLL_SHARED);
 
     try:
       ;
@@ -100,7 +102,9 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
 	  && atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
 	continue;
 
-      lll_futex_timed_wait (futex, newval, &rt);
+      lll_futex_timed_wait (futex, newval, &rt,
+			    // XYZ check mutex flag
+			    LLL_SHARED);
 
     try:
       ;
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym b/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym
index e82c878d39..f50b25bfb8 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym
@@ -1,6 +1,7 @@
 #include <stddef.h>
 #include <stdio.h>
 #include <bits/pthreadtypes.h>
+#include <bits/wordsize.h>
 
 --
 
@@ -12,3 +13,4 @@ READERS_QUEUED	offsetof (pthread_rwlock_t, __data.__nr_readers_queued)
 WRITERS_QUEUED	offsetof (pthread_rwlock_t, __data.__nr_writers_queued)
 FLAGS		offsetof (pthread_rwlock_t, __data.__flags)
 WRITER		offsetof (pthread_rwlock_t, __data.__writer)
+PSHARED		offsetof (pthread_rwlock_t, __data.__shared)
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
index a7150f6aef..c0b59c336f 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
@@ -1,5 +1,5 @@
 /* Machine-specific pthread type layouts.  PowerPC version.
-   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
 
@@ -160,9 +160,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;
@@ -176,9 +176,12 @@ typedef union
     unsigned int __writer_wakeup;
     unsigned int __nr_readers_queued;
     unsigned int __nr_writers_queued;
+    unsigned char __pad1;
+    unsigned char __pad2;
+    unsigned char __shared;
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
-    unsigned int __flags;
+    unsigned char __flags;
     int __writer;
   } __data;
 # endif
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
index 239f4ddf55..cf91f21483 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
@@ -37,37 +37,63 @@
 #define FUTEX_LOCK_PI		6
 #define FUTEX_UNLOCK_PI		7
 #define FUTEX_TRYLOCK_PI	8
+#define FUTEX_PRIVATE_FLAG	128
+
+/* 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);		      \
-    INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __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));			      \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __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);					      \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret;		      \
   })
 
@@ -95,18 +121,19 @@
   })
 
 /* 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);		      \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
   })
-
+  
+  
 #ifdef UP
 # define __lll_acq_instr	""
 # define __lll_rel_instr	""
@@ -228,7 +255,7 @@ extern int __lll_robust_timedlock_wait
     int *__futex = &(lock);						      \
     int __val = atomic_exchange_rel (__futex, 0);			      \
     if (__builtin_expect (__val > 1, 0))				      \
-      lll_futex_wake (__futex, 1);					      \
+      lll_futex_wake (__futex, 1, LLL_SHARED);				      \
   }))
 
 #define lll_robust_mutex_unlock(lock) \
@@ -236,7 +263,7 @@ extern int __lll_robust_timedlock_wait
     int *__futex = &(lock);						      \
     int __val = atomic_exchange_rel (__futex, 0);			      \
     if (__builtin_expect (__val & FUTEX_WAITERS, 0))			      \
-      lll_futex_wake (__futex, 1);					      \
+      lll_futex_wake (__futex, 1, LLL_SHARED);				      \
   }))
 
 #define lll_mutex_unlock_force(lock) \
@@ -244,7 +271,7 @@ extern int __lll_robust_timedlock_wait
     int *__futex = &(lock);						      \
     *__futex = 0;							      \
     __asm __volatile (__lll_rel_instr ::: "memory");			      \
-    lll_futex_wake (__futex, 1);					      \
+    lll_futex_wake (__futex, 1, LLL_SHARED);				      \
   }))
 
 #define lll_mutex_islocked(futex) \
@@ -261,8 +288,6 @@ typedef int lll_lock_t;
 #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
@@ -281,7 +306,7 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
   do {									      \
     __typeof (tid) __tid;						      \
     while ((__tid = (tid)) != 0)					      \
-      lll_futex_wait (&(tid), __tid);					      \
+      lll_futex_wait (&(tid), __tid, LLL_SHARED);			      \
   } while (0)
 
 extern int __lll_timedwait_tid (int *, const struct timespec *)
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c
index 9472dd17ef..6fedac1b33 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c
@@ -1,3 +1,4 @@
+#include <unistd.h>	/* For __getpagesize.  */
 #define NEW_VERNUM GLIBC_2_6
 #define STACKSIZE_ADJUST \
   do {									      \
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
index e1afff8a38..969078094d 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/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.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
 
@@ -30,7 +30,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);
 }
 
 
@@ -74,7 +74,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);
     }
 
 
@@ -92,7 +92,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/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c b/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c
index 91b9955181..0b18cdbcde 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c
@@ -1,5 +1,5 @@
 /* sem_post -- post to a POSIX semaphore.  Powerpc version.
-   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.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
 
@@ -33,7 +33,7 @@ __new_sem_post (sem_t *sem)
 
   __asm __volatile (__lll_rel_instr ::: "memory");
   int nr = atomic_increment_val (futex);
-  int err = lll_futex_wake (futex, nr);
+  int err = lll_futex_wake (futex, nr, LLL_SHARED);
   if (__builtin_expect (err, 0) < 0)
     {
       __set_errno (-err);
diff --git a/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h b/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
index 6b3d3682da..4a49925588 100644
--- a/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
+++ b/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
@@ -1,5 +1,5 @@
 /* Defintions for lowlevel handling in ld.so.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 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,115 +24,6 @@
 #include <lowlevellock.h>
 
 
-/* Special multi-reader lock used in ld.so.  */
-#define __RTLD_MRLOCK_WRITER 1
-#define __RTLD_MRLOCK_RWAIT 2
-#define __RTLD_MRLOCK_WWAIT 4
-#define __RTLD_MRLOCK_RBITS \
-  ~(__RTLD_MRLOCK_WRITER | __RTLD_MRLOCK_RWAIT | __RTLD_MRLOCK_WWAIT)
-#define __RTLD_MRLOCK_INC 8
-#define __RTLD_MRLOCK_TRIES 5
-
-
-typedef int __rtld_mrlock_t;
-
-
-#define __rtld_mrlock_define(CLASS,NAME) \
-  CLASS __rtld_mrlock_t NAME;
-
-
-#define _RTLD_MRLOCK_INITIALIZER 0
-#define __rtld_mrlock_initialize(NAME) \
-  (void) ((NAME) = 0)
-
-
-#define __rtld_mrlock_lock(lock) \
-  do {									      \
-    __label__ out;							      \
-    while (1)								      \
-      {									      \
-	int oldval;							      \
-	for (int tries = 0; tries < __RTLD_MRLOCK_TRIES; ++tries)	      \
-	  {								      \
-	    oldval = lock;						      \
-	    while (__builtin_expect ((oldval				      \
-				      & (__RTLD_MRLOCK_WRITER		      \
-					 | __RTLD_MRLOCK_WWAIT))	      \
-				     == 0, 1))				      \
-	      {								      \
-		int newval = ((oldval & __RTLD_MRLOCK_RBITS)		      \
-			      + __RTLD_MRLOCK_INC);			      \
-		int ret = atomic_compare_and_exchange_val_acq (&(lock),	      \
-							       newval,	      \
-							       oldval);	      \
-		if (__builtin_expect (ret == oldval, 1))		      \
-		  goto out;						      \
-		oldval = ret;						      \
-	      }								      \
-	    atomic_delay ();						      \
-	  }								      \
-	if ((oldval & __RTLD_MRLOCK_RWAIT) == 0)			      \
-	  {								      \
-	    atomic_or (&(lock), __RTLD_MRLOCK_RWAIT);			      \
-	    oldval |= __RTLD_MRLOCK_RWAIT;				      \
-	  }								      \
-	lll_futex_wait (lock, oldval);					      \
-      }									      \
-  out:;									      \
-  } while (0)
-
-
-#define __rtld_mrlock_unlock(lock) \
-  do {									      \
-    int oldval = atomic_exchange_and_add (&(lock), -__RTLD_MRLOCK_INC);	      \
-    if (__builtin_expect ((oldval					      \
-			   & (__RTLD_MRLOCK_RBITS | __RTLD_MRLOCK_WWAIT))     \
-			  == (__RTLD_MRLOCK_INC | __RTLD_MRLOCK_WWAIT), 0))   \
-      /* We have to wake all threads since there might be some queued	      \
-	 readers already.  */						      \
-      lll_futex_wake (&(lock), 0x7fffffff);				      \
-  } while (0)
-
-
-/* There can only ever be one thread trying to get the exclusive lock.  */
-#define __rtld_mrlock_change(lock) \
-  do {									      \
-    __label__ out;							      \
-    while (1)								      \
-      {									      \
-	int oldval;							      \
-	for (int tries = 0; tries < __RTLD_MRLOCK_TRIES; ++tries)	      \
-	  {								      \
-	    oldval = lock;						      \
-	    while (__builtin_expect ((oldval & __RTLD_MRLOCK_RBITS) == 0, 1)) \
-	      {								      \
-		int newval = ((oldval & __RTLD_MRLOCK_RWAIT)		      \
-			      + __RTLD_MRLOCK_WRITER);			      \
-		int ret = atomic_compare_and_exchange_val_acq (&(lock),	      \
-							       newval,	      \
-							       oldval);	      \
-		if (__builtin_expect (ret == oldval, 1))		      \
-		  goto out;						      \
-		oldval = ret;						      \
-	      }								      \
-	    atomic_delay ();						      \
-	  }								      \
-	atomic_or (&(lock), __RTLD_MRLOCK_WWAIT);			      \
-	oldval |= __RTLD_MRLOCK_WWAIT;					      \
-	lll_futex_wait (lock, oldval);					      \
-      }									      \
-  out:;									      \
-  } while (0)
-
-
-#define __rtld_mrlock_done(lock) \
-  do {				 \
-    int oldval = atomic_exchange_and_add (&(lock), -__RTLD_MRLOCK_WRITER);    \
-    if (__builtin_expect ((oldval & __RTLD_MRLOCK_RWAIT) != 0, 0))	      \
-      lll_futex_wake (&(lock), 0x7fffffff);				      \
-  } while (0)
-
-
 /* Function to wait for variable become zero.  Used in ld.so for
    reference counters.  */
 #define __rtld_waitzero(word) \
@@ -142,12 +33,12 @@ typedef int __rtld_mrlock_t;
 	int val = word;							      \
 	if (val == 0)							      \
 	  break;							      \
-	lll_futex_wait (&(word), val);					      \
+	lll_futex_wait (&(word), val, LLL_PRIVATE);			      \
       }									      \
   } while (0)
 
 
 #define __rtld_notify(word) \
-  lll_futex_wake (&(word), 1)
+  lll_futex_wake (&(word), 1, LLL_PRIVATE)
 
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
index 38d9f2ac41..4758b63bd0 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -35,31 +35,50 @@
 #define FUTEX_LOCK_PI		6
 #define FUTEX_UNLOCK_PI		7
 #define FUTEX_TRYLOCK_PI	8
+#define FUTEX_PRIVATE_FLAG	128
+
+/* 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(futex, val) \
-  ({									      \
-     register unsigned long int __r2 asm ("2") = (unsigned long int) (futex); \
-     register unsigned long int __r3 asm ("3") = FUTEX_WAIT;		      \
-     register unsigned long int __r4 asm ("4") = (unsigned long int) (val);   \
-     register unsigned long int __r5 asm ("5") = 0ul;			      \
-     register unsigned long __result asm ("2");				      \
-									      \
-    __asm __volatile ("svc %b1"						      \
-		      : "=d" (__result)					      \
-		      : "i" (SYS_futex), "0" (__r2), "d" (__r3),	      \
-			"d" (__r4), "d" (__r5)				      \
-		      : "cc", "memory" );				      \
-    __result;								      \
-  })
+#define lll_futex_wait(futex, val, private) \
+  lll_futex_timed_wait (futex, val, NULL, private)
 
-
-#define lll_futex_timed_wait(futex, val, timespec) \
+#define lll_futex_timed_wait(futex, val, timespec, private) \
   ({									      \
     register unsigned long int __r2 asm ("2") = (unsigned long int) (futex);  \
-    register unsigned long int __r3 asm ("3") = FUTEX_WAIT;		      \
+    register unsigned long int __r3 asm ("3")				      \
+      = __lll_private_flag (FUTEX_WAIT, private);			      \
     register unsigned long int __r4 asm ("4") = (unsigned long int) (val);    \
     register unsigned long int __r5 asm ("5") = (unsigned long int)(timespec);\
     register unsigned long int __result asm ("2");			      \
@@ -73,10 +92,11 @@
   })
 
 
-#define lll_futex_wake(futex, nr) \
+#define lll_futex_wake(futex, nr, private) \
   ({									      \
     register unsigned long int __r2 asm ("2") = (unsigned long int) (futex);  \
-    register unsigned long int __r3 asm ("3") = FUTEX_WAKE;		      \
+    register unsigned long int __r3 asm ("3")				      \
+      __lll_private_flag (FUTEX_WAKE, private);				      \
     register unsigned long int __r4 asm ("4") = (unsigned long int) (nr);     \
     register unsigned long int __result asm ("2");			      \
 									      \
@@ -94,7 +114,7 @@
       int *__futexp = &(futexv);					      \
 									      \
       atomic_or (__futexp, FUTEX_OWNER_DIED);				      \
-      lll_futex_wake (__futexp, 1);					      \
+      lll_futex_wake (__futexp, 1, LLL_SHARED);				      \
     }									      \
   while (0)
 
@@ -271,7 +291,7 @@ __lll_mutex_unlock (int *futex)
 
   lll_compare_and_swap (futex, oldval, newval, "slr %2,%2");
   if (oldval > 1)
-    lll_futex_wake (futex, 1);
+    lll_futex_wake (futex, 1, LLL_SHARED);
 }
 #define lll_mutex_unlock(futex) \
   __lll_mutex_unlock(&(futex))
@@ -286,7 +306,7 @@ __lll_robust_mutex_unlock (int *futex, int mask)
 
   lll_compare_and_swap (futex, oldval, newval, "slr %2,%2");
   if (oldval & mask)
-    lll_futex_wake (futex, 1);
+    lll_futex_wake (futex, 1, LLL_SHARED);
 }
 #define lll_robust_mutex_unlock(futex) \
   __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS)
@@ -297,7 +317,7 @@ __attribute__ ((always_inline))
 __lll_mutex_unlock_force (int *futex)
 {
   *futex = 0;
-  lll_futex_wake (futex, 1);
+  lll_futex_wake (futex, 1, LLL_SHARED);
 }
 #define lll_mutex_unlock_force(futex) \
   __lll_mutex_unlock_force(&(futex))
@@ -321,8 +341,6 @@ typedef int lll_lock_t;
 #define lll_unlock(futex)       lll_mutex_unlock (futex)
 #define lll_islocked(futex)     lll_mutex_islocked (futex)
 
-extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
-
 /* The states of a lock are:
     1  -  untaken
     0  -  taken by one user
@@ -340,7 +358,7 @@ __lll_wait_tid (int *ptid)
   int tid;
 
   while ((tid = *ptid) != 0)
-    lll_futex_wait (ptid, tid);
+    lll_futex_wait (ptid, tid, LLL_SHARED);
 }
 #define lll_wait_tid(tid) __lll_wait_tid(&(tid))
 
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c
index f29e23fd4b..0012e9ae27 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -30,7 +30,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);
 }
 
 
@@ -76,7 +76,7 @@ __pthread_once (once_control, init_routine)
 	  if (((oldval ^ newval) & -4) == 0)
 	    {
 	      /* Same generation, some other thread was faster. Wait.  */
-	      lll_futex_wait (once_control, newval);
+	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
 	      continue;
 	    }
 	}
@@ -101,7 +101,7 @@ __pthread_once (once_control, init_routine)
 			: "m" (*once_control) : "cc" );
 
       /* Wake up all other threads.  */
-      lll_futex_wake (once_control, INT_MAX);
+      lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
       break;
     }
 
diff --git a/nptl/sysdeps/unix/sysv/linux/sem_post.c b/nptl/sysdeps/unix/sysv/linux/sem_post.c
index 671b43f7f7..7f90325585 100644
--- a/nptl/sysdeps/unix/sysv/linux/sem_post.c
+++ b/nptl/sysdeps/unix/sysv/linux/sem_post.c
@@ -1,5 +1,5 @@
 /* sem_post -- post to a POSIX semaphore.  Generic futex-using version.
-   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.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -29,10 +29,36 @@
 int
 __new_sem_post (sem_t *sem)
 {
+  struct new_sem *isem = (struct new_sem *) sem;
+
+  int nr = atomic_increment_val (&isem->value);
+  atomic_full_barrier ();
+  if (isem->nwaiters > 0)
+    {
+      int err = lll_futex_wake (&isem->value, 1,
+				// XYZ check mutex flag
+				LLL_SHARED);
+      if (__builtin_expect (err, 0) < 0)
+	{
+	  __set_errno (-err);
+	  return -1;
+	}
+    }
+  return 0;
+}
+versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
+
+
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
+int
+attribute_compat_text_section
+__old_sem_post (sem_t *sem)
+{
   int *futex = (int *) sem;
 
   int nr = atomic_increment_val (futex);
-  int err = lll_futex_wake (futex, nr);
+  /* We always have to assume it is a shared semaphore.  */
+  int err = lll_futex_wake (futex, 1, LLL_SHARED);
   if (__builtin_expect (err, 0) < 0)
     {
       __set_errno (-err);
@@ -40,8 +66,5 @@ __new_sem_post (sem_t *sem)
     }
   return 0;
 }
-versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_post, __old_sem_post)
 compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0);
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c b/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
index ef897c1e93..8f92d78abe 100644
--- a/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
+++ b/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
@@ -1,5 +1,5 @@
 /* sem_timedwait -- wait on a semaphore.  Generic futex-using version.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
 
@@ -28,28 +28,29 @@
 #include <shlib-compat.h>
 
 
+extern void __sem_wait_cleanup (void *arg) attribute_hidden;
+
+
 int
 sem_timedwait (sem_t *sem, const struct timespec *abstime)
 {
-  /* First check for cancellation.  */
-  CANCELLATION_P (THREAD_SELF);
-
-  int *futex = (int *) sem;
-  int val;
+  struct new_sem *isem = (struct new_sem *) sem;
   int err;
 
-  if (*futex > 0)
+  if (atomic_decrement_if_positive (&isem->value) > 0)
+    return 0;
+
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
     {
-      val = atomic_decrement_if_positive (futex);
-      if (val > 0)
-	return 0;
+      __set_errno (EINVAL);
+      return -1;
     }
 
-  err = -EINVAL;
-  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
-    goto error_return;
+  atomic_increment (&isem->nwaiters);
+
+  pthread_cleanup_push (__sem_wait_cleanup, isem);
 
-  do
+  while (1)
     {
       struct timeval tv;
       struct timespec rt;
@@ -70,7 +71,11 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
       /* Already timed out?  */
       err = -ETIMEDOUT;
       if (sec < 0)
-	goto error_return;
+	{
+	  __set_errno (ETIMEDOUT);
+	  err = -1;
+	  break;
+	}
 
       /* Do wait.  */
       rt.tv_sec = sec;
@@ -79,21 +84,30 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
       /* Enable asynchronous cancellation.  Required by the standard.  */
       int oldtype = __pthread_enable_asynccancel ();
 
-      err = lll_futex_timed_wait (futex, 0, &rt);
+      err = lll_futex_timed_wait (&isem->value, 0, &rt,
+				  // XYZ check mutex flag
+				  LLL_SHARED);
 
       /* Disable asynchronous cancellation.  */
       __pthread_disable_asynccancel (oldtype);
 
       if (err != 0 && err != -EWOULDBLOCK)
-	goto error_return;
+	{
+	  __set_errno (-err);
+	  err = -1;
+	  break;
+	}
 
-      val = atomic_decrement_if_positive (futex);
+      if (atomic_decrement_if_positive (&isem->value) > 0)
+	{
+	  err = 0;
+	  break;
+	}
     }
-  while (val <= 0);
 
-  return 0;
+  pthread_cleanup_pop (0);
+
+  atomic_decrement (&isem->nwaiters);
 
- error_return:
-  __set_errno (-err);
-  return -1;
+  return err;
 }
diff --git a/nptl/sysdeps/unix/sysv/linux/sem_wait.c b/nptl/sysdeps/unix/sysv/linux/sem_wait.c
index e6733e88a3..12f3f16c2d 100644
--- a/nptl/sysdeps/unix/sysv/linux/sem_wait.c
+++ b/nptl/sysdeps/unix/sysv/linux/sem_wait.c
@@ -1,5 +1,5 @@
 /* sem_wait -- wait on a semaphore.  Generic futex-using version.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
 
@@ -28,12 +28,69 @@
 #include <shlib-compat.h>
 
 
+void
+attribute_hidden
+__sem_wait_cleanup (void *arg)
+{
+  struct new_sem *isem = (struct new_sem *) arg;
+
+  atomic_decrement (&isem->nwaiters);
+}
+
+
 int
 __new_sem_wait (sem_t *sem)
 {
-  /* First check for cancellation.  */
-  CANCELLATION_P (THREAD_SELF);
+  struct new_sem *isem = (struct new_sem *) sem;
+  int err;
+
+  if (atomic_decrement_if_positive (&isem->value) > 0)
+    return 0;
+
+  atomic_increment (&isem->nwaiters);
 
+  pthread_cleanup_push (__sem_wait_cleanup, isem);
+
+  while (1)
+    {
+      /* Enable asynchronous cancellation.  Required by the standard.  */
+      int oldtype = __pthread_enable_asynccancel ();
+
+      err = lll_futex_wait (&isem->value, 0,
+			    // XYZ check mutex flag
+			    LLL_SHARED);
+
+      /* Disable asynchronous cancellation.  */
+      __pthread_disable_asynccancel (oldtype);
+
+      if (err != 0 && err != -EWOULDBLOCK)
+	{
+	  __set_errno (-err);
+	  err = -1;
+	  break;
+	}
+
+      if (atomic_decrement_if_positive (&isem->value) > 0)
+	{
+	  err = 0;
+	  break;
+	}
+    }
+
+  pthread_cleanup_pop (0);
+
+  atomic_decrement (&isem->nwaiters);
+
+  return err;
+}
+versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
+
+
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
+int
+attribute_compat_text_section
+__old_sem_wait (sem_t *sem)
+{
   int *futex = (int *) sem;
   int err;
 
@@ -45,7 +102,8 @@ __new_sem_wait (sem_t *sem)
       /* Enable asynchronous cancellation.  Required by the standard.  */
       int oldtype = __pthread_enable_asynccancel ();
 
-      err = lll_futex_wait (futex, 0);
+      /* Always assume the semaphore is shared.  */
+      err = lll_futex_wait (futex, 0, LLL_SHARED);
 
       /* Disable asynchronous cancellation.  */
       __pthread_disable_asynccancel (oldtype);
@@ -56,8 +114,5 @@ __new_sem_wait (sem_t *sem)
   return -1;
 }
 
-versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_wait, __old_sem_wait)
 compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
index 969686dd5a..badcda5701 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,6 +21,8 @@
 #ifndef _BITS_PTHREADTYPES_H
 #define _BITS_PTHREADTYPES_H	1
 
+#include <endian.h>
+
 #define __SIZEOF_PTHREAD_ATTR_T 36
 #define __SIZEOF_PTHREAD_MUTEX_T 24
 #define __SIZEOF_PTHREAD_MUTEXATTR_T 4
@@ -127,9 +130,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
     pthread_t __writer;
   } __data;
   char __size[__SIZEOF_PTHREAD_RWLOCK_T];
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S
index 94a24b46ee..be85ab7414 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 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
@@ -16,4 +16,32 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <kernel-features.h>
+
+/* All locks in libc are private.  Use the kernel feature if possible.  */
+#define FUTEX_PRIVATE_FLAG	128
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define FUTEX_WAIT		(0 | FUTEX_PRIVATE_FLAG)
+# define FUTEX_WAKE		(1 | FUTEX_PRIVATE_FLAG)
+#else
+# define LOAD_FUTEX_WAIT(reg,tmp) \
+	stc	gbr, tmp	; \
+	mov.w	99f, reg	; \
+	add	reg, tmp 	; \
+	bra	98f		; \
+	 mov.l	@tmp, reg	; \
+99:	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98:
+	
+# define LOAD_FUTEX_WAKE(reg,tmp) \
+	stc	gbr, tmp	; \
+	mov.w	99f, reg	; \
+	add	reg, tmp 	; \
+	mov.l	@tmp, reg	; \
+	bra	98f		; \
+	 mov	#FUTEX_WAKE, tmp ; \
+99:	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98:	or	tmp, reg
+#endif
+
 #include "lowlevellock.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
index ac3169889f..b10903bcd7 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 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
@@ -24,8 +24,24 @@
 
 #define SYS_gettimeofday	__NR_gettimeofday
 #define SYS_futex		240
-#define FUTEX_WAIT		0
-#define FUTEX_WAKE		1
+#ifndef FUTEX_WAIT
+# define FUTEX_WAIT		0
+# define FUTEX_WAKE		1
+#endif
+
+#ifndef LOAD_FUTEX_WAIT
+# if FUTEX_WAIT == 0
+#  define LOAD_FUTEX_WAIT(reg,tmp) \
+	xor	reg, reg
+# else
+#  define LOAD_FUTEX_WAIT(reg,tmp) \
+	mov	#FUTEX_WAIT, reg; \
+	extu.b	reg, reg
+# endif
+# define LOAD_FUTEX_WAKE(reg,tmp) \
+	mov	#FUTEX_WAKE, reg; \
+	extu.b	reg, reg
+#endif
 
 
 	.globl	__lll_mutex_lock_wait
@@ -40,7 +56,7 @@ __lll_mutex_lock_wait:
 	mov	r4, r6
 	mov	r5, r8
 	mov	#0, r7		/* No timeout.  */
-	mov	#FUTEX_WAIT, r5
+	LOAD_FUTEX_WAIT (r5, r0)
 
 	mov	#2, r4
 	cmp/eq	r4, r6
@@ -133,7 +149,7 @@ __lll_mutex_timedlock_wait:
 	bt	8f
 
 	mov	r8, r4
-	mov	#FUTEX_WAIT, r5
+	LOAD_FUTEX_WAIT (r5, r0)
 	mov	r10, r6
 	mov	r15, r7
 	mov	#SYS_futex, r3
@@ -186,41 +202,13 @@ __lll_mutex_timedlock_wait:
 #endif
 
 
-#ifdef NOT_IN_libc
-	.globl	lll_unlock_wake_cb
-	.type	lll_unlock_wake_cb,@function
-	.hidden	lll_unlock_wake_cb
-	.align	5
-	cfi_startproc
-lll_unlock_wake_cb:
-	DEC	(@r4, r2)
-	tst	r2, r2
-	bt	1f
-
-	mov	#FUTEX_WAKE, r5
-	mov	#1, r6		/* Wake one thread.  */
-	mov	#0, r7
-	mov.l	r7, @r4		/* Stores 0.  */
-	mov	#SYS_futex, r3
-	extu.b	r3, r3
-	trapa	#0x14
-	SYSCALL_INST_PAD
-
-1:	
-	rts
-	 nop
-	cfi_endproc
-	.size	lll_unlock_wake_cb,.-lll_unlock_wake_cb
-#endif
-
-
 	.globl	__lll_mutex_unlock_wake
 	.type	__lll_mutex_unlock_wake,@function
 	.hidden	__lll_mutex_unlock_wake
 	.align	5
 	cfi_startproc
 __lll_mutex_unlock_wake:
-	mov	#FUTEX_WAKE, r5
+	LOAD_FUTEX_WAKE (r5, r0)
 	mov	#1, r6		/* Wake one thread.  */
 	mov	#0, r7
 	mov.l	r7, @r4		/* Stores 0.  */
@@ -289,7 +277,10 @@ __lll_timedwait_tid:
 	bt	4f
 
 	mov	r8, r4
-	mov	#FUTEX_WAIT, r5
+	/* XXX The kernel so far uses global futex for the wakeup at
+	   all times.  */
+	mov	#0, r5
+	extu.b	r5, r5
 	mov	r2, r6
 	mov	r15, r7
 	mov	#SYS_futex, r3
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
index 0eb1f0114c..be47bd752e 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 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
@@ -22,6 +22,7 @@
 #include <time.h>
 #include <sys/param.h>
 #include <bits/pthreadtypes.h>
+#include <kernel-features.h>
 
 #define SYS_futex		240
 #define FUTEX_WAIT		0
@@ -29,6 +30,39 @@
 #define FUTEX_LOCK_PI		6
 #define FUTEX_UNLOCK_PI		7
 #define FUTEX_TRYLOCK_PI	8
+#define FUTEX_PRIVATE_FLAG	128
+
+
+/* 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.  */
@@ -251,7 +285,7 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 		and %2,%0\n\
 		mov.l %0,@%1\n\
 	     1: mov r1,r15"\
-		: "=&r" (__result) : "r" (__futex), "r" (FUTEX_TID_MASK) \
+		: "=&r" (__result) : "r" (__futex), "r" (FUTEX_WAITERS) \
 		: "r0", "r1", "memory");	\
 	    if (__result) \
 	      __lll_mutex_unlock_wake (__futex); })
@@ -269,7 +303,7 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 	     1: mov r1,r15"\
 		: "=&r" (__ignore) : "r" (__futex), "r" (FUTEX_OWNER_DIED) \
 		: "r0", "r1", "memory");	\
-	    lll_futex_wake (__futex, 1); })
+	    lll_futex_wake (__futex, 1, LLL_SHARED); })
 
 #define lll_mutex_islocked(futex) \
   (futex != 0)
@@ -294,29 +328,17 @@ typedef int lll_lock_t;
 	trapa #0x14"
 # endif
 
-#define lll_futex_wait(futex, val) \
-  ({									      \
-    int __status;							      \
-    register unsigned long __r3 asm ("r3") = SYS_futex;			      \
-    register unsigned long __r4 asm ("r4") = (unsigned long) (futex);	      \
-    register unsigned long __r5 asm ("r5") = FUTEX_WAIT;		      \
-    register unsigned long __r6 asm ("r6") = (unsigned long) (val);	      \
-    register unsigned long __r7 asm ("r7") = 0;				      \
-    __asm __volatile (SYSCALL_WITH_INST_PAD				      \
-		      : "=z" (__status)					      \
-		      : "r" (__r3), "r" (__r4), "r" (__r5),		      \
-			"r" (__r6), "r" (__r7)				      \
-		      : "memory", "t");					      \
-    __status;								      \
-  })
+#define lll_futex_wait(futex, val, private) \
+  lll_futex_timed_wait (futex, val, NULL, private)
 
 
-#define lll_futex_timed_wait(futex, val, timeout) \
+#define lll_futex_timed_wait(futex, val, timeout, private) \
   ({									      \
     int __status;							      \
     register unsigned long __r3 asm ("r3") = SYS_futex;			      \
     register unsigned long __r4 asm ("r4") = (unsigned long) (futex);	      \
-    register unsigned long __r5 asm ("r5") = FUTEX_WAIT;		      \
+    register unsigned long __r5 asm ("r5")				      \
+      = __lll_private_flag (FUTEX_WAIT, private);			      \
     register unsigned long __r6 asm ("r6") = (unsigned long) (val);	      \
     register unsigned long __r7 asm ("r7") = (timeout);			      \
     __asm __volatile (SYSCALL_WITH_INST_PAD				      \
@@ -328,12 +350,13 @@ typedef int lll_lock_t;
   })
 
 
-#define lll_futex_wake(futex, nr) \
+#define lll_futex_wake(futex, nr, private) \
   do {									      \
     int __ignore;							      \
     register unsigned long __r3 asm ("r3") = SYS_futex;			      \
     register unsigned long __r4 asm ("r4") = (unsigned long) (futex);	      \
-    register unsigned long __r5 asm ("r5") = FUTEX_WAKE;		      \
+    register unsigned long __r5 asm ("r5")				      \
+      = __lll_private_flag (FUTEX_WAKE, private);			      \
     register unsigned long __r6 asm ("r6") = (unsigned long) (nr);	      \
     register unsigned long __r7 asm ("r7") = 0;				      \
     __asm __volatile (SYSCALL_WITH_INST_PAD				      \
@@ -344,9 +367,6 @@ typedef int lll_lock_t;
   } while (0)
 
 
-extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
-
-
 /* The states of a lock are:
     0  -  untaken
     1  -  taken by one user
@@ -370,7 +390,7 @@ extern int __lll_wait_tid (int *tid) attribute_hidden;
   do {									      \
     __typeof (tid) *__tid = &(tid);					      \
     while (*__tid != 0)							      \
-      lll_futex_wait (__tid, *__tid);					      \
+      lll_futex_wait (__tid, *__tid, LLL_SHARED);			      \
   } while (0)
 
 extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
index 1fbb23a5a6..35dd607fc1 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
@@ -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
@@ -65,7 +65,13 @@ pthread_barrier_wait:
 #if CURR_EVENT != 0
 	add	#CURR_EVENT, r4
 #endif
+#if FUTEX_WAIT == 0
+	mov.l	@(PRIVATE,r8), r5
+#else
 	mov	#FUTEX_WAIT, r5
+	mov.l	@(PRIVATE,r8), r0
+	or	r0, r5
+#endif
 	mov	#0, r7
 8:
 	mov	#SYS_futex, r3
@@ -118,6 +124,8 @@ pthread_barrier_wait:
 #endif
 	mov	#0, r7
 	mov	#FUTEX_WAKE, r5
+	mov.l	@(PRIVATE,r8), r0
+	or	r0, r5
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
 	trapa	#0x14
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
index 6c782c8a76..0173cfb7d8 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 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
@@ -120,7 +120,7 @@ __pthread_cond_timedwait:
 	mov.l	@(cond_futex,r8), r0
 	add	r2, r0
 	mov.l	r0, @(cond_futex,r8)
-	mov	#(1 << clock_bits), r2
+	mov	#(1 << nwaiters_shift), r2
 	mov.l	@(cond_nwaiters,r8), r0
 	add	r2, r0
 	mov.l	r0, @(cond_nwaiters,r8)
@@ -136,7 +136,7 @@ __pthread_cond_timedwait:
 #ifdef __NR_clock_gettime
 	/* Get the clock number.	 */
 	mov.l	@(cond_nwaiters,r8), r4
-	mov	#((1 << clock_bits) - 1), r0
+	mov	#((1 << nwaiters_shift) - 1), r0
 	and	r0, r4
 	/* Only clocks 0 and 1 are allowed.  Both are handled in the
 	   kernel.  */
@@ -323,7 +323,7 @@ __pthread_cond_timedwait:
 	mov.l	r1,@(woken_seq+4,r8)
 
 24:
-	mov	#(1 << clock_bits), r2
+	mov	#(1 << nwaiters_shift), r2
 	mov.l	@(cond_nwaiters,r8),r0
 	sub	r2, r0
 	mov.l	r0,@(cond_nwaiters,r8)
@@ -335,7 +335,7 @@ __pthread_cond_timedwait:
 	not	r0, r0
 	cmp/eq	#0, r0
 	bf/s	25f
-	 mov	#((1 << clock_bits) - 1), r1
+	 mov	#((1 << nwaiters_shift) - 1), r1
 	not	r1, r1
 	mov.l	@(cond_nwaiters,r8),r0
 	tst	r1, r0
@@ -557,7 +557,7 @@ __condvar_tw_cleanup:
 	mov.l	r1,@(woken_seq+4,r8)
 
 3:
-	mov	#(1 << clock_bits), r2
+	mov	#(1 << nwaiters_shift), r2
 	mov.l	@(cond_nwaiters,r8),r0
 	sub	r2, r0
 	mov.l	r0,@(cond_nwaiters,r8)
@@ -570,7 +570,7 @@ __condvar_tw_cleanup:
 	not	r0, r0
 	cmp/eq	#0, r0
 	bf/s	4f
-	 mov	#((1 << clock_bits) - 1), r1
+	 mov	#((1 << nwaiters_shift) - 1), r1
 	not	r1, r1
 	mov.l	@(cond_nwaiters,r8),r0
 	tst	r1, r0
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
index 6c59f3e6c0..5eb332e484 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 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
@@ -107,7 +107,7 @@ __pthread_cond_wait:
 	mov.l	@(cond_futex,r8),r0
 	add	r2, r0
 	mov.l	r0,@(cond_futex,r8)
-	mov	#(1 << clock_bits), r2
+	mov	#(1 << nwaiters_shift), r2
 	mov.l	@(cond_nwaiters,r8), r0
 	add	r2, r0
 	mov.l	r0, @(cond_nwaiters,r8)
@@ -197,7 +197,7 @@ __pthread_cond_wait:
 	mov.l	r1,@(woken_seq+4,r8)
 
 16:
-	mov	#(1 << clock_bits), r2
+	mov	#(1 << nwaiters_shift), r2
 	mov.l	@(cond_nwaiters,r8),r0
 	sub	r2, r0
 	mov.l	r0,@(cond_nwaiters,r8)
@@ -209,7 +209,7 @@ __pthread_cond_wait:
 	not	r0, r0
 	cmp/eq	#0, r0
 	bf/s	17f
-	 mov	#((1 << clock_bits) - 1), r1
+	 mov	#((1 << nwaiters_shift) - 1), r1
 	not	r1, r1
 	mov.l	@(cond_nwaiters,r8),r0
 	tst	r1, r0
@@ -421,7 +421,7 @@ __condvar_w_cleanup:
 	mov.l	r1,@(woken_seq+4,r8)
 
 3:
-	mov	#(1 << clock_bits), r2
+	mov	#(1 << nwaiters_shift), r2
 	mov.l	@(cond_nwaiters,r8),r0
 	sub	r2, r0
 	mov.l	r0,@(cond_nwaiters,r8)
@@ -434,7 +434,7 @@ __condvar_w_cleanup:
 	not	r0, r0
 	cmp/eq	#0, r0
 	bf/s	4f
-	 mov	#((1 << clock_bits) - 1), r1
+	 mov	#((1 << nwaiters_shift) - 1), r1
 	not	r1, r1
 	mov.l	@(cond_nwaiters,r8),r0
 	tst	r1, r0
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
index 02af56b4c7..3d694d8376 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
@@ -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
@@ -18,11 +18,13 @@
 
 #include <unwindbuf.h>
 #include <sysdep.h>
+#include <kernel-features.h>
 #include "lowlevel-atomic.h"
 
-#define SYS_futex	240
-#define FUTEX_WAIT	0
-#define FUTEX_WAKE	1
+#define SYS_futex		240
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 	.comm	__fork_generation, 4, 4
 
@@ -95,7 +97,19 @@ __pthread_once:
 	bf	3f	/* Different for generation -> run initializer.  */
 
 	/* Somebody else got here first.  Wait.  */
-	mov	#FUTEX_WAIT, r5
+#if __ASSUME_PRIVATE_FUTEX
+	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r5
+	extu.b	r5, r5
+#else
+	stc	gbr, r1
+	mov.w	.Lpfoff, r2
+	add	r2, r1
+	mov.l	@r1, r5
+# if FUTEX_WAIT != 0
+	mov	#FUTEX_WAIT, r0
+	or	r0, r5
+# endif
+#endif
 	mov	r3, r6
 	mov	#0, r7
 	mov	#SYS_futex, r3
@@ -157,7 +171,17 @@ __pthread_once:
 	INC (@r9, r2)
 	/* Wake up all other threads.  */
 	mov	r9, r4
-	mov	#FUTEX_WAKE, r5
+#if __ASSUME_PRIVATE_FUTEX
+	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
+	extu.b	r5, r5
+#else
+	stc	gbr, r1
+	mov.w	.Lpfoff, r2
+	add	r2, r1
+	mov.l	@r1, r5
+	mov	#FUTEX_WAKE, r0
+	or	r0, r5
+#endif
 	mov	#-1, r6
 	shlr	r6		/* r6 = 0x7fffffff */
 	mov	#0, r7
@@ -192,7 +216,17 @@ __pthread_once:
 	mov	#0, r7
 	mov.l	r7, @r9
 	mov	r9, r4
-	mov	#FUTEX_WAKE, r5
+#if __ASSUME_PRIVATE_FUTEX
+	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
+#else
+	stc	gbr, r1
+	mov.w	.Lpfoff, r2
+	add	r2, r1
+	mov.l	@r1, r5
+	mov	#FUTEX_WAKE, r0
+	or	r0, r5
+#endif
+	extu.b	r5, r5
 	mov	#-1, r6
 	shlr	r6		/* r6 = 0x7fffffff */
 	mov	#SYS_futex, r3
@@ -208,6 +242,10 @@ __pthread_once:
 	sleep
 	cfi_endproc
 
+#if !__ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
 	.align	2
 .Lsigsetjmp:
 	.long	__sigsetjmp@PLT-(.Lsigsetjmp0-.)
@@ -224,23 +262,3 @@ __pthread_once_internal = __pthread_once
 
 	.globl	pthread_once
 pthread_once = __pthread_once
-
-
-	.type	clear_once_control,@function
-	.align	5
-clear_once_control:
-	mov	#0, r0
-	mov.l	r0, @r4
-
-	mov	#FUTEX_WAKE, r5
-	mov	#-1, r6
-	shlr	r6		/* r6 = 0x7fffffff */
-	mov	#0, r7
-	mov	#SYS_futex, r3
-	extu.b	r3, r3
-	trapa	#0x14
-	SYSCALL_INST_PAD
-
-	rts
-	 nop
-	.size	clear_once_control,.-clear_once_control
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
index f64c7217c9..f1795131f8 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 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
@@ -20,11 +20,13 @@
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
 #include <tcb-offsets.h>
+#include <kernel-features.h>
 #include "lowlevel-atomic.h"
 
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 
 	.text
@@ -55,7 +57,8 @@ __pthread_rwlock_rdlock:
 	mov.l	@(WRITERS_QUEUED,r8), r0
 	tst	r0, r0
 	bt	5f
-	mov.l	@(FLAGS,r8), r0
+	mov	#FLAGS, r0
+	mov.b	@(r0,r8), r0
 	tst	r0, r0
 	bt	5f
 3:
@@ -75,9 +78,28 @@ __pthread_rwlock_rdlock:
 	tst	r2, r2
 	bf	10f
 11:
+#if __ASSUME_PRIVATE_FUTEX
+	mov	#PSHARED, r0
+	mov.b	@(r0,r8), r5
+	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+	xor	r0, r5
+	extu.b	r5, r5
+#else
+	mov	#PSHARED, r0
+	mov.b	@(r0,r8), r5
+	extu.b	r5, r5
+# if FUTEX_WAIT != 0
+	mov	#FUTEX_WAIT, r0
+	or	r0, r5
+# endif
+	stc	gbr, r1
+	mov.w	.Lpfoff, r2
+	add	r2, r1
+	mov.l	@r1, r0
+	xor	r0, r5
+#endif
 	mov	r8, r4
 	add	#READERS_WAKEUP, r4
-	mov	#FUTEX_WAIT, r5
 	mov	r9, r6
 	mov	#0, r7
 	mov	#SYS_futex, r3
@@ -124,6 +146,11 @@ __pthread_rwlock_rdlock:
 	rts
 	 mov	r3, r0
 
+#if !__ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+
 1:
 	mov	r8, r5
 #if MUTEX != 0
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
index 633a14b1aa..e87326e9bd 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 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
@@ -20,12 +20,14 @@
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
 #include <tcb-offsets.h>
+#include <kernel-features.h>
 #include "lowlevel-atomic.h"
 
 #define SYS_gettimeofday	__NR_gettimeofday
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 
 	.text
@@ -59,7 +61,8 @@ pthread_rwlock_timedrdlock:
 	mov.l	@(WRITERS_QUEUED,r8), r0
 	tst	r0, r0
 	bt	5f
-	mov.l	@(FLAGS,r8), r0
+	mov	#FLAGS, r0
+	mov.b	@(r0,r8), r0
 	tst	r0, r0
 	bt	5f
 3:
@@ -117,7 +120,26 @@ pthread_rwlock_timedrdlock:
 
 	/* Futex call.  */
 	mov	r15, r7
-	mov	#FUTEX_WAIT, r5
+#if __ASSUME_PRIVATE_FUTEX
+	mov	#PSHARED, r0
+	mov.b	@(r0,r8), r5
+	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+	xor	r0, r5
+	extu.b	r5, r5
+#else
+	mov	#PSHARED, r0
+	mov.b	@(r0,r8), r5
+	extu.b	r5, r5
+# if FUTEX_WAIT != 0
+	mov	#FUTEX_WAIT, r0
+	or	r0, r5
+# endif
+	stc	gbr, r1
+	mov.w	.Lpfoff, r2
+	add	r2, r1
+	mov.l	@r1, r0
+	xor	r0, r5
+#endif
 	mov	r10, r6
 	mov	r8, r4
 	add	#READERS_WAKEUP, r4
@@ -176,6 +198,10 @@ pthread_rwlock_timedrdlock:
 	rts
 	 mov	r3, r0
 
+#if !__ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
 	.align	2
 .L1k0:
 	.long	1000
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
index 29e29b6f65..18641fe9df 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 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
@@ -20,12 +20,14 @@
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
 #include <tcb-offsets.h>
+#include <kernel-features.h>
 #include "lowlevel-atomic.h"
 
 #define SYS_gettimeofday	__NR_gettimeofday
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG    128
 
 
 	.text
@@ -114,7 +116,26 @@ pthread_rwlock_timedwrlock:
 
 	/* Futex call.  */
 	mov	r15, r7
-	mov	#FUTEX_WAIT, r5
+#if __ASSUME_PRIVATE_FUTEX
+	mov	#PSHARED, r0
+	mov.b	@(r0,r8), r5
+	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+	xor	r0, r5
+	extu.b	r5, r5
+#else
+	mov	#PSHARED, r0
+	mov.b	@(r0,r8), r5
+	extu.b	r5, r5
+# if FUTEX_WAIT != 0
+	mov	#FUTEX_WAIT, r0
+	or	r0, r5
+# endif
+	stc	gbr, r1
+	mov.w	.Lpfoff, r2
+	add	r2, r1
+	mov.l	@r1, r0
+	xor	r0, r5
+#endif
 	mov	r10, r6
 	mov	r8, r4
 	add	#WRITERS_WAKEUP, r4
@@ -175,6 +196,10 @@ pthread_rwlock_timedwrlock:
 	rts
 	 mov	r3, r0
 
+#if !__ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
 .L1k1:
 	.word	1000
 	.align	2
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
index 172689bec3..df4df60d7f 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 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
@@ -18,11 +18,13 @@
 
 #include <sysdep.h>
 #include <lowlevelrwlock.h>
+#include <kernel-features.h>
 #include "lowlevel-atomic.h"
 
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 
 	.text
@@ -87,7 +89,24 @@ __pthread_rwlock_unlock:
 	bf	7f
 
 8:
-	mov	#FUTEX_WAKE, r5
+#if __ASSUME_PRIVATE_FUTEX
+	mov	#PSHARED, r0
+	mov.b	@(r0,r8), r5
+	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r0
+	xor	r0, r5
+	extu.b	r5, r5
+#else
+	mov	#PSHARED, r0
+	mov.b	@(r0,r8), r5
+	extu.b	r5, r5
+	mov	#FUTEX_WAKE, r0
+	or	r0, r5
+	stc	gbr, r1
+	mov.w	.Lpfoff, r2
+	add	r2, r1
+	mov.l	@r1, r0
+	xor	r0, r5
+#endif
 	mov	#SYS_futex, r3
 	mov	#0, r7
 	extu.b	r3, r3
@@ -154,6 +173,10 @@ __pthread_rwlock_unlock:
 	bra	8b
 	 mov.l	@r15+, r4
 
+#if !__ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
 	.align	2
 .Lwait8:	
 	.long	__lll_mutex_lock_wait-.Lwait8b
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
index 995d823e80..13a2fda9fd 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 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
@@ -20,11 +20,13 @@
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
 #include <tcb-offsets.h>
+#include <kernel-features.h>
 #include "lowlevel-atomic.h"
 
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 
 	.text
@@ -74,7 +76,26 @@ __pthread_rwlock_wrlock:
 11:
 	mov	r8, r4
 	add	#WRITERS_WAKEUP, r4
-	mov	#FUTEX_WAIT, r5
+#if __ASSUME_PRIVATE_FUTEX
+	mov	#PSHARED, r0
+	mov.b	@(r0,r8), r5
+	mov	#(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+	xor	r0, r5
+	extu.b	r5, r5
+#else
+	mov	#PSHARED, r0
+	mov.b	@(r0,r8), r5
+	extu.b	r5, r5
+# if FUTEX_WAIT != 0
+	mov	#FUTEX_WAIT, r0
+	or	r0, r5
+# endif
+	stc	gbr, r1
+	mov.w	.Lpfoff, r2
+	add	r2, r1
+	mov.l	@r1, r0
+	xor	r0, r5
+#endif
 	mov	r9, r6
 	mov	#0, r7
 	mov	#SYS_futex, r3
@@ -152,6 +173,10 @@ __pthread_rwlock_wrlock:
 	bra	7b
 	 mov	#0, r3
 
+#if !__ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+	.word	PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
 .Ltidoff:
 	.word	TID - TLS_PRE_TCB_SIZE
 
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
index 9bc12da7e0..a63233feab 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
@@ -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
@@ -19,6 +19,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 #include "lowlevel-atomic.h"
 
 
@@ -34,11 +35,14 @@
 	.align	5
 __new_sem_post:
 	mov	#1, r3
-	XADD (r3, @r4, r2)
-
+	XADD (r3, @(VALUE,r4), r2)
+	mov.l	@(NWAITERS,r4), r2
+	tst	r2, r2
+	bt	2f
 	mov	#FUTEX_WAKE, r5
-	mov	r2, r6
-	add	#1, r6
+	mov.l	@(PRIVATE,r4), r1
+	or	r1, r5
+	mov	#1, r6
 	mov	#0, r7
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
@@ -47,6 +51,7 @@ __new_sem_post:
 
 	cmp/pz	r0
 	bf	1f
+2:
 	rts
 	 mov	#0, r0
 
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
index acb7d0f78b..e5e064b3a5 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
@@ -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
@@ -20,32 +20,25 @@
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
 #include <tcb-offsets.h>
+#include <structsem.h>
 #include "lowlevel-atomic.h"
 
 
 #define SYS_gettimeofday	__NR_gettimeofday
 #define SYS_futex		240
 #define FUTEX_WAIT		0
-#define FUTEX_WAKE		1
+
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
 
 	.text
 
 	.globl	sem_timedwait
 	.type	sem_timedwait,@function
 	.align	5
-	cfi_startproc
 sem_timedwait:
-	/* First check for cancellation.  */
-	stc	gbr, r0
-	mov.w	.Lchand, r1
-	mov.l	@(r0,r1), r0
-	mov	#0xf9, r1
-	and	r1, r0
-	cmp/eq	#8, r0
-	bf	0f
-	bra	10f
-	 stc	gbr, r0
-0:
+.LSTARTCODE:
 	mov.l	@r4, r0
 2:
 	tst	r0, r0
@@ -62,22 +55,17 @@ sem_timedwait:
 1:
 	/* Check whether the timeout value is valid.  */
 	mov.l	r8, @-r15
-	cfi_adjust_cfa_offset(4)
-	cfi_rel_offset (r8, 0)
+.Lpush_r8:
 	mov.l	r9, @-r15
-	cfi_adjust_cfa_offset(4)
-	cfi_rel_offset (r9, 0)
+.Lpush_r9:
 	mov.l	r10, @-r15
-	cfi_adjust_cfa_offset(4)
-	cfi_rel_offset (r10, 0)
+.Lpush_r10:
 	mov.l	r12, @-r15
-	cfi_adjust_cfa_offset(4)
-	cfi_rel_offset (r12, 0)
+.Lpush_r12:
 	sts.l	pr, @-r15
-	cfi_adjust_cfa_offset(4)
-	cfi_rel_offset (pr, 0)
+.Lpush_pr:
 	add	#-8, r15
-	cfi_adjust_cfa_offset(8)
+.Lalloc:
 	mov	r4, r8
 	mov	r5, r9
 
@@ -87,13 +75,9 @@ sem_timedwait:
 	cmp/hs	r1, r0
 	bt/s	6f
 	 mov	#EINVAL, r0
-7:
-	mov.l	.Lenable0, r1
-	bsrf	r1
-	 nop
-.Lenable0b:
-	mov	r0, r10
+	INC (@(NWAITERS,r8),r2)
 
+7:
 	/* Compute relative timeout.  */
 	mov	r15, r4
 	mov	#0, r5
@@ -124,9 +108,21 @@ sem_timedwait:
 	mov.l	r2, @r15
 	mov.l	r3, @(4,r15)
 
-	/* Futex call.  */
+.LcleanupSTART:
+	mov.l	.Lenable0, r1
+	bsrf	r1
+	 nop
+.Lenable0b:
+	mov	r0, r10
+
 	mov	r8, r4
-	mov	#FUTEX_WAIT, r5
+#if FUTEX_WAIT == 0
+	mov.l	@(PRIVATE,r8), r5
+#else
+	mov.l	@(PRIVATE,r8), r5
+	mov	#FUTEX_WAIT, r0
+	or	r0, r5
+#endif
 	mov	#0, r6
 	mov	r15, r7
 	mov	#SYS_futex, r3
@@ -140,6 +136,7 @@ sem_timedwait:
 	 mov	r0, r10
 .Ldisable0b:	
 	mov	r10, r0
+.LcleanupEND:
 
 	tst	r0, r0
 	bt	9f
@@ -158,6 +155,10 @@ sem_timedwait:
 	bf/s	8b
 	 mov	r2, r0
 
+	DEC (@(NWAITERS,r8), r2)
+	mov	#0, r0
+
+10:
 	add	#8, r15
 	lds.l	@r15+, pr
 	mov.l	@r15+, r12
@@ -165,12 +166,12 @@ sem_timedwait:
 	mov.l	@r15+, r9
 	mov.l	@r15+, r8
 	rts
-	 mov	#0, r0
+	 nop
 
 3:
 	neg	r0, r0
 6:
-	mov	r0, r8
+	mov	r0, r10
 	mova	.Lgot2, r0
 	mov.l	.Lgot2, r12
 	add	r0, r12
@@ -180,46 +181,20 @@ sem_timedwait:
 	stc	gbr, r1
 	mov.l	@(r0, r12), r0
 	add	r1, r0
-	mov.l	r8, @r0
+	mov.l	r10, @r0
 #else
 	mov.l	.Lerrloc2, r1
 	bsrf	r1
 	 nop
 .Lerrloc2b:
-	mov.l	r8, @r0
+	mov.l	r10, @r0
 #endif
-	add	#8, r15
-	lds.l	@r15+, pr
-	mov.l	@r15+, r12
-	mov.l	@r15+, r10
-	mov.l	@r15+, r9
-	mov.l	@r15+, r8
-	rts
+	DEC (@(NWAITERS,r8), r2)
+	bra	10b
 	 mov	#-1, r0
 
-10:
-	/* Canceled.  */
-	mov.w	.Lresult, r1
-	mov	#-1, r2
-	mov.l	r2, @(r0,r1)
-	mov.w	.Lchand, r0
-	or.b	#0x10, @(r0,gbr)
-	stc	gbr, r0
-	mov.w	.Lclbuf, r1
-	mov.l	.Lunwind, r2
-	braf	r2
-	 mov.l	@(r0,r1), r4
-.Lunwindb:
-	cfi_endproc
-
 .L1k:
 	.word	1000
-.Lchand:
-	.word	CANCELHANDLING - TLS_PRE_TCB_SIZE
-.Lresult:
-	.word	RESULT - TLS_PRE_TCB_SIZE
-.Lclbuf:
-	.word	CLEANUP_JMP_BUF - TLS_PRE_TCB_SIZE
 	.align	2
 .L1g:
 	.long	1000000000
@@ -236,6 +211,151 @@ sem_timedwait:
 	.long	__pthread_enable_asynccancel-.Lenable0b
 .Ldisable0:
 	.long	__pthread_disable_asynccancel-.Ldisable0b
-.Lunwind:
-	.long	HIDDEN_JUMPTARGET (__pthread_unwind)-.Lunwindb
 	.size	sem_timedwait,.-sem_timedwait
+
+	.type	sem_wait_cleanup,@function
+sem_wait_cleanup:
+ 	DEC (@(NWAITERS,r8), r2)
+.LcallUR:
+	mov.l	.Lresume, r1
+#ifdef PIC
+	add	r12, r1
+#endif
+	jsr	@r1
+	 nop
+	sleep
+
+	.align	2
+.Lresume:
+#ifdef PIC
+	.long	_Unwind_Resume@GOTOFF
+#else
+	.long	_Unwind_Resume
+#endif
+.LENDCODE:
+	.size	sem_wait_cleanup,.-sem_wait_cleanup
+
+
+	.section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+	.byte	0xff				! @LPStart format (omit)
+	.byte	0xff				! @TType format (omit)
+	.byte	0x01				! call-site format
+						! DW_EH_PE_uleb128
+	.uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+	.uleb128 .LcleanupSTART-.LSTARTCODE
+	.uleb128 .LcleanupEND-.LcleanupSTART
+	.uleb128 sem_wait_cleanup-.LSTARTCODE
+	.uleb128  0
+	.uleb128 .LcallUR-.LSTARTCODE
+	.uleb128 .LENDCODE-.LcallUR
+	.uleb128 0
+	.uleb128  0
+.Lcstend:
+
+
+	.section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+	.ualong	.LENDCIE-.LSTARTCIE		! Length of the CIE.
+.LSTARTCIE:
+	.ualong	0				! CIE ID.
+	.byte	1				! Version number.
+#ifdef SHARED
+	.string	"zPLR"				! NUL-terminated augmentation
+						! string.
+#else
+	.string	"zPL"				! NUL-terminated augmentation
+						! string.
+#endif
+	.uleb128 1				! Code alignment factor.
+	.sleb128 -4				! Data alignment factor.
+	.byte	0x11				! Return address register
+						! column.
+#ifdef SHARED
+	.uleb128 7				! Augmentation value length.
+	.byte	0x9b				! Personality: DW_EH_PE_pcrel
+						! + DW_EH_PE_sdata4
+						! + DW_EH_PE_indirect
+	.ualong	DW.ref.__gcc_personality_v0-.
+	.byte	0x1b				! LSDA Encoding: DW_EH_PE_pcrel
+						! + DW_EH_PE_sdata4.
+	.byte	0x1b				! FDE Encoding: DW_EH_PE_pcrel
+						! + DW_EH_PE_sdata4.
+#else
+	.uleb128 6				! Augmentation value length.
+	.byte	0x0				! Personality: absolute
+	.ualong	__gcc_personality_v0
+	.byte	0x0				! LSDA Encoding: absolute
+#endif
+	.byte 0x0c				! DW_CFA_def_cfa
+	.uleb128 0xf
+	.uleb128 0
+	.align 4
+.LENDCIE:
+
+	.ualong	.LENDFDE-.LSTARTFDE		! Length of the FDE.
+.LSTARTFDE:
+	.ualong	.LSTARTFDE-.LSTARTFRAME		! CIE pointer.
+#ifdef SHARED
+	.ualong	.LSTARTCODE-.			! PC-relative start address
+						! of the code.
+#else
+	.ualong	.LSTARTCODE			! Start address of the code.
+#endif
+	.ualong	.LENDCODE-.LSTARTCODE		! Length of the code.
+	.uleb128 4				! Augmentation size
+#ifdef SHARED
+	.ualong	.LexceptSTART-.
+#else
+	.ualong	.LexceptSTART
+#endif
+
+	.byte	4				! DW_CFA_advance_loc4
+	.ualong	.Lpush_r8-.LSTARTCODE
+	.byte	14				! DW_CFA_def_cfa_offset
+	.uleb128 4
+	.byte   0x88				! DW_CFA_offset r8
+        .uleb128 1
+	.byte	4				! DW_CFA_advance_loc4
+	.ualong	.Lpush_r9-.Lpush_r8
+	.byte	14				! DW_CFA_def_cfa_offset
+	.uleb128 8
+	.byte   0x89				! DW_CFA_offset r9
+        .uleb128 2
+	.byte	4				! DW_CFA_advance_loc4
+	.ualong	.Lpush_r10-.Lpush_r9
+	.byte	14				! DW_CFA_def_cfa_offset
+	.uleb128 12
+	.byte   0x8a				! DW_CFA_offset r10
+        .uleb128 3
+	.byte	4				! DW_CFA_advance_loc4
+	.ualong	.Lpush_r12-.Lpush_r10
+	.byte	14				! DW_CFA_def_cfa_offset
+	.uleb128 16
+	.byte   0x8c				! DW_CFA_offset r12
+        .uleb128 4
+	.byte	4				! DW_CFA_advance_loc4
+	.ualong	.Lpush_pr-.Lpush_r12
+	.byte	14				! DW_CFA_def_cfa_offset
+	.uleb128 20
+	.byte	0x91				! DW_CFA_offset pr
+	.uleb128 5
+	.byte	4				! DW_CFA_advance_loc4
+	.ualong	.Lalloc-.Lpush_pr
+	.byte	14				! DW_CFA_def_cfa_offset
+	.uleb128 28
+	.align	4
+.LENDFDE:
+
+
+#ifdef SHARED
+	.hidden	DW.ref.__gcc_personality_v0
+	.weak	DW.ref.__gcc_personality_v0
+	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+	.align	4
+	.type	DW.ref.__gcc_personality_v0, @object
+	.size	DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+	.long	__gcc_personality_v0
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
index 9ceb8f1c24..85ce909259 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
@@ -20,44 +20,35 @@
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
 #include <tcb-offsets.h>
+#include <structsem.h>
 #include "lowlevel-atomic.h"
 
 
 #define SYS_gettimeofday	__NR_gettimeofday
 #define SYS_futex		240
 #define FUTEX_WAIT		0
-#define FUTEX_WAKE		1
+
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
 
 	.text
 
 	.globl	__new_sem_wait
 	.type	__new_sem_wait,@function
 	.align	5
-	cfi_startproc
 __new_sem_wait:
-	/* First check for cancellation.  */
-	stc	gbr, r0
-	mov.w	.Lchand, r1
-	mov.l	@(r0,r1), r0
-	mov	#0xf9, r1
-	and	r1, r0
-	cmp/eq	#8, r0
-	bt	5f
-
+.LSTARTCODE:
 	mov.l	r8, @-r15
-	cfi_adjust_cfa_offset(4)
-	cfi_rel_offset (r8, 0)
+.Lpush_r8:
 	mov.l	r10, @-r15
-	cfi_adjust_cfa_offset(4)
-	cfi_rel_offset (r10, 0)
+.Lpush_r10:
 	mov.l	r12, @-r15
-	cfi_adjust_cfa_offset(4)
-	cfi_rel_offset (r12, 0)
+.Lpush_r12:
 	sts.l	pr, @-r15
-	cfi_adjust_cfa_offset(4)
-	cfi_rel_offset (pr, 0)
+.Lpush_pr:
 	mov	r4, r8
-3:
+
 	mov.l	@r8, r0
 2:
 	tst	r0, r0
@@ -68,10 +59,21 @@ __new_sem_wait:
 	CMPXCHG (r4, @r8, r3, r2)
 	bf/s	2b
 	 mov	r2, r0
-	bra	9f
-	 mov	#0, r0
+7:
+	mov	#0, r0
+9:
+	lds.l	@r15+, pr
+	mov.l	@r15+, r12
+	mov.l	@r15+, r10
+	rts
+	 mov.l	@r15+, r8
 
+.Lafter_ret:
 1:
+	INC (@(NWAITERS,r8),r2)
+	
+.LcleanupSTART:
+6:
 	mov.l	.Lenable0, r1
 	bsrf	r1
 	 nop
@@ -79,7 +81,13 @@ __new_sem_wait:
 	mov	r0, r10
 
 	mov	r8, r4
-	mov	#FUTEX_WAIT, r5
+#if FUTEX_WAIT == 0
+	mov.l	@(PRIVATE,r8), r5
+#else
+	mov.l	@(PRIVATE,r8), r5
+	mov	#FUTEX_WAIT, r0
+	or	r0, r5
+#endif
 	mov	#0, r6
 	mov	#0, r7
 	mov	#SYS_futex, r3
@@ -93,14 +101,35 @@ __new_sem_wait:
 	 mov	r0, r10
 .Ldisable0b:	
 	mov	r10, r0
+.LcleanupEND:
 
 	tst	r0, r0
-	bt	3b
+	bt	3f
 	cmp/eq	#-EWOULDBLOCK, r0
-	bt	3b
-	neg	r0, r0
+	bf	4f
+
+3:
+	mov.l	@r8, r0
+5:
+	tst	r0, r0
+	bt	6b
+
+	mov	r0, r3
+	mov	r0, r4
+	add	#-1, r3
+	CMPXCHG (r4, @r8, r3, r2)
+	bf/s	5b
+	 mov	r2, r0
+
+	DEC (@(NWAITERS,r8), r2)
+	bra	7b
+	 nop
 
-	mov	r0, r8
+4:
+	neg	r0, r0
+	mov	r0, r4
+	DEC (@(NWAITERS,r8), r2)
+	mov	r4, r8
 	mova	.Lgot0, r0
 	mov.l	.Lgot0, r12
 	add	r0, r12
@@ -118,36 +147,9 @@ __new_sem_wait:
 .Lerrloc0b:
 	mov.l	r8, @r0
 #endif
-	mov	#-1, r0
-9:
-	lds.l	@r15+, pr
-	mov.l	@r15+, r12
-	mov.l	@r15+, r10
-	rts
-	 mov.l	@r15+, r8
-5:
-	/* Canceled.  */
-	stc	gbr, r0
-	mov.w	.Lresult, r1
-	mov	#-1, r2
-	mov.l	r2, @(r0,r1)
-	mov.w	.Lchand, r0
-	or.b	#0x10, @(r0,gbr)
-	stc	gbr, r0
-	mov.w	.Lclbuf, r1
-	mov.l	.Lunwind, r2
-	braf	r2
-	 mov.l	@(r0,r1), r4
-.Lunwindb:
-	cfi_endproc
-
-.Lchand:
-	.word	CANCELHANDLING - TLS_PRE_TCB_SIZE
-.Lresult:
-	.word	RESULT - TLS_PRE_TCB_SIZE
-.Lclbuf:
-	.word	CLEANUP_JMP_BUF - TLS_PRE_TCB_SIZE
-	.align	2
+	bra	9b
+	 mov	#-1, r0
+
 .Lgot0:
 	.long	_GLOBAL_OFFSET_TABLE_
 #if USE___THREAD
@@ -161,7 +163,143 @@ __new_sem_wait:
 	.long	__pthread_enable_asynccancel-.Lenable0b
 .Ldisable0:
 	.long	__pthread_disable_asynccancel-.Ldisable0b
-.Lunwind:
-	.long	HIDDEN_JUMPTARGET (__pthread_unwind)-.Lunwindb
 	.size	__new_sem_wait,.-__new_sem_wait
 	versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
+
+
+	.type	sem_wait_cleanup,@function
+sem_wait_cleanup:
+ 	DEC (@(NWAITERS,r8), r2)
+.LcallUR:
+	mov.l	.Lresume, r1
+#ifdef PIC
+	add	r12, r1
+#endif
+	jsr	@r1
+	 nop
+	sleep
+
+	.align	2
+.Lresume:
+#ifdef PIC
+	.long	_Unwind_Resume@GOTOFF
+#else
+	.long	_Unwind_Resume
+#endif
+.LENDCODE:
+	.size	sem_wait_cleanup,.-sem_wait_cleanup
+
+
+	.section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+	.byte	0xff				! @LPStart format (omit)
+	.byte	0xff				! @TType format (omit)
+	.byte	0x01				! call-site format
+						! DW_EH_PE_uleb128
+	.uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+	.uleb128 .LcleanupSTART-.LSTARTCODE
+	.uleb128 .LcleanupEND-.LcleanupSTART
+	.uleb128 sem_wait_cleanup-.LSTARTCODE
+	.uleb128  0
+	.uleb128 .LcallUR-.LSTARTCODE
+	.uleb128 .LENDCODE-.LcallUR
+	.uleb128 0
+	.uleb128  0
+.Lcstend:
+
+
+	.section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+	.ualong	.LENDCIE-.LSTARTCIE		! Length of the CIE.
+.LSTARTCIE:
+	.ualong	0				! CIE ID.
+	.byte	1				! Version number.
+#ifdef SHARED
+	.string	"zPLR"				! NUL-terminated augmentation
+						! string.
+#else
+	.string	"zPL"				! NUL-terminated augmentation
+						! string.
+#endif
+	.uleb128 1				! Code alignment factor.
+	.sleb128 -4				! Data alignment factor.
+	.byte	0x11				! Return address register
+						! column.
+#ifdef SHARED
+	.uleb128 7				! Augmentation value length.
+	.byte	0x9b				! Personality: DW_EH_PE_pcrel
+						! + DW_EH_PE_sdata4
+						! + DW_EH_PE_indirect
+	.ualong	DW.ref.__gcc_personality_v0-.
+	.byte	0x1b				! LSDA Encoding: DW_EH_PE_pcrel
+						! + DW_EH_PE_sdata4.
+	.byte	0x1b				! FDE Encoding: DW_EH_PE_pcrel
+						! + DW_EH_PE_sdata4.
+#else
+	.uleb128 6				! Augmentation value length.
+	.byte	0x0				! Personality: absolute
+	.ualong	__gcc_personality_v0
+	.byte	0x0				! LSDA Encoding: absolute
+#endif
+	.byte 0x0c				! DW_CFA_def_cfa
+	.uleb128 0xf
+	.uleb128 0
+	.align 4
+.LENDCIE:
+
+	.ualong	.LENDFDE-.LSTARTFDE		! Length of the FDE.
+.LSTARTFDE:
+	.ualong	.LSTARTFDE-.LSTARTFRAME		! CIE pointer.
+#ifdef SHARED
+	.ualong	.LSTARTCODE-.			! PC-relative start address
+						! of the code.
+#else
+	.ualong	.LSTARTCODE			! Start address of the code.
+#endif
+	.ualong	.LENDCODE-.LSTARTCODE		! Length of the code.
+	.uleb128 4				! Augmentation size
+#ifdef SHARED
+	.ualong	.LexceptSTART-.
+#else
+	.ualong	.LexceptSTART
+#endif
+
+	.byte	4				! DW_CFA_advance_loc4
+	.ualong	.Lpush_r8-.LSTARTCODE
+	.byte	14				! DW_CFA_def_cfa_offset
+	.uleb128 4
+	.byte   0x88				! DW_CFA_offset r8
+        .uleb128 1
+	.byte	4				! DW_CFA_advance_loc4
+	.ualong	.Lpush_r10-.Lpush_r8
+	.byte	14				! DW_CFA_def_cfa_offset
+	.uleb128 8
+	.byte   0x8a				! DW_CFA_offset r10
+        .uleb128 2
+	.byte	4				! DW_CFA_advance_loc4
+	.ualong	.Lpush_r12-.Lpush_r10
+	.byte	14				! DW_CFA_def_cfa_offset
+	.uleb128 12
+	.byte   0x8c				! DW_CFA_offset r12
+        .uleb128 3
+	.byte	4				! DW_CFA_advance_loc4
+	.ualong	.Lpush_pr-.Lpush_r12
+	.byte	14				! DW_CFA_def_cfa_offset
+	.uleb128 16
+	.byte   0x91				! DW_CFA_offset pr
+        .uleb128 4
+	.align	4
+.LENDFDE:
+
+
+#ifdef SHARED
+	.hidden	DW.ref.__gcc_personality_v0
+	.weak	DW.ref.__gcc_personality_v0
+	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+	.align	4
+	.type	DW.ref.__gcc_personality_v0, @object
+	.size	DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+	.long	__gcc_personality_v0
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
index 5013922a2f..922e3c21d3 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -35,37 +35,66 @@
 #define FUTEX_LOCK_PI		6
 #define FUTEX_UNLOCK_PI		7
 #define FUTEX_TRYLOCK_PI	8
+#define FUTEX_PRIVATE_FLAG	128
+
+
+/* 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;								      \
   })
 
@@ -86,7 +115,7 @@
     {									      \
       int *__futexp = &(futexv);					      \
       atomic_or (__futexp, FUTEX_OWNER_DIED);				      \
-      lll_futex_wake (__futexp, 1);					      \
+      lll_futex_wake (__futexp, 1, LLL_SHARED);				      \
     }									      \
   while (0)
 
@@ -212,7 +241,7 @@ __lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
     int *__futex = &(lock);						      \
     int __val = atomic_exchange_24_rel (__futex, 0);			      \
     if (__builtin_expect (__val > 1, 0))				      \
-      lll_futex_wake (__futex, 1);					      \
+      lll_futex_wake (__futex, 1, LLL_SHARED);				      \
   }))
 
 #define lll_robust_mutex_unlock(lock) \
@@ -220,14 +249,14 @@ __lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
     int *__futex = &(lock);						      \
     int __val = atomic_exchange_rel (__futex, 0);			      \
     if (__builtin_expect (__val & FUTEX_WAITERS, 0))			      \
-      lll_futex_wake (__futex, 1);					      \
+      lll_futex_wake (__futex, 1, LLL_SHARED);				      \
   }))
 
 #define lll_mutex_unlock_force(lock) \
   ((void) ({								      \
     int *__futex = &(lock);						      \
     (void) atomic_exchange_24_rel (__futex, 0);				      \
-    lll_futex_wake (__futex, 1);					      \
+    lll_futex_wake (__futex, 1, LLL_SHARED);				      \
   }))
 
 #define lll_mutex_islocked(futex) \
@@ -240,8 +269,6 @@ __lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
 /* Type for lock object.  */
 typedef int lll_lock_t;
 
-extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
-
 /* Initializers for lock.  */
 #define LLL_LOCK_INITIALIZER		(0)
 #define LLL_LOCK_INITIALIZER_LOCKED	(1)
@@ -257,12 +284,12 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
    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 *)
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
index 3b07cc127d..22e2dd3c0c 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/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.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -30,7 +30,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);
 }
 
 
@@ -65,7 +65,7 @@ __pthread_once (once_control, init_routine)
 	  if (((oldval ^ newval) & -4) == 0)
 	    {
 	      /* Same generation, some other thread was faster. Wait.  */
-	      lll_futex_wait (once_control, newval);
+	      lll_futex_wait (once_control, newval, LLL_PRIVATE);
 	      continue;
 	    }
 	}
@@ -84,7 +84,7 @@ __pthread_once (once_control, init_routine)
       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);
       break;
     }
 
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c
index a7611d6a88..cb9578b47b 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c
@@ -1,5 +1,5 @@
 /* low level locking for pthread library.  SPARC version.
-   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
 
@@ -76,21 +76,9 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime)
 }
 
 
-/* These don't get included in libc.so  */
+/* This function doesn't get included in libc.so  */
 #ifdef IS_IN_libpthread
 int
-lll_unlock_wake_cb (int *futex)
-{
-  int val = atomic_exchange_24_rel (futex, 0);
-
-  if (__builtin_expect (val > 1, 0))
-    lll_futex_wake (futex, 1);
-
-  return 0;
-}
-
-
-int
 __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
 {
   int tid;
@@ -127,5 +115,4 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
 
   return 0;
 }
-
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c
index 4dfd11dcbe..868e0d2819 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -52,7 +52,9 @@ pthread_barrier_wait (barrier)
       ++ibarrier->b.curr_event;
 
       /* Wake up everybody.  */
-      lll_futex_wake (&ibarrier->b.curr_event, INT_MAX);
+      lll_futex_wake (&ibarrier->b.curr_event, INT_MAX,
+		      // XYZ check mutex flag
+		      LLL_SHARED);
 
       /* This is the thread which finished the serialization.  */
       result = PTHREAD_BARRIER_SERIAL_THREAD;
@@ -68,7 +70,9 @@ pthread_barrier_wait (barrier)
 
       /* Wait for the event counter of the barrier to change.  */
       do
-	lll_futex_wait (&ibarrier->b.curr_event, event);
+	lll_futex_wait (&ibarrier->b.curr_event, event,
+			// XYZ check mutex flag
+			LLL_SHARED);
       while (event == ibarrier->b.curr_event);
     }
 
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c
index be1cc60b11..527aedfdc7 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c
@@ -1,5 +1,5 @@
 /* sem_post -- post to a POSIX semaphore.  SPARC version.
-   Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -39,7 +39,9 @@ __new_sem_post (sem_t *sem)
       nr = ++*futex;
       __sparc32_atomic_do_unlock24 (futex + 1);
     }
-  int err = lll_futex_wake (futex, nr);
+  int err = lll_futex_wake (futex, nr,
+			    // XYZ check mutex flag
+			    LLL_SHARED);
   if (__builtin_expect (err, 0) < 0)
     {
       __set_errno (-err);
diff --git a/nptl/sysdeps/unix/sysv/linux/structsem.sym b/nptl/sysdeps/unix/sysv/linux/structsem.sym
new file mode 100644
index 0000000000..4f32c68da5
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/structsem.sym
@@ -0,0 +1,10 @@
+#include <stddef.h>
+#include <sched.h>
+#include <bits/pthreadtypes.h>
+#include "internaltypes.h"
+
+--
+
+VALUE		offsetof (struct new_sem, value)
+PRIVATE		offsetof (struct new_sem, private)
+NWAITERS	offsetof (struct new_sem, nwaiters)
diff --git a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c b/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
index 964f5b7094..bc5b7537a3 100644
--- a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
+++ b/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -104,7 +104,7 @@ __unregister_atfork (dso_handle)
       atomic_decrement (&deleted->handler->refcntr);
       unsigned int val;
       while ((val = deleted->handler->refcntr) != 0)
-	lll_futex_wait (&deleted->handler->refcntr, val);
+	lll_futex_wait (&deleted->handler->refcntr, val, LLL_PRIVATE);
 
       deleted = deleted->next;
     }
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
index 693387a266..7a09c81194 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -159,9 +159,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;
@@ -177,7 +177,10 @@ typedef union
     unsigned int __nr_writers_queued;
     /* 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;
     int __writer;
   } __data;
 # endif
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
index 3621efa4fc..3265eee0ed 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -17,14 +17,19 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* In libc.so we do not unconditionally use the lock prefix.  Only if
-   the application is using threads.  */
-#ifndef UP
-# define LOCK \
-	cmpl	$0, __libc_multiple_threads(%rip); 			      \
-	je	0f;							      \
-	lock;								      \
-0:
+#include <kernel-features.h>
+
+/* All locks in libc are private.  Use the kernel feature if possible.  */
+#define FUTEX_PRIVATE_FLAG	128
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define FUTEX_WAIT		(0 | FUTEX_PRIVATE_FLAG)
+# define FUTEX_WAKE		(1 | FUTEX_PRIVATE_FLAG)
+#else
+# define LOAD_FUTEX_WAIT(reg) \
+	movl	%fs:PRIVATE_FUTEX, reg
+# define LOAD_FUTEX_WAKE(reg) \
+	movl	%fs:PRIVATE_FUTEX, reg ; \
+	orl	$FUTEX_WAKE, reg
 #endif
 
 #include "lowlevellock.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
index 6724ded762..502f1d442f 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
@@ -31,8 +31,23 @@
 #endif
 
 #define SYS_futex		202
-#define FUTEX_WAIT		0
-#define FUTEX_WAKE		1
+#ifndef FUTEX_WAIT
+# define FUTEX_WAIT		0
+# define FUTEX_WAKE		1
+#endif
+
+#ifndef LOAD_FUTEX_WAIT
+# if FUTEX_WAIT == 0
+#  define LOAD_FUTEX_WAIT(reg) \
+	xorl	reg, reg
+# else
+#  define LOAD_FUTEX_WAIT(reg) \
+	movl	$FUTEX_WAIT, reg
+# endif
+# define LOAD_FUTEX_WAKE(reg) \
+	movl	$FUTEX_WAKE, reg
+#endif
+
 
 /* For the calculation see asm/vsyscall.h.  */
 #define VSYSCALL_ADDR_vgettimeofday	0xffffffffff600000
@@ -52,11 +67,7 @@ __lll_mutex_lock_wait:
 	cfi_offset(%rdx, -24)
 	xorq	%r10, %r10	/* No timeout.  */
 	movl	$2, %edx
-#if FUTEX_WAIT == 0
-	xorl	%esi, %esi
-#else
-	movl	$FUTEX_WAIT, %esi
-#endif
+	LOAD_FUTEX_WAIT (%esi)
 
 	cmpl	%edx, %eax	/* NB:	 %edx == 2 */
 	jne	2f
@@ -151,11 +162,7 @@ __lll_mutex_timedlock_wait:
 	je	8f
 
 	movq	%rsp, %r10
-#if FUTEX_WAIT == 0
-	xorl	%esi, %esi
-#else
-	movl	$FUTEX_WAIT, %esi
-#endif
+	LOAD_FUTEX_WAIT (%esi)
 	movq	%r12, %rdi
 	movl	$SYS_futex, %eax
 	syscall
@@ -213,26 +220,6 @@ __lll_mutex_timedlock_wait:
 #endif
 
 
-#ifdef NOT_IN_libc
-	.globl	lll_unlock_wake_cb
-	.type	lll_unlock_wake_cb,@function
-	.hidden	lll_unlock_wake_cb
-	.align	16
-lll_unlock_wake_cb:
-	pushq	%rsi
-	pushq	%rdx
-
-	LOCK
-	addl	$1, (%rdi)
-	jng	1f
-
-	popq	%rdx
-	popq	%rsi
-	retq
-	.size	lll_unlock_wake_cb,.-lll_unlock_wake_cb
-#endif
-
-
 	.globl	__lll_mutex_unlock_wake
 	.type	__lll_mutex_unlock_wake,@function
 	.hidden	__lll_mutex_unlock_wake
@@ -247,7 +234,7 @@ __lll_mutex_unlock_wake:
 	cfi_offset(%rdx, -24)
 
 	movl	$0, (%rdi)
-	movl	$FUTEX_WAKE, %esi
+	LOAD_FUTEX_WAKE (%esi)
 	movl	$1, %edx	/* Wake one thread.  */
 	movl	$SYS_futex, %eax
 	syscall
@@ -311,6 +298,8 @@ __lll_timedwait_tid:
 	jz	4f
 
 	movq	%rsp, %r10
+	/* XXX The kernel so far uses global futex for the wakeup at
+	   all times.  */
 #if FUTEX_WAIT == 0
 	xorl	%esi, %esi
 #else
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index bb988f3b2b..7ec7deff17 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
@@ -23,6 +23,8 @@
 #include <time.h>
 #include <sys/param.h>
 #include <bits/pthreadtypes.h>
+#include <kernel-features.h>
+#include <tcb-offsets.h>
 
 #ifndef LOCK_INSTR
 # ifdef UP
@@ -39,8 +41,41 @@
 #define FUTEX_LOCK_PI		6
 #define FUTEX_UNLOCK_PI		7
 #define FUTEX_TRYLOCK_PI	8
+#define FUTEX_PRIVATE_FLAG	128
 
 
+/* 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))								      \
+   : ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG);		      \
+	asm ("andl %%fs:%P1, %0" : "+r" (__fl)				      \
+	     : "i" (offsetof (struct pthread, header.private_futex)));	      \
+	__fl | (fl); }))
+# endif	      
+#endif
+
 /* Initializer for compatibility lock.  */
 #define LLL_MUTEX_LOCK_INITIALIZER		(0)
 #define LLL_MUTEX_LOCK_INITIALIZER_LOCKED	(1)
@@ -148,46 +183,39 @@ LLL_STUB_UNWIND_INFO_START					\
 LLL_STUB_UNWIND_INFO_END
 
 
-#define lll_futex_wait(futex, val) \
-  ({									      \
-    int __status;							      \
-    register __typeof (val) _val __asm ("edx") = (val);			      \
-    __asm __volatile ("xorq %%r10, %%r10\n\t"				      \
-		      "syscall"						      \
-		      : "=a" (__status)					      \
-		      : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT),	      \
-			"d" (_val)					      \
-		      : "memory", "cc", "r10", "r11", "cx");		      \
-    __status;								      \
-  })
+#define lll_futex_wait(futex, val, private) \
+  lll_futex_timed_wait(futex, val, NULL, private)
 
 
-#define lll_futex_timed_wait(futex, val, timeout)			      \
+#define lll_futex_timed_wait(futex, val, timeout, private) \
   ({									      \
     register const struct timespec *__to __asm ("r10") = timeout;	      \
     int __status;							      \
     register __typeof (val) _val __asm ("edx") = (val);			      \
     __asm __volatile ("syscall"						      \
 		      : "=a" (__status)					      \
-		      : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT),	      \
+		      : "0" (SYS_futex), "D" (futex),			      \
+			"S" (__lll_private_flag (FUTEX_WAIT, private)),	      \
 		        "d" (_val), "r" (__to)				      \
 		      : "memory", "cc", "r11", "cx");			      \
     __status;								      \
   })
 
 
-#define lll_futex_wake(futex, nr) \
+#define lll_futex_wake(futex, nr, private) \
   do {									      \
     int __ignore;							      \
     register __typeof (nr) _nr __asm ("edx") = (nr);			      \
     __asm __volatile ("syscall"						      \
 		      : "=a" (__ignore)					      \
-		      : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAKE),	      \
+		      : "0" (SYS_futex), "D" (futex),			      \
+			"S" (__lll_private_flag (FUTEX_WAKE, private)),	      \
 			"d" (_nr)					      \
 		      : "memory", "cc", "r10", "r11", "cx");		      \
   } while (0)
 
 
+
 /* Does not preserve %eax and %ecx.  */
 extern int __lll_mutex_lock_wait (int *__futex, int __val) attribute_hidden;
 /* Does not preserver %eax, %ecx, and %edx.  */
@@ -454,9 +482,6 @@ typedef int lll_lock_t;
 #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
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
index fa8125dd87..63771b3840 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -65,9 +65,10 @@ pthread_barrier_wait:
 	   if the CURR_EVENT memory has meanwhile been changed.  */
 7:
 #if FUTEX_WAIT == 0
-	xorl	%esi, %esi
+	movl	PRIVATE(%rdi), %esi
 #else
 	movl	$FUTEX_WAIT, %esi
+	orl	PRIVATE(%rdi), %esi
 #endif
 	xorq	%r10, %r10
 8:	movl	$SYS_futex, %eax
@@ -116,6 +117,7 @@ pthread_barrier_wait:
 	   so 0x7fffffff is the highest value.  */
 	movl	$0x7fffffff, %edx
 	movl	$FUTEX_WAKE, %esi
+	orl	PRIVATE(%rdi), %esi
 	movl	$SYS_futex, %eax
 	syscall
 
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
index ad3ae1e76e..2afd601b8c 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -111,7 +111,7 @@ __pthread_cond_timedwait:
 	movq	8(%rsp), %rdi
 	incq	total_seq(%rdi)
 	incl	cond_futex(%rdi)
-	addl	$(1 << clock_bits), cond_nwaiters(%rdi)
+	addl	$(1 << nwaiters_shift), cond_nwaiters(%rdi)
 
 	/* Install cancellation handler.  */
 #ifdef PIC
@@ -137,7 +137,7 @@ __pthread_cond_timedwait:
 	   structure stores the number minus 1.  */
 	movq	8(%rsp), %rdi
 	movl	cond_nwaiters(%rdi), %edi
-	andl	$((1 << clock_bits) - 1), %edi
+	andl	$((1 << nwaiters_shift) - 1), %edi
 	/* Only clocks 0 and 1 are allowed so far.  Both are handled in the
 	   kernel.  */
 	leaq	24(%rsp), %rsi
@@ -250,13 +250,13 @@ __pthread_cond_timedwait:
 9:	xorq	%r14, %r14
 14:	incq	woken_seq(%rdi)
 
-24:	subl	$(1 << clock_bits), cond_nwaiters(%rdi)
+24:	subl	$(1 << nwaiters_shift), cond_nwaiters(%rdi)
 
 	/* Wake up a thread which wants to destroy the condvar object.  */
 	cmpq	$0xffffffffffffffff, total_seq(%rdi)
 	jne	25f
 	movl	cond_nwaiters(%rdi), %eax
-	andl	$~((1 << clock_bits) - 1), %eax
+	andl	$~((1 << nwaiters_shift) - 1), %eax
 	jne	25f
 
 	addq	$cond_nwaiters, %rdi
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
index 969e80da2a..aaad22e020 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -77,14 +77,14 @@ __condvar_cleanup:
 	incl	cond_futex(%rdi)
 6:	incq	woken_seq(%rdi)
 
-3:	subl	$(1 << clock_bits), cond_nwaiters(%rdi)
+3:	subl	$(1 << nwaiters_shift), cond_nwaiters(%rdi)
 
 	/* Wake up a thread which wants to destroy the condvar object.  */
 	xorq	%r12, %r12
 	cmpq	$0xffffffffffffffff, total_seq(%rdi)
 	jne	4f
 	movl	cond_nwaiters(%rdi), %eax
-	andl	$~((1 << clock_bits) - 1), %eax
+	andl	$~((1 << nwaiters_shift) - 1), %eax
 	jne	4f
 
 	addq	$cond_nwaiters, %rdi
@@ -185,7 +185,7 @@ __pthread_cond_wait:
 	movq	8(%rsp), %rdi
 	incq	total_seq(%rdi)
 	incl	cond_futex(%rdi)
-	addl	$(1 << clock_bits), cond_nwaiters(%rdi)
+	addl	$(1 << nwaiters_shift), cond_nwaiters(%rdi)
 
 	/* Install cancellation handler.  */
 #ifdef PIC
@@ -262,13 +262,13 @@ __pthread_cond_wait:
 	incq	woken_seq(%rdi)
 
 	/* Unlock */
-16:	subl	$(1 << clock_bits), cond_nwaiters(%rdi)
+16:	subl	$(1 << nwaiters_shift), cond_nwaiters(%rdi)
 
 	/* Wake up a thread which wants to destroy the condvar object.  */
 	cmpq	$0xffffffffffffffff, total_seq(%rdi)
 	jne	17f
 	movl	cond_nwaiters(%rdi), %eax
-	andl	$~((1 << clock_bits) - 1), %eax
+	andl	$~((1 << nwaiters_shift) - 1), %eax
 	jne	17f
 
 	addq	$cond_nwaiters, %rdi
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
index 9db5516913..7740c599d1 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -17,14 +17,19 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <kernel-features.h>
+#include <tcb-offsets.h>
+
 #ifndef UP
 # define LOCK lock
 #else
 # define LOCK
 #endif
 
-#define SYS_futex	202
-#define FUTEX_WAKE	1
+#define SYS_futex		202
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 	.comm	__fork_generation, 4, 4
 
@@ -74,10 +79,15 @@ __pthread_once:
 	jnz	3f	/* Different for generation -> run initializer.  */
 
 	/* Somebody else got here first.  Wait.  */
-#if FUTEX_WAIT == 0
-	xorl	%esi, %esi
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_WAIT|FUTEX_PRIVATE_FLAG, %esi
 #else
+# if FUTEX_WAIT == 0
+	movl	%fs:PRIVATE_FUTEX, %esi
+# else
 	movl	$FUTEX_WAIT, %esi
+	orl	%fs:PRIVATE_FUTEX, %esi
+# endif
 #endif
 	movl	$SYS_futex, %eax
 	syscall
@@ -106,7 +116,12 @@ __pthread_once:
 
 	/* Wake up all other threads.  */
 	movl	$0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %esi
+#else
 	movl	$FUTEX_WAKE, %esi
+	orl	%fs:PRIVATE_FUTEX, %esi
+#endif
 	movl	$SYS_futex, %eax
 	syscall
 
@@ -133,7 +148,12 @@ clear_once_control:
 	movl	$0, (%rdi)
 
 	movl	$0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %esi
+#else
 	movl	$FUTEX_WAKE, %esi
+	orl	%fs:PRIVATE_FUTEX, %esi
+#endif
 	movl	$SYS_futex, %eax
 	syscall
 
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
index 5e9d8fb1d6..e8d257502f 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,11 +20,13 @@
 #include <sysdep.h>
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
+#include <kernel-features.h>
 
 
 #define SYS_futex		202
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 #ifndef UP
 # define LOCK lock
@@ -73,12 +75,20 @@ __pthread_rwlock_rdlock:
 #endif
 	jne	10f
 
-11:	addq	$READERS_WAKEUP, %rdi
-#if FUTEX_WAIT == 0
-	xorl	%esi, %esi
+11:
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+	xorl	PSHARED(%rdi), %esi
 #else
+# if FUTEX_WAIT == 0
+	movl	PSHARED(%rdi), %esi
+# else
 	movl	$FUTEX_WAIT, %esi
+	orl	PSHARED(%rdi), %esi
+# endif
+	xorl	%fs:PRIVATE_FUTEX, %esi
 #endif
+	addq	$READERS_WAKEUP, %rdi
 	movl	$SYS_futex, %eax
 	syscall
 
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
index b44660418a..f703eeb29f 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,11 +20,13 @@
 #include <sysdep.h>
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
+#include <kernel-features.h>
 
 
 #define SYS_futex		202
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 /* For the calculation see asm/vsyscall.h.  */
 #define VSYSCALL_ADDR_vgettimeofday	0xffffffffff600000
@@ -112,10 +114,17 @@ pthread_rwlock_timedrdlock:
 	movq	%rcx, (%rsp)	/* Store relative timeout.  */
 	movq	%rdi, 8(%rsp)
 
-#if FUTEX_WAIT == 0
-	xorl	%esi, %esi
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+	xorl	PSHARED(%r12), %esi
 #else
+# if FUTEX_WAIT == 0
+	movl	PSHARED(%r12), %esi
+# else
 	movl	$FUTEX_WAIT, %esi
+	orl	PSHARED(%r12), %esi
+# endif
+	xorl	%fs:PRIVATE_FUTEX, %esi
 #endif
 	movq	%rsp, %r10
 	movl	%r14d, %edx
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
index 525e5b6b93..fc3bf3d69e 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,11 +20,13 @@
 #include <sysdep.h>
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
+#include <kernel-features.h>
 
 
 #define SYS_futex		202
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 /* For the calculation see asm/vsyscall.h.  */
 #define VSYSCALL_ADDR_vgettimeofday	0xffffffffff600000
@@ -108,10 +110,17 @@ pthread_rwlock_timedwrlock:
 	movq	%rcx, (%rsp)	/* Store relative timeout.  */
 	movq	%rdi, 8(%rsp)
 
-#if FUTEX_WAIT == 0
-	xorl	%esi, %esi
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+	xorl	PSHARED(%r12), %esi
 #else
+# if FUTEX_WAIT == 0
+	movl	PSHARED(%r12), %esi
+# else
 	movl	$FUTEX_WAIT, %esi
+	orl	PSHARED(%r12), %esi
+# endif
+	xorl	%fs:PRIVATE_FUTEX, %esi
 #endif
 	movq	%rsp, %r10
 	movl	%r14d, %edx
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
index 3a6b9f0bad..c4597f60f7 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -19,11 +19,13 @@
 
 #include <sysdep.h>
 #include <lowlevelrwlock.h>
+#include <kernel-features.h>
 
 
 #define SYS_futex		202
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 #ifndef UP
 # define LOCK lock
@@ -56,9 +58,8 @@ __pthread_rwlock_unlock:
 
 5:	movl	$0, WRITER(%rdi)
 
-	movl	$1, %esi
+	movl	$1, %edx
 	leaq	WRITERS_WAKEUP(%rdi), %r10
-	movq	%rsi, %rdx
 	cmpl	$0, WRITERS_QUEUED(%rdi)
 	jne	0f
 
@@ -78,7 +79,16 @@ __pthread_rwlock_unlock:
 #endif
 	jne	7f
 
-8:	movl	$SYS_futex, %eax
+8:
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %esi
+	xorl	PSHARED(%rdi), %esi
+#else
+	movl	$FUTEX_WAKE, %esi
+	orl	PSHARED(%rdi), %esi
+	xorl	%fs:PRIVATE_FUTEX, %esi
+#endif
+	movl	$SYS_futex, %eax
 	movq	%r10, %rdi
 	syscall
 
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
index 0e82f890aa..7f65726849 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,11 +20,13 @@
 #include <sysdep.h>
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
+#include <kernel-features.h>
 
 
 #define SYS_futex		202
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_PRIVATE_FLAG	128
 
 #ifndef UP
 # define LOCK lock
@@ -71,12 +73,20 @@ __pthread_rwlock_wrlock:
 #endif
 	jne	10f
 
-11:	addq	$WRITERS_WAKEUP, %rdi
-#if FUTEX_WAIT == 0
-	xorl	%esi, %esi
+11:
+#ifdef __ASSUME_PRIVATE_FUTEX
+	movl	$FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+	xorl	PSHARED(%rdi), %esi
 #else
+# if FUTEX_WAIT == 0
+	movl	PSHARED(%rdi), %esi
+# else
 	movl	$FUTEX_WAIT, %esi
+	orl	PSHARED(%rdi), %esi
+# endif
+	xorl	%fs:PRIVATE_FUTEX, %esi
 #endif
+	addq	$WRITERS_WAKEUP, %rdi
 	movl	$SYS_futex, %eax
 	syscall
 
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
index 7f608a5974..4919c11fd2 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -37,19 +38,26 @@
 	.type	sem_post,@function
 	.align	16
 sem_post:
-	movl	$1, %edx
 	LOCK
-	xaddl	%edx, (%rdi)
+#if VALUE == 0
+	addl	$1, (%rdi)
+#else
+	addl	$1, VALUE(%rdi)
+#endif
+
+	cmpq	$0, NWAITERS(%rdi)
+	je	2f
 
 	movl	$SYS_futex, %eax
 	movl	$FUTEX_WAKE, %esi
-	incl	%edx
+	orl	PRIVATE(%rdi), %esi
+	movl	$1, %edx
 	syscall
 
 	testq	%rax, %rax
 	js	1f
 
-	xorl	%eax, %eax
+2:	xorl	%eax, %eax
 	retq
 
 1:
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
index 8c5c2a6974..4068a1b6b8 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -28,6 +29,7 @@
 #endif
 
 #define SYS_futex		202
+#define FUTEX_WAIT		0
 
 /* For the calculation see asm/vsyscall.h.  */
 #define VSYSCALL_ADDR_vgettimeofday	0xffffffffff600000
@@ -38,15 +40,23 @@
 	.globl	sem_timedwait
 	.type	sem_timedwait,@function
 	.align	16
-	cfi_startproc
 sem_timedwait:
+.LSTARTCODE:
+#if VALUE == 0
 	movl	(%rdi), %eax
+#else
+	movl	VALUE(%rdi), %eax
+#endif
 2:	testl	%eax, %eax
 	je	1f
 
 	leaq	-1(%rax), %rdx
 	LOCK
+#if VALUE == 0
 	cmpxchgl %edx, (%rdi)
+#else
+	cmpxchgl %edx, VALUE(%rdi)
+#endif
 	jne	2b
 
 	xorl	%eax, %eax
@@ -54,25 +64,25 @@ sem_timedwait:
 
 	/* Check whether the timeout value is valid.  */
 1:	pushq	%r12
-	cfi_adjust_cfa_offset(8)
+.Lpush_r12:
 	pushq	%r13
-	cfi_adjust_cfa_offset(8)
+.Lpush_r13:
 	pushq	%r14
-	cfi_adjust_cfa_offset(8)
+.Lpush_r14:
 	subq	$24, %rsp
-	cfi_adjust_cfa_offset(24)
+.Lsubq:
 
 	movq	%rdi, %r12
-	cfi_offset(12, -16)		/* %r12 */
 	movq	%rsi, %r13
-	cfi_offset(13, -24)		/* %r13 */
 
 	/* Check for invalid nanosecond field.  */
 	cmpq	$1000000000, 8(%r13)
 	movl	$EINVAL, %r14d
-	cfi_offset(14, -24)		/* %r14 */
 	jae	6f
 
+	LOCK
+	addq	$1, NWAITERS(%r12)
+
 7:	xorl	%esi, %esi
 	movq	%rsp, %rdi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
@@ -96,12 +106,22 @@ sem_timedwait:
 	movq	%rdi, (%rsp)	/* Store relative timeout.  */
 	movq	%rsi, 8(%rsp)
 
+.LcleanupSTART:
 	call	__pthread_enable_asynccancel
 	movl	%eax, 16(%rsp)
 
 	movq	%rsp, %r10
+#if VALUE == 0
 	movq	%r12, %rdi
-	xorl	%esi, %esi
+#else
+	leaq	VALUE(%r12), %rdi
+#endif
+#if FUTEX_WAIT == 0
+	movl	PRIVATE(%rdi), %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+	orl	PRIVATE(%rdi), %esi
+#endif
 	movl	$SYS_futex, %eax
 	xorl	%edx, %edx
 	syscall
@@ -109,39 +129,47 @@ sem_timedwait:
 
 	movl	16(%rsp), %edi
 	call	__pthread_disable_asynccancel
+.LcleanupEND:
 
 	testq	%r14, %r14
 	je	9f
 	cmpq	$-EWOULDBLOCK, %r14
 	jne	3f
 
-9:	movl	(%r12), %eax
+9:
+#if VALUE == 0
+	movl	(%r12), %eax
+#else
+	movl	VALUE(%r12), %eax
+#endif
 8:	testl	%eax, %eax
 	je	7b
 
 	leaq	-1(%rax), %rcx
 	LOCK
+#if VALUE == 0
 	cmpxchgl %ecx, (%r12)
+#else
+	cmpxchgl %ecx, VALUE(%r12)
+#endif
 	jne	8b
 
 	xorl	%eax, %eax
-10:	addq	$24, %rsp
-	cfi_adjust_cfa_offset(-24)
+
+10:	LOCK
+	subq	$1, NWAITERS(%r12)
+
+	addq	$24, %rsp
+.Laddq:
 	popq	%r14
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(14)
+.Lpop_r14:
 	popq	%r13
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(13)
+.Lpop_r13:
 	popq	%r12
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(12)
+.Lpop_r12:
 	retq
 
-	cfi_adjust_cfa_offset(48)
-	cfi_offset(12, -16)		/* %r12 */
-	cfi_offset(13, -24)		/* %r13 */
-	cfi_offset(14, -32)		/* %r14 */
+.Lafter_retq:
 3:	negq	%r14
 6:
 #if USE___THREAD
@@ -154,5 +182,159 @@ sem_timedwait:
 
 	orl	$-1, %eax
 	jmp	10b
-	cfi_endproc
 	.size	sem_timedwait,.-sem_timedwait
+
+
+	.type	sem_timedwait_cleanup,@function
+sem_timedwait_cleanup:
+	LOCK
+	subq	$1, NWAITERS(%r12)
+	movq	%rax, %rdi
+.LcallUR:
+	call	_Unwind_Resume@PLT
+	hlt
+.LENDCODE:
+	.size	sem_timedwait_cleanup,.-sem_timedwait_cleanup
+
+
+	.section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+	.byte	0xff				# @LPStart format (omit)
+	.byte	0xff				# @TType format (omit)
+	.byte	0x01				# call-site format
+						# DW_EH_PE_uleb128
+	.uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+	.uleb128 .LcleanupSTART-.LSTARTCODE
+	.uleb128 .LcleanupEND-.LcleanupSTART
+	.uleb128 sem_timedwait_cleanup-.LSTARTCODE
+	.uleb128  0
+	.uleb128 .LcallUR-.LSTARTCODE
+	.uleb128 .LENDCODE-.LcallUR
+	.uleb128 0
+	.uleb128  0
+.Lcstend:
+
+
+	.section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+	.long	.LENDCIE-.LSTARTCIE		# Length of the CIE.
+.LSTARTCIE:
+	.long	0				# CIE ID.
+	.byte	1				# Version number.
+#ifdef SHARED
+	.string	"zPLR"				# NUL-terminated augmentation
+						# string.
+#else
+	.string	"zPL"				# NUL-terminated augmentation
+						# string.
+#endif
+	.uleb128 1				# Code alignment factor.
+	.sleb128 -8				# Data alignment factor.
+	.byte	16				# Return address register
+						# column.
+#ifdef SHARED
+	.uleb128 7				# Augmentation value length.
+	.byte	0x9b				# Personality: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4
+						# + DW_EH_PE_indirect
+	.long	DW.ref.__gcc_personality_v0-.
+	.byte	0x1b				# LSDA Encoding: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4.
+	.byte	0x1b				# FDE Encoding: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4.
+#else
+	.uleb128 10				# Augmentation value length.
+	.byte	0x0				# Personality: absolute
+	.quad	__gcc_personality_v0
+	.byte	0x0				# LSDA Encoding: absolute
+#endif
+	.byte 0x0c				# DW_CFA_def_cfa
+	.uleb128 7
+	.uleb128 8
+	.byte	0x90				# DW_CFA_offset, column 0x10
+	.uleb128 1
+	.align 8
+.LENDCIE:
+
+	.long	.LENDFDE-.LSTARTFDE		# Length of the FDE.
+.LSTARTFDE:
+	.long	.LSTARTFDE-.LSTARTFRAME		# CIE pointer.
+#ifdef SHARED
+	.long	.LSTARTCODE-.			# PC-relative start address
+						# of the code.
+	.long	.LENDCODE-.LSTARTCODE		# Length of the code.
+	.uleb128 4				# Augmentation size
+	.long	.LexceptSTART-.
+#else
+	.quad	.LSTARTCODE			# Start address of the code.
+	.quad	.LENDCODE-.LSTARTCODE		# Length of the code.
+	.uleb128 8				# Augmentation size
+	.quad	.LexceptSTART
+#endif
+
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpush_r12-.LSTARTCODE
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 16
+	.byte   0x8c				# DW_CFA_offset %r12
+        .uleb128 2
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpush_r13-.Lpush_r12
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 24
+	.byte   0x8d				# DW_CFA_offset %r13
+        .uleb128 3
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpush_r14-.Lpush_r13
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 32
+	.byte   0x8e				# DW_CFA_offset %r14
+        .uleb128 4
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lsubq-.Lpush_r14
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 56
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Laddq-.Lsubq
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 32
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpop_r14-.Laddq
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 24
+	.byte	0xce				# DW_CFA_restore %r14
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpop_r13-.Lpop_r14
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 16
+	.byte	0xcd				# DW_CFA_restore %r13
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpop_r12-.Lpop_r13
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 8
+	.byte	0xcc				# DW_CFA_restore %r12
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lafter_retq-.Lpop_r12
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 56
+	.byte   0x8c				# DW_CFA_offset %r12
+        .uleb128 2
+	.byte   0x8d				# DW_CFA_offset %r13
+        .uleb128 3
+	.byte   0x8e				# DW_CFA_offset %r14
+        .uleb128 4
+	.align	8
+.LENDFDE:
+
+
+#ifdef SHARED
+	.hidden	DW.ref.__gcc_personality_v0
+	.weak	DW.ref.__gcc_personality_v0
+	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+	.align	8
+	.type	DW.ref.__gcc_personality_v0, @object
+	.size	DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+	.quad	__gcc_personality_v0
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
index 6b77dfc0d8..643090f065 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -37,7 +37,7 @@ sem_trywait:
 2:	testl	%eax, %eax
 	jz	1f
 
-	leaq	-1(%rax), %rdx
+	leal	-1(%rax), %edx
 	LOCK
 	cmpxchgl %edx, (%rdi)
 	jne	2b
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
index 5bd78eb944..e099ede029 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <pthread-errnos.h>
+#include <structsem.h>
 
 #ifndef UP
 # define LOCK lock
@@ -28,6 +29,7 @@
 #endif
 
 #define SYS_futex		202
+#define FUTEX_WAIT		0
 
 
 	.text
@@ -35,57 +37,93 @@
 	.globl	sem_wait
 	.type	sem_wait,@function
 	.align	16
-	cfi_startproc
 sem_wait:
+.LSTARTCODE:
 	pushq	%r12
-	cfi_adjust_cfa_offset(8)
-	cfi_offset(12, -16)
+.Lpush_r12:
 	pushq	%r13
-	cfi_adjust_cfa_offset(8)
+.Lpush_r13:
 	movq	%rdi, %r13
-	cfi_offset(13, -24)
 
-3:	movl	(%r13), %eax
+#if VALUE == 0
+	movl	(%r13), %eax
+#else
+	movl	VALUE(%r13), %eax
+#endif
 2:	testl	%eax, %eax
 	je	1f
 
-	leaq	-1(%rax), %rdx
+	leal	-1(%rax), %edx
 	LOCK
+#if VALUE == 0
 	cmpxchgl %edx, (%r13)
+#else
+	cmpxchgl %edx, VALUE(%r13)
+#endif
 	jne	2b
-	xorl	%eax, %eax
 
-	popq	%r13
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(13)
+7:	xorl	%eax, %eax
+
+9:	popq	%r13
+.Lpop_r13:
 	popq	%r12
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(12)
+.Lpop_r12:
 
 	retq
 
-	cfi_adjust_cfa_offset(16)
-	cfi_offset(12, -16)
-	cfi_offset(13, -24)
-1:	call	__pthread_enable_asynccancel
+.Lafter_retq:
+1:	LOCK
+	addq	$1, NWAITERS(%r13)
+
+.LcleanupSTART:
+6:	call	__pthread_enable_asynccancel
 	movl	%eax, %r8d
 
 	xorq	%r10, %r10
 	movl	$SYS_futex, %eax
 	movq	%r13, %rdi
-	movq	%r10, %rsi
-	movq	%r10, %rdx
+#if FUTEX_WAIT == 0
+	movl	PRIVATE(%rdi), %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+	orl	PRIVATE(%rdi), %esi
+#endif
+	xorl	%edx, %edx
 	syscall
 	movq	%rax, %r12
 
 	movl	%r8d, %edi
 	call	__pthread_disable_asynccancel
+.LcleanupEND:
 
 	testq	%r12, %r12
-	je	3b
+	je	3f
 	cmpq	$-EWOULDBLOCK, %r12
-	je	3b
-	negq	%r12
+	jne	4f
+
+3:
+#if VALUE == 0
+	movl	(%r13), %eax
+#else
+	movl	VALUE(%r13), %eax
+#endif
+5:	testl	%eax, %eax
+	je	6b
+
+	leal	-1(%rax), %edx
+	LOCK
+#if VALUE == 0
+	cmpxchgl %edx, (%r13)
+#else
+	cmpxchgl %edx, VALUE(%r13)
+#endif
+	jne	5b
+
+	LOCK
+	subq	$1, NWAITERS(%r13)
+	jmp	7b
+
+4:	negq	%r12
 #if USE___THREAD
 	movq	errno@gottpoff(%rip), %rdx
 	movl	%r12d, %fs:(%rdx)
@@ -95,13 +133,142 @@ sem_wait:
 #endif
 	orl	$-1, %eax
 
-	popq	%r13
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(13)
-	popq	%r12
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(12)
+	LOCK
+	subq	$1, NWAITERS(%r13)
 
-	retq
-	cfi_endproc
+	jmp 9b
 	.size	sem_wait,.-sem_wait
+
+
+	.type	sem_wait_cleanup,@function
+sem_wait_cleanup:
+	LOCK
+	subq	$1, NWAITERS(%r13)
+	movq	%rax, %rdi
+.LcallUR:
+	call	_Unwind_Resume@PLT
+	hlt
+.LENDCODE:
+	.size	sem_wait_cleanup,.-sem_wait_cleanup
+
+
+	.section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+	.byte	0xff				# @LPStart format (omit)
+	.byte	0xff				# @TType format (omit)
+	.byte	0x01				# call-site format
+						# DW_EH_PE_uleb128
+	.uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+	.uleb128 .LcleanupSTART-.LSTARTCODE
+	.uleb128 .LcleanupEND-.LcleanupSTART
+	.uleb128 sem_wait_cleanup-.LSTARTCODE
+	.uleb128  0
+	.uleb128 .LcallUR-.LSTARTCODE
+	.uleb128 .LENDCODE-.LcallUR
+	.uleb128 0
+	.uleb128  0
+.Lcstend:
+
+
+	.section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+	.long	.LENDCIE-.LSTARTCIE		# Length of the CIE.
+.LSTARTCIE:
+	.long	0				# CIE ID.
+	.byte	1				# Version number.
+#ifdef SHARED
+	.string	"zPLR"				# NUL-terminated augmentation
+						# string.
+#else
+	.string	"zPL"				# NUL-terminated augmentation
+						# string.
+#endif
+	.uleb128 1				# Code alignment factor.
+	.sleb128 -8				# Data alignment factor.
+	.byte	16				# Return address register
+						# column.
+#ifdef SHARED
+	.uleb128 7				# Augmentation value length.
+	.byte	0x9b				# Personality: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4
+						# + DW_EH_PE_indirect
+	.long	DW.ref.__gcc_personality_v0-.
+	.byte	0x1b				# LSDA Encoding: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4.
+	.byte	0x1b				# FDE Encoding: DW_EH_PE_pcrel
+						# + DW_EH_PE_sdata4.
+#else
+	.uleb128 10				# Augmentation value length.
+	.byte	0x0				# Personality: absolute
+	.quad	__gcc_personality_v0
+	.byte	0x0				# LSDA Encoding: absolute
+#endif
+	.byte 0x0c				# DW_CFA_def_cfa
+	.uleb128 7
+	.uleb128 8
+	.byte	0x90				# DW_CFA_offset, column 0x10
+	.uleb128 1
+	.align 8
+.LENDCIE:
+
+	.long	.LENDFDE-.LSTARTFDE		# Length of the FDE.
+.LSTARTFDE:
+	.long	.LSTARTFDE-.LSTARTFRAME		# CIE pointer.
+#ifdef SHARED
+	.long	.LSTARTCODE-.			# PC-relative start address
+						# of the code.
+	.long	.LENDCODE-.LSTARTCODE		# Length of the code.
+	.uleb128 4				# Augmentation size
+	.long	.LexceptSTART-.
+#else
+	.quad	.LSTARTCODE			# Start address of the code.
+	.quad	.LENDCODE-.LSTARTCODE		# Length of the code.
+	.uleb128 8				# Augmentation size
+	.quad	.LexceptSTART
+#endif
+
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpush_r12-.LSTARTCODE
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 16
+	.byte   0x8c				# DW_CFA_offset %r12
+        .uleb128 2
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpush_r13-.Lpush_r12
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 24
+	.byte   0x8d				# DW_CFA_offset %r13
+        .uleb128 3
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpop_r13-.Lpush_r13
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 16
+	.byte	0xcd				# DW_CFA_restore %r13
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpop_r12-.Lpop_r13
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 8
+	.byte	0xcc				# DW_CFA_restore %r12
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lafter_retq-.Lpop_r12
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 24
+	.byte   0x8c				# DW_CFA_offset %r12
+        .uleb128 2
+	.byte   0x8d				# DW_CFA_offset %r13
+        .uleb128 3
+	.align	8
+.LENDFDE:
+
+
+#ifdef SHARED
+	.hidden	DW.ref.__gcc_personality_v0
+	.weak	DW.ref.__gcc_personality_v0
+	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+	.align	8
+	.type	DW.ref.__gcc_personality_v0, @object
+	.size	DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+	.quad	__gcc_personality_v0
+#endif
diff --git a/nptl/sysdeps/x86_64/tcb-offsets.sym b/nptl/sysdeps/x86_64/tcb-offsets.sym
index 21274ecab9..1c70c6bde7 100644
--- a/nptl/sysdeps/x86_64/tcb-offsets.sym
+++ b/nptl/sysdeps/x86_64/tcb-offsets.sym
@@ -12,3 +12,6 @@ MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
 MULTIPLE_THREADS_OFFSET	offsetof (tcbhead_t, multiple_threads)
 POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
 VGETCPU_CACHE_OFFSET	offsetof (tcbhead_t, vgetcpu_cache)
+#ifndef __ASSUME_PRIVATE_FUTEX
+PRIVATE_FUTEX		offsetof (tcbhead_t, private_futex)
+#endif
diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
index 4a614c02af..79db61c709 100644
--- a/nptl/sysdeps/x86_64/tls.h
+++ b/nptl/sysdeps/x86_64/tls.h
@@ -26,6 +26,8 @@
 # include <stddef.h>
 # include <stdint.h>
 # include <stdlib.h>
+# include <sysdep.h>
+# include <kernel-features.h>
 
 
 /* Type for the dtv.  */
@@ -52,6 +54,9 @@ typedef struct
   uintptr_t stack_guard;
   uintptr_t pointer_guard;
   unsigned long int vgetcpu_cache[2];
+#ifndef __ASSUME_PRIVATE_FUTEX
+  int private_futex;
+#endif
 } tcbhead_t;
 
 #else /* __ASSEMBLER__ */
@@ -350,7 +355,7 @@ typedef struct
 		    : "i" (offsetof (struct pthread, header.gscope_flag)),    \
 		      "0" (THREAD_GSCOPE_FLAG_UNUSED));			      \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)				      \
-	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		      \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);    \
     }									      \
   while (0)
 #define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/tst-initializers1.c b/nptl/tst-initializers1.c
index eacee35c61..9036e6eac3 100644
--- a/nptl/tst-initializers1.c
+++ b/nptl/tst-initializers1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2005.
 
@@ -37,15 +37,15 @@ main (void)
   if (mtx_normal.__data.__kind != PTHREAD_MUTEX_TIMED_NP)
     return 1;
   if (mtx_recursive.__data.__kind != PTHREAD_MUTEX_RECURSIVE_NP)
-    return 1;
+    return 2;
   if (mtx_errorchk.__data.__kind != PTHREAD_MUTEX_ERRORCHECK_NP)
-    return 1;
+    return 3;
   if (mtx_adaptive.__data.__kind != PTHREAD_MUTEX_ADAPTIVE_NP)
-    return 1;
+    return 4;
   if (rwl_normal.__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP)
-    return 1;
+    return 5;
   if (rwl_writer.__data.__flags
       != PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)
-    return 1;
+    return 6;
   return 0;
 }
diff --git a/nptl/tst-locale2.c b/nptl/tst-locale2.c
index c8821ad6b8..a238209f87 100644
--- a/nptl/tst-locale2.c
+++ b/nptl/tst-locale2.c
@@ -11,4 +11,5 @@ useless (void *a)
 {
   pthread_t th;
   pthread_create (&th, 0, useless, a);
+  return NULL;
 }
diff --git a/nptl/tst-sem11.c b/nptl/tst-sem11.c
new file mode 100644
index 0000000000..6633ddd1f3
--- /dev/null
+++ b/nptl/tst-sem11.c
@@ -0,0 +1,76 @@
+#include <semaphore.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <internaltypes.h>
+
+#ifndef SEM_WAIT
+# define SEM_WAIT(s) sem_wait (s)
+#endif
+
+static void *
+tf (void *arg)
+{
+#ifdef PREPARE
+  PREPARE
+#endif
+  SEM_WAIT (arg);
+  return NULL;
+}
+
+int
+main (void)
+{
+  int tries = 5;
+  pthread_t th;
+  sem_t s;
+ again:
+  if (sem_init (&s, 0, 0) != 0)
+    {
+      puts ("sem_init failed");
+      return 1;
+    }
+
+  struct new_sem *is = (struct new_sem *) &s;
+
+  if (is->nwaiters != 0)
+    {
+      puts ("nwaiters not initialized");
+      return 1;
+    }
+
+  if (pthread_create (&th, NULL, tf, &s) != 0)
+    {
+      puts ("pthread_create failed");
+      return 1;
+    }
+
+  sleep (1);
+
+  if (pthread_cancel (th) != 0)
+    {
+      puts ("pthread_cancel failed");
+      return 1;
+    }
+
+  void *r;
+  if (pthread_join (th, &r) != 0)
+    {
+      puts ("pthread_join failed");
+      return 1;
+    }
+  if (r != PTHREAD_CANCELED && --tries > 0)
+    {
+      /* Maybe we get the scheduling right the next time.  */
+      sem_destroy (&s);
+      goto again;
+    }
+
+  if (is->nwaiters != 0)
+    {
+      puts ("nwaiters not reset");
+      return 1;
+    }
+
+  return 0;
+}
diff --git a/nptl/tst-sem12.c b/nptl/tst-sem12.c
new file mode 100644
index 0000000000..71d02b70e9
--- /dev/null
+++ b/nptl/tst-sem12.c
@@ -0,0 +1,14 @@
+#include <time.h>
+#include <sys/time.h>
+
+
+#define PREPARE \
+  struct timespec ts; \
+  struct timeval tv; \
+  gettimeofday (&tv, NULL); \
+  TIMEVAL_TO_TIMESPEC (&tv, &ts); \
+  ts.tv_sec += 60;
+
+#define SEM_WAIT(s) sem_timedwait (s, &ts)
+
+#include "tst-sem11.c"
diff --git a/nptl/tst-typesizes.c b/nptl/tst-typesizes.c
index db8936f5f4..17a1e297d3 100644
--- a/nptl/tst-typesizes.c
+++ b/nptl/tst-typesizes.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
 
@@ -59,7 +59,8 @@ do_test (void)
   TEST_TYPE2 (pthread_rwlockattr_t, struct pthread_rwlockattr);
   TEST_TYPE2 (pthread_barrier_t, struct pthread_barrier);
   TEST_TYPE2 (pthread_barrierattr_t, struct pthread_barrierattr);
-  TEST_TYPE2 (sem_t, struct sem);
+  TEST_TYPE2 (sem_t, struct new_sem);
+  TEST_TYPE2 (sem_t, struct old_sem);
 
   return result;
 }