about summary refs log tree commit diff
path: root/nptl
diff options
context:
space:
mode:
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog209
-rw-r--r--nptl/Makefile10
-rw-r--r--nptl/allocatestack.c59
-rw-r--r--nptl/descr.h3
-rw-r--r--nptl/init.c4
-rw-r--r--nptl/pthreadP.h4
-rw-r--r--nptl/pthread_getattr_np.c10
-rw-r--r--nptl/pthread_mutex_lock.c4
-rw-r--r--nptl/pthread_mutex_timedlock.c8
-rw-r--r--nptl/pthread_mutex_trylock.c8
-rw-r--r--nptl/shlib-versions2
-rw-r--r--nptl/sysdeps/alpha/tls.h25
-rw-r--r--nptl/sysdeps/i386/tls.h23
-rw-r--r--nptl/sysdeps/ia64/tls.h25
-rw-r--r--nptl/sysdeps/powerpc/tls.h25
-rw-r--r--nptl/sysdeps/s390/tls.h26
-rw-r--r--nptl/sysdeps/sh/tls.h25
-rw-r--r--nptl/sysdeps/sparc/tls.h25
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.c9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c22
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread_kill.c18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h153
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/x86_64/tls.h23
-rw-r--r--nptl/tst-cancel-wrappers.sh3
-rw-r--r--nptl/tst-cancel4.c44
-rw-r--r--nptl/tst-robust9.c94
-rw-r--r--nptl/tst-robustpi9.c2
-rw-r--r--nptl/tst-sem10.c88
42 files changed, 997 insertions, 61 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 4a22f0e75c..1bc6c2d5bc 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,212 @@
+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-05-28  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/i386/tls.h (THREAD_GSCOPE_RESET_FLAG): Use explicit
+	insn suffix.
+	(THREAD_GSCOPE_GET_FLAG): Remove.
+	* sysdeps/x86_64/tls.h (THREAD_GSCOPE_GET_FLAG): Remove.
+	* allocatestack.c (__wait_lookup_done): Revert 2007-05-24
+	changes.
+	* sysdeps/powerpc/tls.h (tcbhead_t): Remove gscope_flag.
+	(THREAD_GSCOPE_GET_FLAG): Remove.
+	(THREAD_GSCOPE_RESET_FLAG): Use THREAD_SELF->header.gscope_flag
+	instead of THREAD_GSCOPE_GET_FLAG.
+	(THREAD_GSCOPE_SET_FLAG): Likewise.  Add atomic_write_barrier after
+	it.
+	* sysdeps/s390/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
+	THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_WAIT): Define.
+	* sysdeps/sparc/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
+	THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_WAIT): Define.
+	* sysdeps/sh/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
+	THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_WAIT): Define.
+	* sysdeps/ia64/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
+	THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_WAIT): Define.
+
+2007-05-24  Richard Henderson  <rth@redhat.com>
+
+	* descr.h (struct pthread): Add header.gscope_flag.
+	* sysdeps/alpha/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
+	THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_WAIT): Define.
+
+2007-05-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* allocatestack.c: Revert last change.
+	* init.c: Likewise.
+	* sysdeps/i386/tls.h: Likewise.
+	* sysdeps/x86_64/tls.h: Likewise.
+
+2007-05-24  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/powerpc/tls.h (tcbhead_t): Add gscope_flag.
+	(THREAD_GSCOPE_FLAG_UNUSED, THREAD_GSCOPE_FLAG_USED,
+	THREAD_GSCOPE_FLAG_WAIT): Define.
+	(THREAD_GSCOPE_GET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_WAIT): Define.
+	* sysdeps/i386/tls.h (THREAD_GSCOPE_WAIT): Don't use
+	PTR_DEMANGLE.
+	(THREAD_GSCOPE_GET_FLAG): Define.
+	* sysdeps/x86_64/tls.h (THREAD_GSCOPE_GET_FLAG): Define.
+	* allocatestack.c (__wait_lookup_done): Use THREAD_GSCOPE_GET_FLAG
+	instead of ->header.gscope_flag directly.
+
+2007-05-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread-functions.h (struct pthread_functions):
+	Remove ptr_wait_lookup_done again.
+	* init.c (pthread_functions): Don't add .ptr_wait_lookup_done here.
+	(__pthread_initialize_minimal_internal): Initialize
+	_dl_wait_lookup_done pointer in _rtld_global directly.
+	* sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init):
+	Remove code to code _dl_wait_lookup_done.
+	* sysdeps/x86_64/tls.h (THREAD_GSCOPE_WAIT): The pointer is not
+	encrypted for now.
+
+2007-05-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* allocatestack.c (__wait_lookup_done): New function.
+	* sysdeps/pthread/pthread-functions.h (struct pthread_functions):
+	Add ptr_wait_lookup_done.
+	* init.c (pthread_functions): Initialize .ptr_wait_lookup_done.
+	* pthreadP.h: Declare __wait_lookup_done.
+	* sysdeps/i386/tls.h (tcbhead_t): Add gscope_flag.
+	Define macros to implement reference handling of global scope.
+	* sysdeps/x86_64/tls.h: Likewise.
+	* sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init):
+	Initialize GL(dl_wait_lookup_done).
+
+2006-12-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h
+	(__rtld_mrlock_initialize): Add missing closing parenthesis.
+
+2006-10-29  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (RTLD_SINGLE_THREAD_P):
+	Define.
+	(SINGLE_THREAD_P): Define to 1 if IS_IN_rtld.
+	* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Likewise.
+
+2006-10-27  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h (__rtld_mrlock_lock,
+	__rtld_mrlock_change): Update oldval if atomic compare and exchange
+	failed.
+
+	* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (SINGLE_THREAD_P):
+	Define to THREAD_SELF->header.multiple_threads.
+	* sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (SINGLE_THREAD_P):
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (SINGLE_THREAD_P):
+	Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (SINGLE_THREAD_P):
+	Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (SINGLE_THREAD_P):
+	Likewise.
+
+2006-10-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h: New file..
+
+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]
+	* pthread_mutex_lock.c: Preserve FUTEX_WAITERS bit when dead owner
+	is detected.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	Patch in part by Atsushi Nemoto <anemo@mba.ocn.ne.jp>.
+
+	* Makefile (tests): Add tst-robust9 and tst-robustpi9.
+	* tst-robust9.c: New file.
+	* tst-robustpi9.c: New file.
+
+2007-05-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+	(__lll_robust_lock_wait): Fix race caused by reloading of futex value.
+	(__lll_robust_timedlock_wait): Likewise.
+	Reported by Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>.
+
+2007-05-06  Mike Frysinger  <vapier@gentoo.org>
+
+	[BZ #4465]
+	* tst-cancel-wrappers.sh: Set C["fdatasync"] to 1.
+	* tst-cancel4.c (tf_fdatasync): New test.
+
+2007-02-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/fork.c (__libc_fork): Reset refcntr in
+	new thread, don't just decrement it.
+	Patch by Suzuki K P <suzuki@in.ibm.com>.
+
+2007-02-09  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+	(__lll_mutex_timedlock_wait): Use correct pointer when we don't
+	call into the kernel to delay.
+
+2006-12-28  David S. Miller  <davem@davemloft.net>
+
+	* shlib-versions: Fix sparc64 linux target specification.
+
+2006-12-21  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/pthread_kill.c (pthread_kill): Make sure
+	tid isn't reread from pd->tid in between ESRCH test and the syscall.
+
 2006-10-08  Jakub Jelinek  <jakub@redhat.com>
 
 	* sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstack.c: New file.
diff --git a/nptl/Makefile b/nptl/Makefile
index ef12a80689..7ccdd18409 100644
--- a/nptl/Makefile
+++ b/nptl/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.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -209,16 +209,16 @@ tests = tst-typesizes \
 	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
 	tst-cond20 tst-cond21 tst-cond22 \
 	tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
-	tst-robust6 tst-robust7 tst-robust8 \
-	tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 \
-	tst-robustpi5 tst-robustpi6 tst-robustpi7 tst-robustpi8 \
+	tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
+	tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
+	tst-robustpi6 tst-robustpi7 tst-robustpi8 tst-robustpi9 \
 	tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
 	tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
 	tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
 	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-sem8 tst-sem9 tst-sem10 \
 	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 c05cd47dff..736c63d69f 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.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.
 
@@ -982,3 +982,60 @@ __pthread_init_static_tls (struct link_map *map)
 
   lll_unlock (stack_cache_lock);
 }
+
+
+void
+attribute_hidden
+__wait_lookup_done (void)
+{
+  lll_lock (stack_cache_lock);
+
+  struct pthread *self = THREAD_SELF;
+
+  /* Iterate over the list with system-allocated threads first.  */
+  list_t *runp;
+  list_for_each (runp, &stack_used)
+    {
+      struct pthread *t = list_entry (runp, struct pthread, list);
+      if (t == self || t->header.gscope_flag == THREAD_GSCOPE_FLAG_UNUSED)
+	continue;
+
+      int *const gscope_flagp = &t->header.gscope_flag;
+
+      /* We have to wait until this thread is done with the global
+	 scope.  First tell the thread that we are waiting and
+	 possibly have to be woken.  */
+      if (atomic_compare_and_exchange_bool_acq (gscope_flagp,
+						THREAD_GSCOPE_FLAG_WAIT,
+						THREAD_GSCOPE_FLAG_USED))
+	continue;
+
+      do
+	lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT);
+      while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
+    }
+
+  /* Now the list with threads using user-allocated stacks.  */
+  list_for_each (runp, &__stack_user)
+    {
+      struct pthread *t = list_entry (runp, struct pthread, list);
+      if (t == self || t->header.gscope_flag == THREAD_GSCOPE_FLAG_UNUSED)
+	continue;
+
+      int *const gscope_flagp = &t->header.gscope_flag;
+
+      /* We have to wait until this thread is done with the global
+	 scope.  First tell the thread that we are waiting and
+	 possibly have to be woken.  */
+      if (atomic_compare_and_exchange_bool_acq (gscope_flagp,
+						THREAD_GSCOPE_FLAG_WAIT,
+						THREAD_GSCOPE_FLAG_USED))
+	continue;
+
+      do
+	lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT);
+      while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
+    }
+
+  lll_unlock (stack_cache_lock);
+}
diff --git a/nptl/descr.h b/nptl/descr.h
index 321ce85085..241ba527ed 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -131,6 +131,7 @@ struct pthread
     struct
     {
       int multiple_threads;
+      int gscope_flag;
     } header;
 #endif
 
diff --git a/nptl/init.c b/nptl/init.c
index 14441153b8..7144abd3fb 100644
--- a/nptl/init.c
+++ b/nptl/init.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.
 
@@ -386,6 +386,8 @@ __pthread_initialize_minimal_internal (void)
 
   GL(dl_init_static_tls) = &__pthread_init_static_tls;
 
+  GL(dl_wait_lookup_done) = &__wait_lookup_done;
+
   /* Register the fork generation counter with the libc.  */
 #ifndef TLS_MULTIPLE_THREADS_IN_TCB
   __libc_multiple_threads_ptr =
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index f9634ab0ff..21ce6fe0b7 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.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.
 
@@ -545,6 +545,8 @@ extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
 
 extern void __free_stack_cache (void) attribute_hidden;
 
+extern void __wait_lookup_done (void) attribute_hidden;
+
 #ifdef SHARED
 # define PTHREAD_STATIC_FN_REQUIRE(name)
 #else
diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c
index 4bdc7b5b15..f6cd8899d8 100644
--- a/nptl/pthread_getattr_np.c
+++ b/nptl/pthread_getattr_np.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.
 
@@ -168,8 +168,12 @@ pthread_getattr_np (thread_id, attr)
 	{
 	  free (cpuset);
 	  if (ret == ENOSYS)
-	    /* There is no such functionality.  */
-	    ret = 0;
+	    {	  
+	      /* There is no such functionality.  */
+	      ret = 0;
+	      iattr->cpuset = NULL;
+	      iattr->cpusetsize = 0;
+	    }
 	}
     }
 
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index 52cc47f4cc..1c3ee4fe25 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.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.
 
@@ -127,6 +127,8 @@ __pthread_mutex_lock (mutex)
 	      int newval = id;
 #ifdef NO_INCR
 	      newval |= FUTEX_WAITERS;
+#else
+	      newval |= (oldval & FUTEX_WAITERS);
 #endif
 
 	      newval
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index c8e6b8507a..8fd681c6ef 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.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.
 
@@ -119,9 +119,11 @@ pthread_mutex_timedlock (mutex, abstime)
 	  if ((oldval & FUTEX_OWNER_DIED) != 0)
 	    {
 	      /* The previous owner died.  Try locking the mutex.  */
-	      int newval
+	      int newval = id | (oldval & FUTEX_WAITERS);
+
+	      newval
 		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
-						       id, oldval);
+						       newval, oldval);
 	      if (newval != oldval)
 		{
 		  oldval = newval;
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 94d519233b..66aca8e4b2 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.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.
 
@@ -91,9 +91,11 @@ __pthread_mutex_trylock (mutex)
 	  if ((oldval & FUTEX_OWNER_DIED) != 0)
 	    {
 	      /* The previous owner died.  Try locking the mutex.  */
-	      int newval
+	      int newval = id | (oldval & FUTEX_WAITERS);
+
+	      newval
 		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
-						       id, oldval);
+						       newval, oldval);
 
 	      if (newval != oldval)
 		{
diff --git a/nptl/shlib-versions b/nptl/shlib-versions
index 5e18753be2..06ac620f06 100644
--- a/nptl/shlib-versions
+++ b/nptl/shlib-versions
@@ -1,5 +1,5 @@
 mips.*-.*-linux.*	libpthread=0		GLIBC_2.0 GLIBC_2.2
-sparc64-.*-linux.*	libpthread=0		GLIBC_2.2
+sparc64.*-.*-linux.*	libpthread=0		GLIBC_2.2
 sh.*-.*-linux.*		libpthread=0		GLIBC_2.2
 ia64.*-.*-linux.*	libpthread=0		GLIBC_2.2
 hppa.*-.*-linux.*	libpthread=0		GLIBC_2.2
diff --git a/nptl/sysdeps/alpha/tls.h b/nptl/sysdeps/alpha/tls.h
index 20f780c5f5..07db15939d 100644
--- a/nptl/sysdeps/alpha/tls.h
+++ b/nptl/sysdeps/alpha/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  NPTL/Alpha version.
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -124,6 +124,29 @@ typedef struct
 #define THREAD_SETMEM_NC(descr, member, idx, value) \
   descr->member[idx] = (value)
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= 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);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h
index a870a848cf..b3d9142fc5 100644
--- a/nptl/sysdeps/i386/tls.h
+++ b/nptl/sysdeps/i386/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  nptl/i386 version.
-   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.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -51,6 +51,7 @@ typedef struct
   uintptr_t sysinfo;
   uintptr_t stack_guard;
   uintptr_t pointer_guard;
+  int gscope_flag;
 } tcbhead_t;
 
 # define TLS_MULTIPLE_THREADS_IN_TCB 1
@@ -434,6 +435,26 @@ union user_desc_init
    = THREAD_GETMEM (THREAD_SELF, header.pointer_guard))
 
 
+/* Get and set the global scope generation counter in the TCB head.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									      \
+    { int __res;							      \
+      asm volatile ("xchgl %0, %%gs:%P1"				      \
+		    : "=r" (__res)					      \
+		    : "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);		      \
+    }									      \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/ia64/tls.h b/nptl/sysdeps/ia64/tls.h
index 69101ad8c4..a43f096798 100644
--- a/nptl/sysdeps/ia64/tls.h
+++ b/nptl/sysdeps/ia64/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  nptl/IA-64 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.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -166,6 +166,29 @@ register struct pthread *__thread_self __asm__("r13");
   (((uintptr_t *) ((char *) (descr) + TLS_PRE_TCB_SIZE))[-2] \
    = THREAD_GET_POINTER_GUARD ())
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= 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);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/powerpc/tls.h b/nptl/sysdeps/powerpc/tls.h
index 976a271362..ad5698c6f8 100644
--- a/nptl/sysdeps/powerpc/tls.h
+++ b/nptl/sysdeps/powerpc/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  NPTL/PowerPC version.
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -183,6 +183,29 @@ register void *__thread_register __asm__ ("r13");
    different value to mean unset l_tls_offset.  */
 # define NO_TLS_OFFSET		-1
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= 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);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/s390/tls.h b/nptl/sysdeps/s390/tls.h
index 89ff095d52..8e8f86d64e 100644
--- a/nptl/sysdeps/s390/tls.h
+++ b/nptl/sysdeps/s390/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  NPTL/s390 version.
-   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
@@ -50,6 +50,7 @@ typedef struct
   int multiple_threads;
   uintptr_t sysinfo;
   uintptr_t stack_guard;
+  int gscope_flag;
 } tcbhead_t;
 
 # ifndef __s390x__
@@ -171,6 +172,29 @@ typedef struct
 #define THREAD_SET_POINTER_GUARD(value)
 #define THREAD_COPY_POINTER_GUARD(descr)
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= 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);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/sh/tls.h b/nptl/sysdeps/sh/tls.h
index 49d105518a..2873fe73a8 100644
--- a/nptl/sysdeps/sh/tls.h
+++ b/nptl/sysdeps/sh/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  NPTL/SH version.
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -153,6 +153,29 @@ typedef struct
      __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));			      \
      ((tcbhead_t *) (descr + 1))->pointer_guard	= __tcbp->pointer_guard;})
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= 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);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/sparc/tls.h b/nptl/sysdeps/sparc/tls.h
index 127bbf695f..a008f29055 100644
--- a/nptl/sysdeps/sparc/tls.h
+++ b/nptl/sysdeps/sparc/tls.h
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  NPTL/sparc version.
-   Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 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
@@ -144,6 +144,29 @@ register struct pthread *__thread_self __asm__("%g7");
 # define THREAD_COPY_POINTER_GUARD(descr) \
   ((descr)->header.pointer_guard = THREAD_GET_POINTER_GUARD ())
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= 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);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* !ASSEMBLER */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h
index f3f7718e3e..aa42768f70 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -167,3 +167,9 @@ extern int __local_multiple_threads attribute_hidden;
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c
index 840974401b..98bb237c06 100644
--- a/nptl/sysdeps/unix/sysv/linux/fork.c
+++ b/nptl/sysdeps/unix/sysv/linux/fork.c
@@ -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.
 
@@ -167,8 +167,11 @@ __libc_fork (void)
 	    allp->handler->child_handler ();
 
 	  /* Note that we do not have to wake any possible waiter.
-	     This is the only thread in the new process.  */
-	  --allp->handler->refcntr;
+ 	     This is the only thread in the new process.  The count
+ 	     may have been bumped up by other threads doing a fork.
+ 	     We reset it to 1, to avoid waiting for non-existing
+ 	     thread(s) to release the count.  */
+	  allp->handler->refcntr = 1;
 
 	  /* XXX We could at this point look through the object pool
 	     and mark all objects not on the __fork_handlers list as
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 aa1f9f41ca..bf70e17fca 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_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.
 
@@ -79,10 +79,7 @@ sem_timedwait:
 	jae	6f
 
 	cfi_offset(3, -16)		/* %ebx */
-7:	call	__pthread_enable_asynccancel
-	movl	%eax, 8(%esp)
-
-	xorl	%ecx, %ecx
+7:	xorl	%ecx, %ecx
 	movl	%esp, %ebx
 	movl	%ecx, %edx
 	movl	$SYS_gettimeofday, %eax
@@ -105,6 +102,10 @@ sem_timedwait:
 
 	movl	%ecx, (%esp)	/* Store relative timeout.  */
 	movl	%edx, 4(%esp)
+
+	call	__pthread_enable_asynccancel
+	movl	%eax, 8(%esp)
+
 	movl	28(%esp), %ebx
 	xorl	%ecx, %ecx
 	movl	%esp, %esi
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
index 147f5c8470..d60dcd33d5 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
 
@@ -137,3 +137,9 @@
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
index 63aaa96eb0..c4d52860dd 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
 
@@ -220,3 +220,9 @@ __GC_##name:								      \
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
index 3e88ee1866..30ef991bd0 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
@@ -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.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
 
@@ -30,6 +30,10 @@ __lll_robust_lock_wait (int *futex)
   int oldval = *futex;
   int tid = THREAD_GETMEM (THREAD_SELF, tid);
 
+  /* If the futex changed meanwhile try locking again.  */
+  if (oldval == 0)
+    goto try;
+
   do
     {
       if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
@@ -41,6 +45,9 @@ __lll_robust_lock_wait (int *futex)
 	continue;
 
       lll_futex_wait (futex, newval);
+
+    try:
+      ;
     }
   while ((oldval = atomic_compare_and_exchange_val_acq (futex,
 							tid | FUTEX_WAITERS,
@@ -57,6 +64,11 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
     return EINVAL;
 
   int tid = THREAD_GETMEM (THREAD_SELF, tid);
+  int oldval = *futex;
+
+  /* If the futex changed meanwhile try locking again.  */
+  if (oldval == 0)
+    goto try;
 
   do
     {
@@ -80,7 +92,6 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
 	return ETIMEDOUT;
 
       /* Wait.  */
-      int oldval = *futex;
       if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
 	return oldval;
 
@@ -90,8 +101,13 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
 	continue;
 
       lll_futex_timed_wait (futex, newval, &rt);
+
+    try:
+      ;
     }
-  while (atomic_compare_and_exchange_bool_acq (futex, tid | FUTEX_WAITERS, 0));
+  while ((oldval = atomic_compare_and_exchange_val_acq (futex,
+							tid | FUTEX_WAITERS,
+							0)) != 0);
 
   return 0;
 }
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
index dcbc0d6520..3752abc870 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
@@ -128,3 +128,9 @@
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
index 83eb444ece..707765ab58 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
@@ -117,3 +117,9 @@
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c b/nptl/sysdeps/unix/sysv/linux/pthread_kill.c
index 9115d6f40b..75089365c3 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c
+++ b/nptl/sysdeps/unix/sysv/linux/pthread_kill.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -33,7 +33,15 @@ __pthread_kill (threadid, signo)
   struct pthread *pd = (struct pthread *) threadid;
 
   /* Make sure the descriptor is valid.  */
-  if (INVALID_TD_P (pd))
+  if (DEBUGGING_P && INVALID_TD_P (pd))
+    /* Not a valid thread handle.  */
+    return ESRCH;
+
+  /* Force load of pd->tid into local variable or register.  Otherwise
+     if a thread exits between ESRCH test and tgkill, we might return
+     EINVAL, because pd->tid would be cleared by the kernel.  */
+  pid_t tid = atomic_forced_read (pd->tid);
+  if (__builtin_expect (tid <= 0, 0))
     /* Not a valid thread handle.  */
     return ESRCH;
 
@@ -53,15 +61,15 @@ __pthread_kill (threadid, signo)
   int val;
 #if __ASSUME_TGKILL
   val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
-			  pd->tid, signo);
+			  tid, signo);
 #else
 # ifdef __NR_tgkill
   val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
-			  pd->tid, signo);
+			  tid, signo);
   if (INTERNAL_SYSCALL_ERROR_P (val, err)
       && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
 # endif
-    val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, signo);
+    val = INTERNAL_SYSCALL (tkill, err, 2, tid, signo);
 #endif
 
   return (INTERNAL_SYSCALL_ERROR_P (val, err)
diff --git a/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h b/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
new file mode 100644
index 0000000000..39db5a3bd4
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
@@ -0,0 +1,153 @@
+/* Defintions for lowlevel handling in ld.so.
+   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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _RTLD_LOWLEVEL_H
+#define  _RTLD_LOWLEVEL_H 1
+
+#include <atomic.h>
+#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) \
+  do {									      \
+    while (1)								      \
+      {									      \
+	int val = word;							      \
+	if (val == 0)							      \
+	  break;							      \
+	lll_futex_wait (&(word), val);					      \
+      }									      \
+  } while (0)
+
+
+#define __rtld_notify(word) \
+  lll_futex_wake (&(word), 1)
+
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
index 09dac2c90b..17ab562daa 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -113,3 +113,9 @@ L(pseudo_end):
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
index f8eb6a9ebc..77ce742495 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -126,3 +126,9 @@ extern int __local_multiple_threads attribute_hidden;
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
index 9a967eaf53..a8065c6a8c 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -161,3 +161,9 @@
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
index 75a4eb9469..f0349906b2 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
 
@@ -104,3 +104,9 @@ __##syscall_name##_nocancel:			\
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
index dd263a597c..2c76d01715 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
@@ -102,3 +102,9 @@ __##syscall_name##_nocancel:			\
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
index 90f10e6f4f..394dec8d82 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -164,7 +164,7 @@ __lll_mutex_timedlock_wait:
 8:				/* NB: %edx == 2 */
 	xorl	%eax, %eax
 	LOCK
-	cmpxchgl %edx, (%rdi)
+	cmpxchgl %edx, (%r12)
 	jnz	7f
 
 6:	addq	$16, %rsp
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 c44d3f5e77..51136cf2dc 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.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.
 
@@ -79,10 +79,7 @@ sem_timedwait:
 	cfi_offset(14, -24)		/* %r14 */
 	jae	6f
 
-7:	call	__pthread_enable_asynccancel
-	movl	%eax, 16(%rsp)
-
-	xorl	%esi, %esi
+7:	xorl	%esi, %esi
 	movq	%rsp, %rdi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
 	callq	*%rax
@@ -105,6 +102,9 @@ sem_timedwait:
 	movq	%rdi, (%rsp)	/* Store relative timeout.  */
 	movq	%rsi, 8(%rsp)
 
+	call	__pthread_enable_asynccancel
+	movl	%eax, 16(%rsp)
+
 	movq	%rsp, %r10
 	movq	%r12, %rdi
 	xorl	%esi, %esi
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
index 97debaba99..3e741da794 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
 
@@ -136,3 +136,9 @@ extern int __local_multiple_threads attribute_hidden;
 # define NO_CANCELLATION 1
 
 #endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
index 65ff0639b6..b6385b135c 100644
--- a/nptl/sysdeps/x86_64/tls.h
+++ b/nptl/sysdeps/x86_64/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  nptl/x86_64 version.
-   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
@@ -47,6 +47,7 @@ typedef struct
   dtv_t *dtv;
   void *self;		/* Pointer to the thread descriptor.  */
   int multiple_threads;
+  int gscope_flag;
   uintptr_t sysinfo;
   uintptr_t stack_guard;
   uintptr_t pointer_guard;
@@ -339,6 +340,26 @@ typedef struct
    = THREAD_GETMEM (THREAD_SELF, header.pointer_guard))
 
 
+/* Get and set the global scope generation counter in the TCB head.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									      \
+    { int __res;							      \
+      asm volatile ("xchgl %0, %%fs:%P1"				      \
+		    : "=r" (__res)					      \
+		    : "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);		      \
+    }									      \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/tst-cancel-wrappers.sh b/nptl/tst-cancel-wrappers.sh
index d6f16d1ed2..61b9fb52de 100644
--- a/nptl/tst-cancel-wrappers.sh
+++ b/nptl/tst-cancel-wrappers.sh
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Test whether all cancelable functions are cancelable.
-# 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 Jakub Jelinek <jakub@redhat.com>, 2002.
 
@@ -26,6 +26,7 @@ C["close"]=1
 C["connect"]=1
 C["creat"]=1
 C["fcntl"]=1
+C["fdatasync"]=1
 C["fsync"]=1
 C["msgrcv"]=1
 C["msgsnd"]=1
diff --git a/nptl/tst-cancel4.c b/nptl/tst-cancel4.c
index 73cfa44614..45df6ce076 100644
--- a/nptl/tst-cancel4.c
+++ b/nptl/tst-cancel4.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.
 
@@ -1571,6 +1571,47 @@ tf_fsync (void *arg)
 
 
 static void *
+tf_fdatasync (void *arg)
+{
+  if (arg == NULL)
+    // XXX If somebody can provide a portable test case in which fdatasync()
+    // blocks we can enable this test to run in both rounds.
+    abort ();
+
+  tempfd = open ("Makefile", O_RDONLY);
+  if (tempfd == -1)
+    {
+      printf ("%s: cannot open Makefile\n", __FUNCTION__);
+      exit (1);
+    }
+
+  int r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  pthread_cleanup_push (cl, NULL);
+
+  fdatasync (tempfd);
+
+  pthread_cleanup_pop (0);
+
+  printf ("%s: fdatasync returned\n", __FUNCTION__);
+
+  exit (1);
+}
+
+
+static void *
 tf_msync (void *arg)
 {
   if (arg == NULL)
@@ -2078,6 +2119,7 @@ static struct
   ADD_TEST (pread, 2, 1),
   ADD_TEST (pwrite, 2, 1),
   ADD_TEST (fsync, 2, 1),
+  ADD_TEST (fdatasync, 2, 1),
   ADD_TEST (msync, 2, 1),
   ADD_TEST (sendto, 2, 1),
   ADD_TEST (sendmsg, 2, 1),
diff --git a/nptl/tst-robust9.c b/nptl/tst-robust9.c
new file mode 100644
index 0000000000..1d6ba179be
--- /dev/null
+++ b/nptl/tst-robust9.c
@@ -0,0 +1,94 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+
+static pthread_mutex_t m;
+
+static void *
+tf (void *data)
+{
+  int err = pthread_mutex_lock (&m);
+  if (err == EOWNERDEAD)
+    {
+      err = pthread_mutex_consistent_np (&m);
+      if (err)
+	{
+	  puts ("pthread_mutex_consistent_np");
+	  exit (1);
+	}
+    }
+  else if (err)
+    {
+      puts ("pthread_mutex_lock");
+      exit (1);
+    }
+  printf ("thread%ld got the lock.\n", (long int) data);
+  sleep (1);
+  /* exit without unlock */
+  return NULL;
+}
+
+static int
+do_test (void)
+{
+  int err, i;
+  pthread_t t[3];
+  pthread_mutexattr_t ma;
+
+  pthread_mutexattr_init (&ma);
+  err = pthread_mutexattr_setrobust_np (&ma, PTHREAD_MUTEX_ROBUST_NP);
+  if (err)
+    {
+      puts ("pthread_mutexattr_setrobust_np");
+      return 1;
+    }
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+  err = pthread_mutex_init (&m, &ma);
+#ifdef ENABLE_PI
+  if (err == ENOTSUP)
+    {
+      puts ("PI robust mutexes not supported");
+      return 0;
+    }
+#endif
+  if (err)
+    {
+      puts ("pthread_mutex_init");
+      return 1;
+    }
+
+  for (i = 0; i < sizeof (t) / sizeof (t[0]); i++)
+    {
+      err = pthread_create (&t[i], NULL, tf, (void *) (long int) i);
+      if (err)
+	{
+	  puts ("pthread_create");
+	  return 1;
+	}
+    }
+
+  for (i = 0; i < sizeof (t) / sizeof (t[0]); i++)
+    {
+      err = pthread_join (t[i], NULL);
+      if (err)
+	{
+	  puts ("pthread_join");
+	  return 1;
+	}
+    }
+  return 0;
+}
+
+#define TIMEOUT 5
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-robustpi9.c b/nptl/tst-robustpi9.c
new file mode 100644
index 0000000000..d059aa7d88
--- /dev/null
+++ b/nptl/tst-robustpi9.c
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust9.c"
diff --git a/nptl/tst-sem10.c b/nptl/tst-sem10.c
new file mode 100644
index 0000000000..9f6e870a85
--- /dev/null
+++ b/nptl/tst-sem10.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2007.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+
+static int
+do_test (void)
+{
+  sem_t s;
+  if (sem_init (&s, 0, 0) == -1)
+    {
+      puts ("sem_init failed");
+      return 1;
+    }
+
+  struct timeval tv;
+  if (gettimeofday (&tv, NULL) != 0)
+    {
+      puts ("gettimeofday failed");
+      return 1;
+    }
+
+  struct timespec ts;
+  TIMEVAL_TO_TIMESPEC (&tv, &ts);
+
+  /* Set ts to yesterday.  */
+  ts.tv_sec -= 86400;
+
+  int type_before;
+  if (pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type_before) != 0)
+    {
+      puts ("first pthread_setcanceltype failed");
+      return 1;
+    }
+
+  errno = 0;
+  if (TEMP_FAILURE_RETRY (sem_timedwait (&s, &ts)) != -1)
+    {
+      puts ("sem_timedwait succeeded");
+      return 1;
+    }
+  if (errno != ETIMEDOUT)
+    {
+      printf ("sem_timedwait return errno = %d instead of ETIMEDOUT\n",
+	      errno);
+      return 1;
+    }
+
+  int type_after;
+  if (pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type_after) != 0)
+    {
+      puts ("second pthread_setcanceltype failed");
+      return 1;
+    }
+  if (type_after != PTHREAD_CANCEL_DEFERRED)
+    {
+      puts ("sem_timedwait changed cancellation type");
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"