about summary refs log tree commit diff
path: root/nptl/sysdeps
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
committerJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
commit0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch)
tree2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /nptl/sysdeps
parent7d58530341304d403a6626d7f7a1913165fe2f32 (diff)
downloadglibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.gz
glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.xz
glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.zip
2.5-18.1
Diffstat (limited to 'nptl/sysdeps')
-rw-r--r--nptl/sysdeps/alpha/tls.h34
-rw-r--r--nptl/sysdeps/generic/lowlevellock.h89
-rw-r--r--nptl/sysdeps/i386/jmpbuf-unwind.h31
-rw-r--r--nptl/sysdeps/i386/tcb-offsets.sym1
-rw-r--r--nptl/sysdeps/i386/tls.h58
-rw-r--r--nptl/sysdeps/ia64/pthread_spin_lock.c2
-rw-r--r--nptl/sysdeps/ia64/pthread_spin_trylock.c2
-rw-r--r--nptl/sysdeps/ia64/tcb-offsets.sym8
-rw-r--r--nptl/sysdeps/ia64/tls.h72
-rw-r--r--nptl/sysdeps/powerpc/jmpbuf-unwind.h31
-rw-r--r--nptl/sysdeps/powerpc/tcb-offsets.sym4
-rw-r--r--nptl/sysdeps/powerpc/tls.h67
-rw-r--r--nptl/sysdeps/pthread/Makefile4
-rw-r--r--nptl/sysdeps/pthread/Subdirs1
-rw-r--r--nptl/sysdeps/pthread/aio_misc.h74
-rw-r--r--nptl/sysdeps/pthread/allocalim.h13
-rw-r--r--nptl/sysdeps/pthread/bits/libc-lock.h12
-rw-r--r--nptl/sysdeps/pthread/bits/sigthread.h8
-rw-r--r--nptl/sysdeps/pthread/createthread.c3
-rw-r--r--nptl/sysdeps/pthread/gai_misc.h119
-rw-r--r--nptl/sysdeps/pthread/pt-initfini.c8
-rw-r--r--nptl/sysdeps/pthread/pthread-functions.h5
-rw-r--r--nptl/sysdeps/pthread/pthread.h361
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_broadcast.c8
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_signal.c5
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_wait.c14
-rw-r--r--nptl/sysdeps/pthread/sigfillset.c4
-rw-r--r--nptl/sysdeps/pthread/unwind-forcedunwind.c17
-rw-r--r--nptl/sysdeps/s390/jmpbuf-unwind.h37
-rw-r--r--nptl/sysdeps/s390/tcb-offsets.sym1
-rw-r--r--nptl/sysdeps/s390/tls.h58
-rw-r--r--nptl/sysdeps/sh/tcb-offsets.sym1
-rw-r--r--nptl/sysdeps/sh/tls.h47
-rw-r--r--nptl/sysdeps/sparc/sparc32/jmpbuf-unwind.h31
-rw-r--r--nptl/sysdeps/sparc/tcb-offsets.sym1
-rw-r--r--nptl/sysdeps/sparc/tls.h58
-rw-r--r--nptl/sysdeps/unix/sysv/linux/Makefile8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/aio_misc.h10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/clone.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h81
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/bits/local_lim.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h24
-rw-r--r--nptl/sysdeps/unix/sysv/linux/configure3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.c9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.h4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/clone.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S63
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S227
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S7
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S47
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S28
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S17
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S (renamed from nptl/sysdeps/generic/pt-raise.c)14
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S (renamed from nptl/sysdeps/sh/jmpbuf-unwind.h)17
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h332
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h42
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/smp.h56
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h288
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/vfork.S19
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/__ia64_longjmp.S5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/clone2.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/createthread.c4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h39
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h85
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/pt-initfini.c95
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/unwind-forcedunwind.c3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/kernel-features.h6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c113
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/mq_notify.c4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h90
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h118
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h41
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstack.c (renamed from nptl/sysdeps/pthread/sigaction.c)53
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c (renamed from nptl/sysdeps/alpha/jmpbuf-unwind.h)39
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c111
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread_kill.c18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/register-atfork.c4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h153
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h99
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/s390-32/clone.S11
-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/clone.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/clone.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h142
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S224
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h128
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sleep.c12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/smp.h30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/Makefile2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h95
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c131
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_init.c62
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c100
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_init.c63
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c54
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c117
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c59
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c74
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_init.c1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_init.c1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_trywait.c1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h97
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h91
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/timer_create.c13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/timer_routines.c50
-rw-r--r--nptl/sysdeps/unix/sysv/linux/unregister-atfork.c4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h35
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/clone.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S97
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h352
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S229
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S15
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S19
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S33
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S34
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S45
-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.S26
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S24
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S14
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S16
-rw-r--r--nptl/sysdeps/x86_64/jmpbuf-unwind.h31
-rw-r--r--nptl/sysdeps/x86_64/tcb-offsets.sym1
-rw-r--r--nptl/sysdeps/x86_64/tls.h59
172 files changed, 5282 insertions, 1634 deletions
diff --git a/nptl/sysdeps/alpha/tls.h b/nptl/sysdeps/alpha/tls.h
index bc6630953f..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 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
@@ -23,6 +23,7 @@
 # include <dl-sysdep.h>
 
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 
@@ -30,7 +31,11 @@
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 #else /* __ASSEMBLER__ */
@@ -60,7 +65,7 @@ typedef union dtv
 typedef struct
 {
   dtv_t *dtv;
-  void *private;
+  void *__private;
 } tcbhead_t;
 
 /* This is the size of the initial TCB.  */
@@ -119,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/generic/lowlevellock.h b/nptl/sysdeps/generic/lowlevellock.h
deleted file mode 100644
index 9cffca83e6..0000000000
--- a/nptl/sysdeps/generic/lowlevellock.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#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.
-
-   All code that looks at bit 31 first increases the 'number of
-   interested threads' usage counter, which is in bits 0-30.
-
-   All negative mutex values indicate that the mutex is still locked.  */
-
-
-static inline void
-__generic_mutex_lock (int *mutex)
-{
-  unsigned int v;
-
-  /* Bit 31 was clear, we got the mutex.  (this is the fastpath).  */
-  if (atomic_bit_test_set (mutex, 31) == 0)
-    return;
-
-  atomic_increment (mutex);
-
-  while (1)
-    {
-      if (atomic_bit_test_set (mutex, 31) == 0)
-	{
-	  atomic_decrement (mutex);
-	  return;
-	}
-
-      /* We have to wait now. First make sure the futex value we are
-	 monitoring is truly negative (i.e. locked). */
-      v = *mutex;
-      if (v >= 0)
-	continue;
-
-      lll_futex_wait (mutex, v);
-    }
-}
-
-
-static inline void
-__generic_mutex_unlock (int *mutex)
-{
-  /* Adding 0x80000000 to the counter results in 0 if and only if
-     there are not other interested threads - we can return (this is
-     the fastpath).  */
-  if (atomic_add_zero (0x80000000, mutex))
-    return;
-
-  /* There are other threads waiting for this mutex, wake one of them
-     up.  */
-  lll_futex_wake (mutex, 1);
-}
-
-
-#define lll_mutex_lock(futex) __generic_mutex_lock (&(futex))
-#define lll_mutex_unlock(futex) __generic_mutex_unlock (&(futex))
diff --git a/nptl/sysdeps/i386/jmpbuf-unwind.h b/nptl/sysdeps/i386/jmpbuf-unwind.h
deleted file mode 100644
index 5cef8b1cf5..0000000000
--- a/nptl/sysdeps/i386/jmpbuf-unwind.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <setjmp.h>
-#include <stdint.h>
-#include <unwind.h>
-
-#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
-  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
-
-#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
-  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_SP] - (_adj))
-
-/* We use the normal lobngjmp for unwinding.  */
-#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/nptl/sysdeps/i386/tcb-offsets.sym b/nptl/sysdeps/i386/tcb-offsets.sym
index 4e0444ba38..7c8d9a5ca5 100644
--- a/nptl/sysdeps/i386/tcb-offsets.sym
+++ b/nptl/sysdeps/i386/tcb-offsets.sym
@@ -11,3 +11,4 @@ SYSINFO_OFFSET		offsetof (tcbhead_t, sysinfo)
 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)
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h
index 945a4c71d6..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 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
@@ -22,6 +22,7 @@
 
 #include <dl-sysdep.h>
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 # include <stdlib.h>
@@ -32,18 +33,25 @@
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
 typedef struct
 {
-  void *tcb;		/* Pointer to the TCB.  Not necessary the
+  void *tcb;		/* Pointer to the TCB.  Not necessarily the
 			   thread descriptor used by libpthread.  */
   dtv_t *dtv;
   void *self;		/* Pointer to the thread descriptor.  */
   int multiple_threads;
   uintptr_t sysinfo;
+  uintptr_t stack_guard;
+  uintptr_t pointer_guard;
+  int gscope_flag;
 } tcbhead_t;
 
 # define TLS_MULTIPLE_THREADS_IN_TCB 1
@@ -97,11 +105,13 @@ union user_desc_init
 /* Get the thread descriptor definition.  */
 # include <nptl/descr.h>
 
-/* This is the size of the initial TCB.  */
-# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+/* This is the size of the initial TCB.  Can't be just sizeof (tcbhead_t),
+   because NPTL getpid, __libc_alloca_cutoff etc. need (almost) the whole
+   struct pthread even when not linked with -lpthread.  */
+# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
 
 /* Alignment requirements for the initial TCB.  */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
 
 /* This is the size of the TCB.  */
 # define TLS_TCB_SIZE sizeof (struct pthread)
@@ -409,6 +419,42 @@ union user_desc_init
      __res; })
 
 
+/* Set the stack guard field in TCB head.  */
+#define THREAD_SET_STACK_GUARD(value) \
+  THREAD_SETMEM (THREAD_SELF, header.stack_guard, value)
+#define THREAD_COPY_STACK_GUARD(descr) \
+  ((descr)->header.stack_guard						      \
+   = THREAD_GETMEM (THREAD_SELF, header.stack_guard))
+
+
+/* Set the pointer guard field in the TCB head.  */
+#define THREAD_SET_POINTER_GUARD(value) \
+  THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
+#define THREAD_COPY_POINTER_GUARD(descr) \
+  ((descr)->header.pointer_guard					      \
+   = 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/pthread_spin_lock.c b/nptl/sysdeps/ia64/pthread_spin_lock.c
index 71aaef9451..7d25af7c4b 100644
--- a/nptl/sysdeps/ia64/pthread_spin_lock.c
+++ b/nptl/sysdeps/ia64/pthread_spin_lock.c
@@ -25,7 +25,7 @@ pthread_spin_lock (lock)
 {
   int *p = (int *) lock;
 
-  while (__builtin_expect (__sync_val_compare_and_swap_si (p, 0, 1), 0))
+  while (__builtin_expect (__sync_val_compare_and_swap (p, 0, 1), 0))
     {
       /* Spin without using the atomic instruction.  */
       do
diff --git a/nptl/sysdeps/ia64/pthread_spin_trylock.c b/nptl/sysdeps/ia64/pthread_spin_trylock.c
index b7cbf14782..0fd8b99b7a 100644
--- a/nptl/sysdeps/ia64/pthread_spin_trylock.c
+++ b/nptl/sysdeps/ia64/pthread_spin_trylock.c
@@ -24,5 +24,5 @@ int
 pthread_spin_trylock (lock)
      pthread_spinlock_t *lock;
 {
-  return __sync_val_compare_and_swap_si ((int *) lock, 0, 1) == 0 ? 0 : EBUSY;
+  return __sync_val_compare_and_swap ((int *) lock, 0, 1) == 0 ? 0 : EBUSY;
 }
diff --git a/nptl/sysdeps/ia64/tcb-offsets.sym b/nptl/sysdeps/ia64/tcb-offsets.sym
index f5108e0a9e..e1707ab1c8 100644
--- a/nptl/sysdeps/ia64/tcb-offsets.sym
+++ b/nptl/sysdeps/ia64/tcb-offsets.sym
@@ -1,7 +1,7 @@
 #include <sysdep.h>
 #include <tls.h>
 
-PID			offsetof (struct pthread, pid) - sizeof (struct pthread)
-TID			offsetof (struct pthread, tid) - sizeof (struct pthread)
-MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) - sizeof (struct pthread)
-SYSINFO_OFFSET		offsetof (tcbhead_t, private)
+PID			offsetof (struct pthread, pid) - TLS_PRE_TCB_SIZE
+TID			offsetof (struct pthread, tid) - TLS_PRE_TCB_SIZE
+MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) - TLS_PRE_TCB_SIZE
+SYSINFO_OFFSET		offsetof (tcbhead_t, __private)
diff --git a/nptl/sysdeps/ia64/tls.h b/nptl/sysdeps/ia64/tls.h
index 4591a415c0..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 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
@@ -22,6 +22,7 @@
 
 #include <dl-sysdep.h>
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 # include <stdlib.h>
@@ -32,14 +33,18 @@
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
 typedef struct
 {
   dtv_t *dtv;
-  void *private;
+  void *__private;
 } tcbhead_t;
 
 register struct pthread *__thread_self __asm__("r13");
@@ -75,8 +80,16 @@ register struct pthread *__thread_self __asm__("r13");
 /* This is the size of the TCB.  */
 # define TLS_TCB_SIZE sizeof (tcbhead_t)
 
-/* This is the size we need before TCB.  */
-# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
+/* This is the size we need before TCB.
+   If there is not any room for uintptr_t stack_guard and
+   uintptr_t pointer_guard in struct pthread's final padding,
+   we need to put struct pthread 16 byte slower.  */
+# define TLS_PRE_TCB_SIZE \
+  (sizeof (struct pthread)						\
+   + (PTHREAD_STRUCT_END_PADDING < 2 * sizeof (uintptr_t)		\
+      ? ((2 * sizeof (uintptr_t) + __alignof__ (struct pthread) - 1)	\
+	 & ~(__alignof__ (struct pthread) - 1))				\
+      : 0))
 
 /* Alignment requirements for the TCB.  */
 # define TLS_TCB_ALIGN __alignof__ (struct pthread)
@@ -100,8 +113,9 @@ register struct pthread *__thread_self __asm__("r13");
 #  define GET_DTV(descr) \
   (((tcbhead_t *) (descr))->dtv)
 
-#define THREAD_SELF_SYSINFO	(((tcbhead_t *) __thread_self)->private)
-#define THREAD_SYSINFO(pd)	(((tcbhead_t *) ((pd) + 1))->private)
+#define THREAD_SELF_SYSINFO	(((tcbhead_t *) __thread_self)->__private)
+#define THREAD_SYSINFO(pd) \
+  (((tcbhead_t *) ((char *) (pd) + TLS_PRE_TCB_SIZE))->__private)
 
 #if defined NEED_DL_SYSINFO
 # define INIT_SYSINFO   THREAD_SELF_SYSINFO = (void *) GLRO(dl_sysinfo)
@@ -120,10 +134,11 @@ register struct pthread *__thread_self __asm__("r13");
   (((tcbhead_t *)__thread_self)->dtv)
 
 /* Return the thread descriptor for the current thread.  */
-# define THREAD_SELF (__thread_self - 1)
+# define THREAD_SELF \
+  ((struct pthread *) ((char *) __thread_self - TLS_PRE_TCB_SIZE))
 
 /* Magic for libthread_db to know how to do THREAD_SELF.  */
-# define DB_THREAD_SELF REGISTER (64, 64, 13 * 8, -sizeof (struct pthread))
+# define DB_THREAD_SELF REGISTER (64, 64, 13 * 8, -TLS_PRE_TCB_SIZE)
 
 /* Access to data in the thread descriptor is easy.  */
 #define THREAD_GETMEM(descr, member) \
@@ -135,6 +150,45 @@ register struct pthread *__thread_self __asm__("r13");
 #define THREAD_SETMEM_NC(descr, member, idx, value) \
   descr->member[idx] = (value)
 
+/* Set the stack guard field in TCB head.  */
+#define THREAD_SET_STACK_GUARD(value) \
+  (((uintptr_t *) __thread_self)[-1] = (value))
+#define THREAD_COPY_STACK_GUARD(descr) \
+  (((uintptr_t *) ((char *) (descr) + TLS_PRE_TCB_SIZE))[-1] \
+   = ((uintptr_t *) __thread_self)[-1])
+
+/* Set the pointer guard field in TCB head.  */
+#define THREAD_GET_POINTER_GUARD() \
+  (((uintptr_t *) __thread_self)[-2])
+#define THREAD_SET_POINTER_GUARD(value) \
+  (((uintptr_t *) __thread_self)[-2] = (value))
+#define THREAD_COPY_POINTER_GUARD(descr) \
+  (((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/jmpbuf-unwind.h b/nptl/sysdeps/powerpc/jmpbuf-unwind.h
deleted file mode 100644
index 0b817160d3..0000000000
--- a/nptl/sysdeps/powerpc/jmpbuf-unwind.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <setjmp.h>
-#include <stdint.h>
-#include <unwind.h>
-
-#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
-  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
-
-#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
-  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_GPR1] - (_adj))
-
-/* We use the normal lobngjmp for unwinding.  */
-#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/nptl/sysdeps/powerpc/tcb-offsets.sym b/nptl/sysdeps/powerpc/tcb-offsets.sym
index a9701fb5b7..4a8671e802 100644
--- a/nptl/sysdeps/powerpc/tcb-offsets.sym
+++ b/nptl/sysdeps/powerpc/tcb-offsets.sym
@@ -6,10 +6,12 @@
 -- Abuse tls.h macros to derive offsets relative to the thread register.
 # undef __thread_register
 # define __thread_register	((void *) 0)
-# define thread_offsetof(mem)	((void *) &THREAD_SELF->mem - (void *) 0)
+# define thread_offsetof(mem)	((ptrdiff_t) THREAD_SELF + offsetof (struct pthread, mem))
+
 
 #if TLS_MULTIPLE_THREADS_IN_TCB
 MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
 #endif
 PID				thread_offsetof (pid)
 TID				thread_offsetof (tid)
+POINTER_GUARD			(offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
diff --git a/nptl/sysdeps/powerpc/tls.h b/nptl/sysdeps/powerpc/tls.h
index ce7f5bd53d..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 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
@@ -23,6 +23,7 @@
 # include <dl-sysdep.h>
 
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 
@@ -30,7 +31,11 @@
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 #else /* __ASSEMBLER__ */
@@ -60,11 +65,13 @@ typedef union dtv
 /* Get the thread descriptor definition.  */
 # include <nptl/descr.h>
 
-/* This layout is actually wholly private and not affected by the ABI.
-   Nor does it overlap the pthread data structure, so we need nothing
-   extra here at all.  */
+/* The stack_guard is accessed directly by GCC -fstack-protector code,
+   so it is a part of public ABI.  The dtv and pointer_guard fields
+   are private.  */
 typedef struct
 {
+  uintptr_t pointer_guard;
+  uintptr_t stack_guard;
   dtv_t *dtv;
 } tcbhead_t;
 
@@ -122,7 +129,7 @@ register void *__thread_register __asm__ ("r13");
 
 /* Return the address of the dtv for the current thread.  */
 # define THREAD_DTV() \
-     (((tcbhead_t *) (__thread_register - TLS_TCB_OFFSET))[-1].dtv)
+    (((tcbhead_t *) (__thread_register - TLS_TCB_OFFSET))[-1].dtv)
 
 /* Return the thread descriptor for the current thread.  */
 # define THREAD_SELF \
@@ -131,9 +138,9 @@ register void *__thread_register __asm__ ("r13");
 
 /* Magic for libthread_db to know how to do THREAD_SELF.  */
 # define DB_THREAD_SELF							      \
-  REGISTER (32, 32, PT_THREAD_POINTER * 4,					      \
+  REGISTER (32, 32, PT_THREAD_POINTER * 4,				      \
 	    - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)			      \
-  REGISTER (64, 64, PT_THREAD_POINTER * 8,					      \
+  REGISTER (64, 64, PT_THREAD_POINTER * 8,				      \
 	    - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
 
 /* Read member of the thread descriptor directly.  */
@@ -151,10 +158,54 @@ register void *__thread_register __asm__ ("r13");
 # define THREAD_SETMEM_NC(descr, member, idx, value) \
     ((void)(descr), (THREAD_SELF)->member[idx] = (value))
 
+/* Set the stack guard field in TCB head.  */
+# define THREAD_SET_STACK_GUARD(value) \
+    (((tcbhead_t *) ((char *) __thread_register				      \
+		     - TLS_TCB_OFFSET))[-1].stack_guard = (value))
+# define THREAD_COPY_STACK_GUARD(descr) \
+    (((tcbhead_t *) ((char *) (descr)					      \
+		     + TLS_PRE_TCB_SIZE))[-1].stack_guard		      \
+     = ((tcbhead_t *) ((char *) __thread_register			      \
+		       - TLS_TCB_OFFSET))[-1].stack_guard)
+
+/* Set the stack guard field in TCB head.  */
+# define THREAD_GET_POINTER_GUARD() \
+    (((tcbhead_t *) ((char *) __thread_register				      \
+		     - TLS_TCB_OFFSET))[-1].pointer_guard)
+# define THREAD_SET_POINTER_GUARD(value) \
+    (THREAD_GET_POINTER_GUARD () = (value))
+# define THREAD_COPY_POINTER_GUARD(descr) \
+    (((tcbhead_t *) ((char *) (descr)					      \
+		     + TLS_PRE_TCB_SIZE))[-1].pointer_guard		      \
+     = THREAD_GET_POINTER_GUARD())
+
 /* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some
    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/pthread/Makefile b/nptl/sysdeps/pthread/Makefile
index 207e10fad2..72550d74a7 100644
--- a/nptl/sysdeps/pthread/Makefile
+++ b/nptl/sysdeps/pthread/Makefile
@@ -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.
 
@@ -18,7 +18,6 @@
 # 02111-1307 USA.
 
 ifeq ($(subdir),csu)
-CFLAGS-libc-start.c += -I../nptl
 routines += unwind-resume
 shared-only-routines += unwind-resume
 CFLAGS-unwind-resume.c += -fexceptions -fasynchronous-unwind-tables
@@ -31,7 +30,6 @@ endif
 ifeq ($(subdir),rt)
 librt-sysdep_routines += timer_routines librt-cancellation rt-unwind-resume
 librt-shared-only-routines += rt-unwind-resume
-CPPFLAGS-timer_routines.c = -I../nptl
 CFLAGS-librt-cancellation.c += -fexceptions -fasynchronous-unwind-tables
 CFLAGS-rt-unwind-resume.c += -fexceptions -fasynchronous-unwind-tables
 
diff --git a/nptl/sysdeps/pthread/Subdirs b/nptl/sysdeps/pthread/Subdirs
index 4d1f4d876b..36266c1e69 100644
--- a/nptl/sysdeps/pthread/Subdirs
+++ b/nptl/sysdeps/pthread/Subdirs
@@ -1 +1,2 @@
+nptl
 nptl_db
diff --git a/nptl/sysdeps/pthread/aio_misc.h b/nptl/sysdeps/pthread/aio_misc.h
new file mode 100644
index 0000000000..c5a11f4550
--- /dev/null
+++ b/nptl/sysdeps/pthread/aio_misc.h
@@ -0,0 +1,74 @@
+/* Copyright (C) 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
+   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.  */
+
+/* We define a special synchronization primitive for AIO.  POSIX
+   conditional variables would be ideal but the pthread_cond_*wait
+   operations do not return on EINTR.  This is a requirement for
+   correct aio_suspend and lio_listio implementations.  */
+
+#include <assert.h>
+#include <pthreadP.h>
+#include <lowlevellock.h>
+
+#define DONT_NEED_AIO_MISC_COND	1
+
+#define AIO_MISC_NOTIFY(waitlist) \
+  do {									      \
+    if (*waitlist->counterp > 0 && --*waitlist->counterp == 0)		      \
+      lll_futex_wake (waitlist->counterp, 1);				      \
+  } while (0)
+
+#define AIO_MISC_WAIT(result, futex, timeout, cancel)			      \
+  do {									      \
+    volatile int *futexaddr = &futex;					      \
+    int oldval = futex;							      \
+									      \
+    if (oldval != 0)							      \
+      {									      \
+	pthread_mutex_unlock (&__aio_requests_mutex);			      \
+									      \
+	int oldtype;							      \
+	if (cancel)							      \
+	  oldtype = LIBC_CANCEL_ASYNC ();				      \
+									      \
+	int status;							      \
+	do								      \
+	  {								      \
+	    status = lll_futex_timed_wait (futexaddr, oldval, timeout);	      \
+	    if (status != -EWOULDBLOCK)					      \
+	      break;							      \
+									      \
+	    oldval = *futexaddr;					      \
+	  }								      \
+	while (oldval != 0);						      \
+									      \
+	if (cancel)							      \
+	  LIBC_CANCEL_RESET (oldtype);					      \
+									      \
+	if (status == -EINTR)						      \
+	  result = EINTR;						      \
+	else if (status == -ETIMEDOUT)					      \
+	  result = EAGAIN;						      \
+	else								      \
+	  assert (status == 0 || status == -EWOULDBLOCK);		      \
+									      \
+	pthread_mutex_lock (&__aio_requests_mutex);			      \
+      }									      \
+  } while (0)
+
+#include_next <aio_misc.h>
diff --git a/nptl/sysdeps/pthread/allocalim.h b/nptl/sysdeps/pthread/allocalim.h
index 2d666c0b0a..f13c3a3305 100644
--- a/nptl/sysdeps/pthread/allocalim.h
+++ b/nptl/sysdeps/pthread/allocalim.h
@@ -1,18 +1,18 @@
 /* Determine whether block of given size can be allocated on the stack or not.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 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
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
+   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
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
+   You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If not,
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
@@ -21,7 +21,8 @@
 #include <limits.h>
 
 
-extern inline int
+extern int
+__always_inline
 __libc_use_alloca (size_t size)
 {
   return (__builtin_expect (size <= PTHREAD_STACK_MIN / 4, 1)
diff --git a/nptl/sysdeps/pthread/bits/libc-lock.h b/nptl/sysdeps/pthread/bits/libc-lock.h
index 0adf273e35..795caa7135 100644
--- a/nptl/sysdeps/pthread/bits/libc-lock.h
+++ b/nptl/sysdeps/pthread/bits/libc-lock.h
@@ -1,18 +1,18 @@
 /* libc-internal interface for mutex locks.  NPTL version.
-   Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1996-2001, 2002, 2003, 2005 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 Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
+   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
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
+   You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If not,
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
@@ -408,7 +408,7 @@ extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer
 
 
 /* Normal cleanup handling, based on C cleanup attribute.  */
-extern inline void
+extern __inline void
 __libc_cleanup_routine (struct __pthread_cleanup_frame *f)
 {
   if (f->__do_it)
diff --git a/nptl/sysdeps/pthread/bits/sigthread.h b/nptl/sysdeps/pthread/bits/sigthread.h
index df2bcac291..960bde18a9 100644
--- a/nptl/sysdeps/pthread/bits/sigthread.h
+++ b/nptl/sysdeps/pthread/bits/sigthread.h
@@ -3,16 +3,16 @@
    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 Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
+   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
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
+   You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If not,
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
diff --git a/nptl/sysdeps/pthread/createthread.c b/nptl/sysdeps/pthread/createthread.c
index 03a0f1aa37..88658a16e1 100644
--- a/nptl/sysdeps/pthread/createthread.c
+++ b/nptl/sysdeps/pthread/createthread.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.
 
@@ -242,6 +242,7 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr,
 		       || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))
     stopped = true;
   pd->stopped_start = stopped;
+  pd->parent_cancelhandling = THREAD_GETMEM (THREAD_SELF, cancelhandling);
 
   /* Actually create the thread.  */
   int res = do_clone (pd, attr, clone_flags, start_thread,
diff --git a/nptl/sysdeps/pthread/gai_misc.h b/nptl/sysdeps/pthread/gai_misc.h
new file mode 100644
index 0000000000..9f6a73dad1
--- /dev/null
+++ b/nptl/sysdeps/pthread/gai_misc.h
@@ -0,0 +1,119 @@
+/* Copyright (C) 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
+   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.  */
+
+/* We define a special synchronization primitive for AIO.  POSIX
+   conditional variables would be ideal but the pthread_cond_*wait
+   operations do not return on EINTR.  This is a requirement for
+   correct aio_suspend and lio_listio implementations.  */
+
+#include <assert.h>
+#include <signal.h>
+#include <pthreadP.h>
+#include <lowlevellock.h>
+
+#define DONT_NEED_GAI_MISC_COND	1
+
+#define GAI_MISC_NOTIFY(waitlist) \
+  do {									      \
+    if (*waitlist->counterp > 0 && --*waitlist->counterp == 0)		      \
+      lll_futex_wake (waitlist->counterp, 1);				      \
+  } while (0)
+
+#define GAI_MISC_WAIT(result, futex, timeout, cancel) \
+  do {									      \
+    volatile int *futexaddr = &futex;					      \
+    int oldval = futex;							      \
+									      \
+    if (oldval != 0)							      \
+      {									      \
+	pthread_mutex_unlock (&__gai_requests_mutex);			      \
+									      \
+	int oldtype;							      \
+	if (cancel)							      \
+	  oldtype = LIBC_CANCEL_ASYNC ();				      \
+									      \
+	int status;							      \
+	do								      \
+	  {								      \
+	    status = lll_futex_timed_wait (futexaddr, oldval, timeout);	      \
+	    if (status != -EWOULDBLOCK)					      \
+	      break;							      \
+									      \
+	    oldval = *futexaddr;					      \
+	  }								      \
+	while (oldval != 0);						      \
+									      \
+	if (cancel)							      \
+	  LIBC_CANCEL_RESET (oldtype);					      \
+									      \
+	if (status == -EINTR)						      \
+	  result = EINTR;						      \
+	else if (status == -ETIMEDOUT)					      \
+	  result = EAGAIN;						      \
+	else								      \
+	  assert (status == 0 || status == -EWOULDBLOCK);		      \
+									      \
+	pthread_mutex_lock (&__gai_requests_mutex);			      \
+      }									      \
+  } while (0)
+
+
+#define gai_start_notify_thread __gai_start_notify_thread
+#define gai_create_helper_thread __gai_create_helper_thread
+
+extern inline void
+__gai_start_notify_thread (void)
+{
+  sigset_t ss;
+  sigemptyset (&ss);
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, NULL, _NSIG / 8);
+}
+
+extern inline int
+__gai_create_helper_thread (pthread_t *threadp, void *(*tf) (void *),
+			    void *arg)
+{
+  pthread_attr_t attr;
+
+  /* Make sure the thread is created detached.  */
+  pthread_attr_init (&attr);
+  pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+
+  /* The helper thread needs only very little resources.  */
+  (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+  /* Block all signals in the helper thread.  To do this thoroughly we
+     temporarily have to block all signals here.  */
+  sigset_t ss;
+  sigset_t oss;
+  sigfillset (&ss);
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, &oss, _NSIG / 8);
+
+  int ret = pthread_create (threadp, &attr, tf, arg);
+
+  /* Restore the signal mask.  */
+  INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &oss, NULL,
+		    _NSIG / 8);
+
+  (void) pthread_attr_destroy (&attr);
+  return ret;
+}
+
+#include_next <gai_misc.h>
diff --git a/nptl/sysdeps/pthread/pt-initfini.c b/nptl/sysdeps/pthread/pt-initfini.c
index e9169e652a..1e35edd3eb 100644
--- a/nptl/sysdeps/pthread/pt-initfini.c
+++ b/nptl/sysdeps/pthread/pt-initfini.c
@@ -3,11 +3,11 @@
    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 Library General Public
+   and/or modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
 
-   In addition to the permissions in the GNU Library General Public
+   In addition to the permissions in the GNU Lesser General Public
    License, the Free Software Foundation gives you unlimited
    permission to link the compiled version of this file with other
    programs, and to distribute those programs without any restriction
@@ -19,9 +19,9 @@
    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 Library General Public License for more details.
+   GNU Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
+   You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If not,
    write to the Free Software Foundation, 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
diff --git a/nptl/sysdeps/pthread/pthread-functions.h b/nptl/sysdeps/pthread/pthread-functions.h
index 2845346128..74d24005c3 100644
--- a/nptl/sysdeps/pthread/pthread-functions.h
+++ b/nptl/sysdeps/pthread/pthread-functions.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -90,11 +90,12 @@ struct pthread_functions
   void (*ptr__pthread_cleanup_pop_restore) (struct _pthread_cleanup_buffer *,
 					    int);
 #define HAVE_PTR_NTHREADS
-  int *ptr_nthreads;
+  unsigned int *ptr_nthreads;
   void (*ptr___pthread_unwind) (__pthread_unwind_buf_t *)
        __attribute ((noreturn)) __cleanup_fct_attribute;
   void (*ptr__nptl_deallocate_tsd) (void);
   int (*ptr__nptl_setxid) (struct xid_command *);
+  void (*ptr_freeres) (void);
 };
 
 /* Variable in libc.so.  */
diff --git a/nptl/sysdeps/pthread/pthread.h b/nptl/sysdeps/pthread/pthread.h
index 5046a6976b..f60ecdee18 100644
--- a/nptl/sysdeps/pthread/pthread.h
+++ b/nptl/sysdeps/pthread/pthread.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 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
@@ -60,24 +60,50 @@ enum
 #endif
 };
 
-/* Mutex initializers.  */
-#define PTHREAD_MUTEX_INITIALIZER \
-  { }
+
 #ifdef __USE_GNU
-# if __WORDSIZE == 64
+/* Robust mutex or not flags.  */
+enum
+{
+  PTHREAD_MUTEX_STALLED_NP,
+  PTHREAD_MUTEX_ROBUST_NP
+};
+#endif
+
+
+#ifdef __USE_UNIX98
+/* Mutex protocols.  */
+enum
+{
+  PTHREAD_PRIO_NONE,
+  PTHREAD_PRIO_INHERIT,
+  PTHREAD_PRIO_PROTECT
+};
+#endif
+
+
+/* Mutex initializers.  */
+#if __WORDSIZE == 64
+# define PTHREAD_MUTEX_INITIALIZER \
+  { { 0, 0, 0, 0, 0, 0, { 0, 0 } } }
+# ifdef __USE_GNU
 #  define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP } }
+  { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { 0, 0 } } }
 #  define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP } }
+  { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { 0, 0 } } }
 #  define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP } }
-# else
+  { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { 0, 0 } } }
+# endif
+#else
+# define PTHREAD_MUTEX_INITIALIZER \
+  { { 0, 0, 0, 0, 0, { 0 } } }
+# ifdef __USE_GNU
 #  define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP } }
+  { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { 0 } } }
 #  define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP } }
+  { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { 0 } } }
 #  define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
-  { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP } }
+  { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { 0 } } }
 # endif
 #endif
 
@@ -93,8 +119,13 @@ enum
 };
 
 /* Read-write lock initializers.  */
-# define PTHREAD_RWLOCK_INITIALIZER \
-  { }
+# if __WORDSIZE == 64
+#  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 \
@@ -102,7 +133,7 @@ enum
       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, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 0 } }
 #  endif
 # endif
 #endif  /* Unix98 or XOpen2K */
@@ -140,7 +171,7 @@ enum
 
 
 /* Conditional variable handling.  */
-#define PTHREAD_COND_INITIALIZER { }
+#define PTHREAD_COND_INITIALIZER { { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } }
 
 
 /* Cleanup buffers */
@@ -190,7 +221,7 @@ __BEGIN_DECLS
 extern int pthread_create (pthread_t *__restrict __newthread,
 			   __const pthread_attr_t *__restrict __attr,
 			   void *(*__start_routine) (void *),
-			   void *__restrict __arg) __THROW;
+			   void *__restrict __arg) __THROW __nonnull ((1, 3));
 
 /* Terminate calling thread.
 
@@ -240,71 +271,78 @@ extern int pthread_equal (pthread_t __thread1, pthread_t __thread2) __THROW;
 /* Initialize thread attribute *ATTR with default attributes
    (detachstate is PTHREAD_JOINABLE, scheduling policy is SCHED_OTHER,
     no user-provided stack).  */
-extern int pthread_attr_init (pthread_attr_t *__attr) __THROW;
+extern int pthread_attr_init (pthread_attr_t *__attr) __THROW __nonnull ((1));
 
 /* Destroy thread attribute *ATTR.  */
-extern int pthread_attr_destroy (pthread_attr_t *__attr) __THROW;
+extern int pthread_attr_destroy (pthread_attr_t *__attr)
+     __THROW __nonnull ((1));
 
 /* Get detach state attribute.  */
 extern int pthread_attr_getdetachstate (__const pthread_attr_t *__attr,
-					int *__detachstate) __THROW;
+					int *__detachstate)
+     __THROW __nonnull ((1, 2));
 
 /* Set detach state attribute.  */
 extern int pthread_attr_setdetachstate (pthread_attr_t *__attr,
-					int __detachstate) __THROW;
+					int __detachstate)
+     __THROW __nonnull ((1));
 
 
 /* Get the size of the guard area created for stack overflow protection.  */
 extern int pthread_attr_getguardsize (__const pthread_attr_t *__attr,
-				      size_t *__guardsize) __THROW;
+				      size_t *__guardsize)
+     __THROW __nonnull ((1, 2));
 
 /* Set the size of the guard area created for stack overflow protection.  */
 extern int pthread_attr_setguardsize (pthread_attr_t *__attr,
-				      size_t __guardsize) __THROW;
+				      size_t __guardsize)
+     __THROW __nonnull ((1));
 
 
 /* Return in *PARAM the scheduling parameters of *ATTR.  */
 extern int pthread_attr_getschedparam (__const pthread_attr_t *__restrict
 				       __attr,
 				       struct sched_param *__restrict __param)
-     __THROW;
+     __THROW __nonnull ((1, 2));
 
 /* Set scheduling parameters (priority, etc) in *ATTR according to PARAM.  */
 extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr,
 				       __const struct sched_param *__restrict
-				       __param) __THROW;
+				       __param) __THROW __nonnull ((1, 2));
 
 /* Return in *POLICY the scheduling policy of *ATTR.  */
 extern int pthread_attr_getschedpolicy (__const pthread_attr_t *__restrict
 					__attr, int *__restrict __policy)
-     __THROW;
+     __THROW __nonnull ((1, 2));
 
 /* Set scheduling policy in *ATTR according to POLICY.  */
 extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy)
-     __THROW;
+     __THROW __nonnull ((1));
 
 /* Return in *INHERIT the scheduling inheritance mode of *ATTR.  */
 extern int pthread_attr_getinheritsched (__const pthread_attr_t *__restrict
 					 __attr, int *__restrict __inherit)
-     __THROW;
+     __THROW __nonnull ((1, 2));
 
 /* Set scheduling inheritance mode in *ATTR according to INHERIT.  */
 extern int pthread_attr_setinheritsched (pthread_attr_t *__attr,
-					 int __inherit) __THROW;
+					 int __inherit)
+     __THROW __nonnull ((1));
 
 
 /* Return in *SCOPE the scheduling contention scope of *ATTR.  */
 extern int pthread_attr_getscope (__const pthread_attr_t *__restrict __attr,
-				  int *__restrict __scope) __THROW;
+				  int *__restrict __scope)
+     __THROW __nonnull ((1, 2));
 
 /* Set scheduling contention scope in *ATTR according to SCOPE.  */
 extern int pthread_attr_setscope (pthread_attr_t *__attr, int __scope)
-     __THROW;
+     __THROW __nonnull ((1));
 
 /* Return the previously set address for the stack.  */
 extern int pthread_attr_getstackaddr (__const pthread_attr_t *__restrict
 				      __attr, void **__restrict __stackaddr)
-     __THROW __attribute_deprecated__;
+     __THROW __nonnull ((1, 2)) __attribute_deprecated__;
 
 /* Set the starting address of the stack of the thread to be created.
    Depending on whether the stack grows up or down the value must either
@@ -312,30 +350,32 @@ extern int pthread_attr_getstackaddr (__const pthread_attr_t *__restrict
    minimal size of the block must be PTHREAD_STACK_MIN.  */
 extern int pthread_attr_setstackaddr (pthread_attr_t *__attr,
 				      void *__stackaddr)
-     __THROW __attribute_deprecated__;
+     __THROW __nonnull ((1)) __attribute_deprecated__;
 
 /* Return the currently used minimal stack size.  */
 extern int pthread_attr_getstacksize (__const pthread_attr_t *__restrict
 				      __attr, size_t *__restrict __stacksize)
-     __THROW;
+     __THROW __nonnull ((1, 2));
 
 /* Add information about the minimum stack size needed for the thread
    to be started.  This size must never be less than PTHREAD_STACK_MIN
    and must also not exceed the system limits.  */
 extern int pthread_attr_setstacksize (pthread_attr_t *__attr,
-				      size_t __stacksize) __THROW;
+				      size_t __stacksize)
+     __THROW __nonnull ((1));
 
 #ifdef __USE_XOPEN2K
 /* Return the previously set address for the stack.  */
 extern int pthread_attr_getstack (__const pthread_attr_t *__restrict __attr,
 				  void **__restrict __stackaddr,
-				  size_t *__restrict __stacksize) __THROW;
+				  size_t *__restrict __stacksize)
+     __THROW __nonnull ((1, 2, 3));
 
 /* The following two interfaces are intended to replace the last two.  They
    require setting the address as well as the size since only setting the
    address will make the implementation on some architectures impossible.  */
 extern int pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
-				  size_t __stacksize) __THROW;
+				  size_t __stacksize) __THROW __nonnull ((1));
 #endif
 
 #ifdef __USE_GNU
@@ -343,19 +383,22 @@ extern int pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
    the processors represented in CPUSET.  */
 extern int pthread_attr_setaffinity_np (pthread_attr_t *__attr,
 					size_t __cpusetsize,
-					__const cpu_set_t *__cpuset) __THROW;
+					__const cpu_set_t *__cpuset)
+     __THROW __nonnull ((1, 3));
 
 /* Get bit set in CPUSET representing the processors threads created with
    ATTR can run on.  */
 extern int pthread_attr_getaffinity_np (__const pthread_attr_t *__attr,
 					size_t __cpusetsize,
-					cpu_set_t *__cpuset) __THROW;
+					cpu_set_t *__cpuset)
+     __THROW __nonnull ((1, 3));
 
 
 /* Initialize thread attribute *ATTR with attributes corresponding to the
    already running thread TH.  It shall be called on unitialized ATTR
    and destroyed with pthread_attr_destroy when no longer needed.  */
-extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) __THROW;
+extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr)
+     __THROW __nonnull ((2));
 #endif
 
 
@@ -365,13 +408,13 @@ extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) __THROW;
    and *PARAM.  */
 extern int pthread_setschedparam (pthread_t __target_thread, int __policy,
 				  __const struct sched_param *__param)
-     __THROW;
+     __THROW __nonnull ((3));
 
 /* Return in *POLICY and *PARAM the scheduling parameters for TARGET_THREAD. */
 extern int pthread_getschedparam (pthread_t __target_thread,
 				  int *__restrict __policy,
 				  struct sched_param *__restrict __param)
-     __THROW;
+     __THROW __nonnull ((2, 3));
 
 /* Set the scheduling priority for TARGET_THREAD.  */
 extern int pthread_setschedprio (pthread_t __target_thread, int __prio)
@@ -397,11 +440,13 @@ extern int pthread_yield (void) __THROW;
 /* Limit specified thread TH to run only on the processors represented
    in CPUSET.  */
 extern int pthread_setaffinity_np (pthread_t __th, size_t __cpusetsize,
-				   __const cpu_set_t *__cpuset) __THROW;
+				   __const cpu_set_t *__cpuset)
+     __THROW __nonnull ((3));
 
 /* Get bit set in CPUSET representing the processors TH can run on.  */
 extern int pthread_getaffinity_np (pthread_t __th, size_t __cpusetsize,
-				   cpu_set_t *__cpuset) __THROW;
+				   cpu_set_t *__cpuset)
+     __THROW __nonnull ((3));
 #endif
 
 
@@ -415,7 +460,7 @@ extern int pthread_getaffinity_np (pthread_t __th, size_t __cpusetsize,
    The initialization functions might throw exception which is why
    this function is not marked with __THROW.  */
 extern int pthread_once (pthread_once_t *__once_control,
-			 void (*__init_routine) (void));
+			 void (*__init_routine) (void)) __nonnull ((1, 2));
 
 
 /* Functions for handling cancellation.
@@ -527,7 +572,7 @@ class __pthread_cleanup_class
    function the compiler is free to decide inlining the change when
    needed or fall back on the copy which must exist somewhere
    else.  */
-extern inline void
+extern __inline void
 __pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
 {
   if (__frame->__do_it)
@@ -652,16 +697,16 @@ extern void __pthread_unregister_cancel_restore (__pthread_unwind_buf_t *__buf)
 
 /* Internal interface to initiate cleanup.  */
 extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
-     __cleanup_fct_attribute __attribute ((__noreturn__))
+     __cleanup_fct_attribute __attribute__ ((__noreturn__))
 # ifndef SHARED
-     __attribute ((__weak__))
+     __attribute__ ((__weak__))
 # endif
      ;
 #endif
 
 /* Function used in the macros.  */
 struct __jmp_buf_tag;
-extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) __THROW;
+extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) __THROW;
 
 
 /* Mutex handling.  */
@@ -669,56 +714,123 @@ extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) __THROW;
 /* Initialize a mutex.  */
 extern int pthread_mutex_init (pthread_mutex_t *__mutex,
 			       __const pthread_mutexattr_t *__mutexattr)
-     __THROW;
+     __THROW __nonnull ((1));
 
 /* Destroy a mutex.  */
-extern int pthread_mutex_destroy (pthread_mutex_t *__mutex) __THROW;
+extern int pthread_mutex_destroy (pthread_mutex_t *__mutex)
+     __THROW __nonnull ((1));
 
 /* Try locking a mutex.  */
-extern int pthread_mutex_trylock (pthread_mutex_t *_mutex) __THROW;
+extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)
+     __THROW __nonnull ((1));
 
 /* Lock a mutex.  */
-extern int pthread_mutex_lock (pthread_mutex_t *__mutex) __THROW;
+extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
+     __THROW __nonnull ((1));
 
 #ifdef __USE_XOPEN2K
 /* Wait until lock becomes available, or specified time passes. */
 extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
                                     __const struct timespec *__restrict
-                                    __abstime) __THROW;
+                                    __abstime) __THROW __nonnull ((1, 2));
 #endif
 
 /* Unlock a mutex.  */
-extern int pthread_mutex_unlock (pthread_mutex_t *__mutex) __THROW;
+extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
+     __THROW __nonnull ((1));
+
+
+#ifdef __USE_UNIX98
+/* Get the priority ceiling of MUTEX.  */
+extern int pthread_mutex_getprioceiling (__const pthread_mutex_t *
+					 __restrict __mutex,
+					 int *__restrict __prioceiling)
+     __THROW __nonnull ((1, 2));
+
+/* Set the priority ceiling of MUTEX to PRIOCEILING, return old
+   priority ceiling value in *OLD_CEILING.  */
+extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict __mutex,
+					 int __prioceiling,
+					 int *__restrict __old_ceiling)
+     __THROW __nonnull ((1, 3));
+#endif
+
+
+#ifdef __USE_GNU
+/* Declare the state protected by MUTEX as consistent.  */
+extern int pthread_mutex_consistent_np (pthread_mutex_t *__mutex)
+     __THROW __nonnull ((1));
+#endif
 
 
 /* Functions for handling mutex attributes.  */
 
 /* Initialize mutex attribute object ATTR with default attributes
    (kind is PTHREAD_MUTEX_TIMED_NP).  */
-extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr) __THROW;
+extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr)
+     __THROW __nonnull ((1));
 
 /* Destroy mutex attribute object ATTR.  */
-extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr) __THROW;
+extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr)
+     __THROW __nonnull ((1));
 
 /* Get the process-shared flag of the mutex attribute ATTR.  */
 extern int pthread_mutexattr_getpshared (__const pthread_mutexattr_t *
 					 __restrict __attr,
-					 int *__restrict __pshared) __THROW;
+					 int *__restrict __pshared)
+     __THROW __nonnull ((1, 2));
 
 /* Set the process-shared flag of the mutex attribute ATTR.  */
 extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
-					 int __pshared) __THROW;
+					 int __pshared)
+     __THROW __nonnull ((1));
 
 #ifdef __USE_UNIX98
 /* Return in *KIND the mutex kind attribute in *ATTR.  */
 extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict
-				      __attr, int *__restrict __kind) __THROW;
+				      __attr, int *__restrict __kind)
+     __THROW __nonnull ((1, 2));
 
 /* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
    PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
    PTHREAD_MUTEX_DEFAULT).  */
 extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
-     __THROW;
+     __THROW __nonnull ((1));
+
+/* Return in *PROTOCOL the mutex protocol attribute in *ATTR.  */
+extern int pthread_mutexattr_getprotocol (__const pthread_mutexattr_t *
+					  __restrict __attr,
+					  int *__restrict __protocol)
+     __THROW __nonnull ((1, 2));
+
+/* Set the mutex protocol attribute in *ATTR to PROTOCOL (either
+   PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT, or PTHREAD_PRIO_PROTECT).  */
+extern int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr,
+					  int __protocol)
+     __THROW __nonnull ((1));
+
+/* Return in *PRIOCEILING the mutex prioceiling attribute in *ATTR.  */
+extern int pthread_mutexattr_getprioceiling (__const pthread_mutexattr_t *
+					     __restrict __attr,
+					     int *__restrict __prioceiling)
+     __THROW __nonnull ((1, 2));
+
+/* Set the mutex prioceiling attribute in *ATTR to PRIOCEILING.  */
+extern int pthread_mutexattr_setprioceiling (pthread_mutexattr_t *__attr,
+					     int __prioceiling)
+     __THROW __nonnull ((1));
+#endif
+
+#ifdef __USE_GNU
+/* Get the robustness flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_getrobust_np (__const pthread_mutexattr_t *__attr,
+					   int *__robustness)
+     __THROW __nonnull ((1, 2));
+
+/* Set the robustness flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
+					   int __robustness)
+     __THROW __nonnull ((1));
 #endif
 
 
@@ -729,66 +841,77 @@ extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
    the default values if later is NULL.  */
 extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
 				__const pthread_rwlockattr_t *__restrict
-				__attr) __THROW;
+				__attr) __THROW __nonnull ((1));
 
 /* Destroy read-write lock RWLOCK.  */
-extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock) __THROW;
+extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock)
+     __THROW __nonnull ((1));
 
 /* Acquire read lock for RWLOCK.  */
-extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock) __THROW;
+extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)
+     __THROW __nonnull ((1));
 
 /* Try to acquire read lock for RWLOCK.  */
-extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock) __THROW;
+extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock)
+  __THROW __nonnull ((1));
 
 # ifdef __USE_XOPEN2K
 /* Try to acquire read lock for RWLOCK or return after specfied time.  */
 extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
 				       __const struct timespec *__restrict
-				       __abstime) __THROW;
+				       __abstime) __THROW __nonnull ((1, 2));
 # endif
 
 /* Acquire write lock for RWLOCK.  */
-extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock) __THROW;
+extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
+     __THROW __nonnull ((1));
 
 /* Try to acquire write lock for RWLOCK.  */
-extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock) __THROW;
+extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock)
+     __THROW __nonnull ((1));
 
 # ifdef __USE_XOPEN2K
 /* Try to acquire write lock for RWLOCK or return after specfied time.  */
 extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
 				       __const struct timespec *__restrict
-				       __abstime) __THROW;
+				       __abstime) __THROW __nonnull ((1, 2));
 # endif
 
 /* Unlock RWLOCK.  */
-extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock) __THROW;
+extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
+     __THROW __nonnull ((1));
 
 
 /* Functions for handling read-write lock attributes.  */
 
 /* Initialize attribute object ATTR with default values.  */
-extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr) __THROW;
+extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr)
+     __THROW __nonnull ((1));
 
 /* Destroy attribute object ATTR.  */
-extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr) __THROW;
+extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr)
+     __THROW __nonnull ((1));
 
 /* Return current setting of process-shared attribute of ATTR in PSHARED.  */
 extern int pthread_rwlockattr_getpshared (__const pthread_rwlockattr_t *
 					  __restrict __attr,
-					  int *__restrict __pshared) __THROW;
+					  int *__restrict __pshared)
+     __THROW __nonnull ((1, 2));
 
 /* Set process-shared attribute of ATTR to PSHARED.  */
 extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr,
-					  int __pshared) __THROW;
+					  int __pshared)
+     __THROW __nonnull ((1));
 
 /* Return current setting of reader/writer preference.  */
 extern int pthread_rwlockattr_getkind_np (__const pthread_rwlockattr_t *
 					  __restrict __attr,
-					  int *__restrict __pref) __THROW;
+					  int *__restrict __pref)
+     __THROW __nonnull ((1, 2));
 
 /* Set reader/write preference.  */
 extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr,
-					  int __pref) __THROW;
+					  int __pref) __THROW __nonnull ((1));
 #endif
 
 
@@ -798,16 +921,19 @@ extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr,
    the default values if later is NULL.  */
 extern int pthread_cond_init (pthread_cond_t *__restrict __cond,
 			      __const pthread_condattr_t *__restrict
-			      __cond_attr) __THROW;
+			      __cond_attr) __THROW __nonnull ((1));
 
 /* Destroy condition variable COND.  */
-extern int pthread_cond_destroy (pthread_cond_t *__cond) __THROW;
+extern int pthread_cond_destroy (pthread_cond_t *__cond)
+     __THROW __nonnull ((1));
 
 /* Wake up one thread waiting for condition variable COND.  */
-extern int pthread_cond_signal (pthread_cond_t *__cond) __THROW;
+extern int pthread_cond_signal (pthread_cond_t *__cond)
+     __THROW __nonnull ((1));
 
 /* Wake up all threads waiting for condition variables COND.  */
-extern int pthread_cond_broadcast (pthread_cond_t *__cond) __THROW;
+extern int pthread_cond_broadcast (pthread_cond_t *__cond)
+     __THROW __nonnull ((1));
 
 /* Wait for condition variable COND to be signaled or broadcast.
    MUTEX is assumed to be locked before.
@@ -815,7 +941,8 @@ extern int pthread_cond_broadcast (pthread_cond_t *__cond) __THROW;
    This function is a cancellation point and therefore not marked with
    __THROW.  */
 extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
-			      pthread_mutex_t *__restrict __mutex);
+			      pthread_mutex_t *__restrict __mutex)
+     __nonnull ((1, 2));
 
 /* Wait for condition variable COND to be signaled or broadcast until
    ABSTIME.  MUTEX is assumed to be locked before.  ABSTIME is an
@@ -827,36 +954,39 @@ extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
 extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
 				   pthread_mutex_t *__restrict __mutex,
 				   __const struct timespec *__restrict
-				   __abstime);
+				   __abstime) __nonnull ((1, 2, 3));
 
 /* Functions for handling condition variable attributes.  */
 
 /* Initialize condition variable attribute ATTR.  */
-extern int pthread_condattr_init (pthread_condattr_t *__attr) __THROW;
+extern int pthread_condattr_init (pthread_condattr_t *__attr)
+     __THROW __nonnull ((1));
 
 /* Destroy condition variable attribute ATTR.  */
-extern int pthread_condattr_destroy (pthread_condattr_t *__attr) __THROW;
+extern int pthread_condattr_destroy (pthread_condattr_t *__attr)
+     __THROW __nonnull ((1));
 
 /* Get the process-shared flag of the condition variable attribute ATTR.  */
 extern int pthread_condattr_getpshared (__const pthread_condattr_t *
                                         __restrict __attr,
-                                        int *__restrict __pshared) __THROW;
+                                        int *__restrict __pshared)
+     __THROW __nonnull ((1, 2));
 
 /* Set the process-shared flag of the condition variable attribute ATTR.  */
 extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
-                                        int __pshared) __THROW;
+                                        int __pshared) __THROW __nonnull ((1));
 
 #ifdef __USE_XOPEN2K
 /* Get the clock selected for the conditon variable attribute ATTR.  */
 extern int pthread_condattr_getclock (__const pthread_condattr_t *
 				      __restrict __attr,
 				      __clockid_t *__restrict __clock_id)
-     __THROW;
+     __THROW __nonnull ((1, 2));
 
 /* Set the clock selected for the conditon variable attribute ATTR.  */
 extern int pthread_condattr_setclock (pthread_condattr_t *__attr,
-				      __clockid_t __clock_id) __THROW;
-
+				      __clockid_t __clock_id)
+     __THROW __nonnull ((1));
 #endif
 
 
@@ -866,19 +996,23 @@ extern int pthread_condattr_setclock (pthread_condattr_t *__attr,
 /* Initialize the spinlock LOCK.  If PSHARED is nonzero the spinlock can
    be shared between different processes.  */
 extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
-     __THROW;
+     __THROW __nonnull ((1));
 
 /* Destroy the spinlock LOCK.  */
-extern int pthread_spin_destroy (pthread_spinlock_t *__lock) __THROW;
+extern int pthread_spin_destroy (pthread_spinlock_t *__lock)
+     __THROW __nonnull ((1));
 
 /* Wait until spinlock LOCK is retrieved.  */
-extern int pthread_spin_lock (pthread_spinlock_t *__lock) __THROW;
+extern int pthread_spin_lock (pthread_spinlock_t *__lock)
+     __THROW __nonnull ((1));
 
 /* Try to lock spinlock LOCK.  */
-extern int pthread_spin_trylock (pthread_spinlock_t *__lock) __THROW;
+extern int pthread_spin_trylock (pthread_spinlock_t *__lock)
+     __THROW __nonnull ((1));
 
 /* Release spinlock LOCK.  */
-extern int pthread_spin_unlock (pthread_spinlock_t *__lock) __THROW;
+extern int pthread_spin_unlock (pthread_spinlock_t *__lock)
+     __THROW __nonnull ((1));
 
 
 /* Functions to handle barriers.  */
@@ -887,29 +1021,36 @@ extern int pthread_spin_unlock (pthread_spinlock_t *__lock) __THROW;
    opened when COUNT waiters arrived.  */
 extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier,
 				 __const pthread_barrierattr_t *__restrict
-				 __attr, unsigned int __count) __THROW;
+				 __attr, unsigned int __count)
+     __THROW __nonnull ((1));
 
 /* Destroy a previously dynamically initialized barrier BARRIER.  */
-extern int pthread_barrier_destroy (pthread_barrier_t *__barrier) __THROW;
+extern int pthread_barrier_destroy (pthread_barrier_t *__barrier)
+     __THROW __nonnull ((1));
 
 /* Wait on barrier BARRIER.  */
-extern int pthread_barrier_wait (pthread_barrier_t *__barrier) __THROW;
+extern int pthread_barrier_wait (pthread_barrier_t *__barrier)
+     __THROW __nonnull ((1));
 
 
 /* Initialize barrier attribute ATTR.  */
-extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr) __THROW;
+extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr)
+     __THROW __nonnull ((1));
 
 /* Destroy previously dynamically initialized barrier attribute ATTR.  */
-extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr) __THROW;
+extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr)
+     __THROW __nonnull ((1));
 
 /* Get the process-shared flag of the barrier attribute ATTR.  */
 extern int pthread_barrierattr_getpshared (__const pthread_barrierattr_t *
 					   __restrict __attr,
-					   int *__restrict __pshared) __THROW;
+					   int *__restrict __pshared)
+     __THROW __nonnull ((1, 2));
 
 /* Set the process-shared flag of the barrier attribute ATTR.  */
 extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr,
-                                           int __pshared) __THROW;
+                                           int __pshared)
+     __THROW __nonnull ((1));
 #endif
 
 
@@ -922,7 +1063,8 @@ extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr,
    DESTR_FUNCTION is not called if the value associated is NULL when
    the key is destroyed.  */
 extern int pthread_key_create (pthread_key_t *__key,
-			       void (*__destr_function) (void *)) __THROW;
+			       void (*__destr_function) (void *))
+     __THROW __nonnull ((1));
 
 /* Destroy KEY.  */
 extern int pthread_key_delete (pthread_key_t __key) __THROW;
@@ -932,13 +1074,14 @@ extern void *pthread_getspecific (pthread_key_t __key) __THROW;
 
 /* Store POINTER in the thread-specific data slot identified by KEY. */
 extern int pthread_setspecific (pthread_key_t __key,
-				__const void *__pointer) __THROW;
+				__const void *__pointer) __THROW ;
 
 
 #ifdef __USE_XOPEN2K
 /* Get ID of CPU-time clock for thread THREAD_ID.  */
 extern int pthread_getcpuclockid (pthread_t __thread_id,
-				  __clockid_t *__clock_id) __THROW;
+				  __clockid_t *__clock_id)
+     __THROW __nonnull ((2));
 #endif
 
 
@@ -957,6 +1100,16 @@ extern int pthread_atfork (void (*__prepare) (void),
 			   void (*__parent) (void),
 			   void (*__child) (void)) __THROW;
 
+
+#ifdef __USE_EXTERN_INLINES
+/* Optimizations.  */
+extern __inline int
+__NTH (pthread_equal (pthread_t __thread1, pthread_t __thread2))
+{
+  return __thread1 == __thread2;
+}
+#endif
+
 __END_DECLS
 
 #endif	/* pthread.h */
diff --git a/nptl/sysdeps/pthread/pthread_cond_broadcast.c b/nptl/sysdeps/pthread/pthread_cond_broadcast.c
index 1eac8ecf83..2b8b5460f4 100644
--- a/nptl/sysdeps/pthread/pthread_cond_broadcast.c
+++ b/nptl/sysdeps/pthread/pthread_cond_broadcast.c
@@ -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 Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -55,6 +55,12 @@ __pthread_cond_broadcast (cond)
 
       /* Wake everybody.  */
       pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
+
+      /* XXX: Kernel so far doesn't support requeue to PI futex.  */
+      if (__builtin_expect (mut->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP,
+			    0))
+	goto wake_all;
+
       /* lll_futex_requeue returns 0 for success and non-zero
 	 for errors.  */
       if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1,
diff --git a/nptl/sysdeps/pthread/pthread_cond_signal.c b/nptl/sysdeps/pthread/pthread_cond_signal.c
index f5623480f8..5a9bbcad91 100644
--- a/nptl/sysdeps/pthread/pthread_cond_signal.c
+++ b/nptl/sysdeps/pthread/pthread_cond_signal.c
@@ -43,6 +43,11 @@ __pthread_cond_signal (cond)
       ++cond->__data.__futex;
 
       /* Wake one.  */
+      if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
+						     1, &cond->__data.__lock),
+						     0))
+	return 0;
+
       lll_futex_wake (&cond->__data.__futex, 1);
     }
 
diff --git a/nptl/sysdeps/pthread/pthread_cond_wait.c b/nptl/sysdeps/pthread/pthread_cond_wait.c
index 86669458a0..f5f5cec5a8 100644
--- a/nptl/sysdeps/pthread/pthread_cond_wait.c
+++ b/nptl/sysdeps/pthread/pthread_cond_wait.c
@@ -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 Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -50,10 +50,16 @@ __condvar_cleanup (void *arg)
   if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
     {
       /* This thread is not waiting anymore.  Adjust the sequence counters
-	 appropriately.  */
-      ++cbuffer->cond->__data.__wakeup_seq;
+	 appropriately.  We do not increment WAKEUP_SEQ if this would
+	 bump it over the value of TOTAL_SEQ.  This can happen if a thread
+	 was woken and then canceled.  */
+      if (cbuffer->cond->__data.__wakeup_seq
+	  < cbuffer->cond->__data.__total_seq)
+	{
+	  ++cbuffer->cond->__data.__wakeup_seq;
+	  ++cbuffer->cond->__data.__futex;
+	}
       ++cbuffer->cond->__data.__woken_seq;
-      ++cbuffer->cond->__data.__futex;
     }
 
   cbuffer->cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;
diff --git a/nptl/sysdeps/pthread/sigfillset.c b/nptl/sysdeps/pthread/sigfillset.c
index fe58ccd53e..180607c77b 100644
--- a/nptl/sysdeps/pthread/sigfillset.c
+++ b/nptl/sysdeps/pthread/sigfillset.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2005 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,4 +18,4 @@
 
 #include <nptl/pthreadP.h>
 
-#include <sysdeps/generic/sigfillset.c>
+#include <signal/sigfillset.c>
diff --git a/nptl/sysdeps/pthread/unwind-forcedunwind.c b/nptl/sysdeps/pthread/unwind-forcedunwind.c
index b0f8487086..6792d719d3 100644
--- a/nptl/sysdeps/pthread/unwind-forcedunwind.c
+++ b/nptl/sysdeps/pthread/unwind-forcedunwind.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>.
 
@@ -31,13 +31,18 @@ static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
 static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
 
 void
+__attribute_noinline__
 pthread_cancel_init (void)
 {
   void *resume, *personality, *forcedunwind, *getcfa;
   void *handle;
 
   if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
-    return;
+    {
+      /* Force gcc to reload all values.  */
+      asm volatile ("" ::: "memory");
+      return;
+    }
 
   handle = __libc_dlopen ("libgcc_s.so.1");
 
@@ -56,6 +61,10 @@ pthread_cancel_init (void)
   libgcc_s_resume = resume;
   libgcc_s_personality = personality;
   libgcc_s_forcedunwind = forcedunwind;
+  /* Make sure libgcc_s_getcfa is written last.  Otherwise,
+     pthread_cancel_init might return early even when the pointer the
+     caller is interested in is not initialized yet.  */
+  atomic_write_barrier ();
   libgcc_s_getcfa = getcfa;
 }
 
@@ -64,6 +73,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
 {
   if (__builtin_expect (libgcc_s_resume == NULL, 0))
     pthread_cancel_init ();
+
   libgcc_s_resume (exc);
 }
 
@@ -75,6 +85,7 @@ __gcc_personality_v0 (int version, _Unwind_Action actions,
 {
   if (__builtin_expect (libgcc_s_personality == NULL, 0))
     pthread_cancel_init ();
+
   return libgcc_s_personality (version, actions, exception_class,
 			       ue_header, context);
 }
@@ -85,6 +96,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
 {
   if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
     pthread_cancel_init ();
+
   return libgcc_s_forcedunwind (exc, stop, stop_argument);
 }
 
@@ -93,5 +105,6 @@ _Unwind_GetCFA (struct _Unwind_Context *context)
 {
   if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
     pthread_cancel_init ();
+
   return libgcc_s_getcfa (context);
 }
diff --git a/nptl/sysdeps/s390/jmpbuf-unwind.h b/nptl/sysdeps/s390/jmpbuf-unwind.h
deleted file mode 100644
index 9f7e1ad583..0000000000
--- a/nptl/sysdeps/s390/jmpbuf-unwind.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <setjmp.h>
-#include <stdint.h>
-#include <unwind.h>
-#include <bits/wordsize.h>
-
-/* On s390{,x}, CFA is always 96 (resp. 160) bytes above actual
-   %r15.  */
-#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
-  _JMPBUF_UNWINDS_ADJ (_jmpbuf,					\
-		       (void *) (_Unwind_GetCFA (_context)	\
-				 - 32 - 2 * __WORDSIZE), _adj)
-
-#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj)		\
-  ((uintptr_t) (_address) - (_adj)				\
-   < (uintptr_t) (_jmpbuf)->__gregs[__JB_GPR15] - (_adj))
-
-/* We use the normal longjmp for unwinding.  */
-#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/nptl/sysdeps/s390/tcb-offsets.sym b/nptl/sysdeps/s390/tcb-offsets.sym
index 237f975b25..9cfae211e0 100644
--- a/nptl/sysdeps/s390/tcb-offsets.sym
+++ b/nptl/sysdeps/s390/tcb-offsets.sym
@@ -2,5 +2,6 @@
 #include <tls.h>
 
 MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
+STACK_GUARD			offsetof (tcbhead_t, stack_guard)
 PID				offsetof (struct pthread, pid)
 TID				offsetof (struct pthread, tid)
diff --git a/nptl/sysdeps/s390/tls.h b/nptl/sysdeps/s390/tls.h
index c9b991df32..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 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
@@ -22,6 +22,7 @@
 
 #include <dl-sysdep.h>
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 # include <stdlib.h>
@@ -32,7 +33,11 @@
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
@@ -43,9 +48,9 @@ typedef struct
   dtv_t *dtv;
   void *self;		/* Pointer to the thread descriptor.  */
   int multiple_threads;
-# ifdef NEED_DL_SYSINFO
   uintptr_t sysinfo;
-# endif
+  uintptr_t stack_guard;
+  int gscope_flag;
 } tcbhead_t;
 
 # ifndef __s390x__
@@ -76,11 +81,13 @@ typedef struct
 /* Get the thread descriptor definition.  */
 # include <nptl/descr.h>
 
-/* This is the size of the initial TCB.  */
-# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+/* This is the size of the initial TCB.  Can't be just sizeof (tcbhead_t),
+   because NPTL getpid, __libc_alloca_cutoff etc. need (almost) the whole
+   struct pthread even when not linked with -lpthread.  */
+# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
 
 /* Alignment requirements for the initial TCB.  */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
 
 /* This is the size of the TCB.  */
 # define TLS_TCB_SIZE sizeof (struct pthread)
@@ -151,6 +158,43 @@ typedef struct
 #define THREAD_SETMEM_NC(descr, member, idx, value) \
   descr->member[idx] = (value)
 
+/* Set the stack guard field in TCB head.  */
+#define THREAD_SET_STACK_GUARD(value) \
+  THREAD_SETMEM (THREAD_SELF, header.stack_guard, value)
+#define THREAD_COPY_STACK_GUARD(descr) \
+  ((descr)->header.stack_guard						      \
+   = THREAD_GETMEM (THREAD_SELF, header.stack_guard))
+
+/* s390 doesn't have HP_TIMING_*, so for the time being
+   use stack_guard as pointer_guard.  */
+#define THREAD_GET_POINTER_GUARD() \
+  THREAD_GETMEM (THREAD_SELF, header.stack_guard)
+#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/tcb-offsets.sym b/nptl/sysdeps/sh/tcb-offsets.sym
index 539789a817..4ad866335b 100644
--- a/nptl/sysdeps/sh/tcb-offsets.sym
+++ b/nptl/sysdeps/sh/tcb-offsets.sym
@@ -9,3 +9,4 @@ CLEANUP_JMP_BUF		offsetof (struct pthread, cleanup_jmp_buf)
 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)
diff --git a/nptl/sysdeps/sh/tls.h b/nptl/sysdeps/sh/tls.h
index db490ab7ee..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 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
@@ -23,6 +23,7 @@
 # include <dl-sysdep.h>
 
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 
@@ -30,13 +31,17 @@
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 typedef struct
 {
   dtv_t *dtv;
-  void *private;
+  uintptr_t pointer_guard;
 } tcbhead_t;
 
 # define TLS_MULTIPLE_THREADS_IN_TCB 1
@@ -135,6 +140,42 @@ typedef struct
 # define THREAD_SETMEM_NC(descr, member, idx, value) \
     descr->member[idx] = (value)
 
+#define THREAD_GET_POINTER_GUARD() \
+  ({ tcbhead_t *__tcbp;							      \
+     __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));			      \
+     __tcbp->pointer_guard;})
+ #define THREAD_SET_POINTER_GUARD(value) \
+  ({ tcbhead_t *__tcbp;							      \
+     __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));			      \
+     __tcbp->pointer_guard = (value);})
+#define THREAD_COPY_POINTER_GUARD(descr) \
+  ({ tcbhead_t *__tcbp;							      \
+     __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/sparc32/jmpbuf-unwind.h b/nptl/sysdeps/sparc/sparc32/jmpbuf-unwind.h
deleted file mode 100644
index 5cef8b1cf5..0000000000
--- a/nptl/sysdeps/sparc/sparc32/jmpbuf-unwind.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <setjmp.h>
-#include <stdint.h>
-#include <unwind.h>
-
-#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
-  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
-
-#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
-  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_SP] - (_adj))
-
-/* We use the normal lobngjmp for unwinding.  */
-#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/nptl/sysdeps/sparc/tcb-offsets.sym b/nptl/sysdeps/sparc/tcb-offsets.sym
index 237f975b25..923af8a5b7 100644
--- a/nptl/sysdeps/sparc/tcb-offsets.sym
+++ b/nptl/sysdeps/sparc/tcb-offsets.sym
@@ -2,5 +2,6 @@
 #include <tls.h>
 
 MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
+POINTER_GUARD			offsetof (tcbhead_t, pointer_guard)
 PID				offsetof (struct pthread, pid)
 TID				offsetof (struct pthread, tid)
diff --git a/nptl/sysdeps/sparc/tls.h b/nptl/sysdeps/sparc/tls.h
index 8980f9fc0c..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 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
@@ -22,6 +22,7 @@
 
 #include <dl-sysdep.h>
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 # include <stdlib.h>
@@ -31,7 +32,11 @@
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 typedef struct
@@ -41,6 +46,9 @@ typedef struct
   dtv_t *dtv;
   void *self;
   int multiple_threads;
+  uintptr_t sysinfo;
+  uintptr_t stack_guard;
+  uintptr_t pointer_guard;
 } tcbhead_t;
 
 #else /* __ASSEMBLER__ */
@@ -64,11 +72,13 @@ typedef struct
 
 register struct pthread *__thread_self __asm__("%g7");
 
-/* This is the size of the initial TCB.  */
-# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+/* This is the size of the initial TCB.  Can't be just sizeof (tcbhead_t),
+   because NPTL getpid, __libc_alloca_cutoff etc. need (almost) the whole
+   struct pthread even when not linked with -lpthread.  */
+# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
 
 /* Alignment requirements for the initial TCB.  */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
 
 /* This is the size of the TCB.  */
 # define TLS_TCB_SIZE sizeof (struct pthread)
@@ -119,6 +129,44 @@ register struct pthread *__thread_self __asm__("%g7");
 #define THREAD_SETMEM_NC(descr, member, idx, value) \
   descr->member[idx] = (value)
 
+/* Set the stack guard field in TCB head.  */
+#define THREAD_SET_STACK_GUARD(value) \
+  THREAD_SETMEM (THREAD_SELF, header.stack_guard, value)
+# define THREAD_COPY_STACK_GUARD(descr) \
+  ((descr)->header.stack_guard \
+   = THREAD_GETMEM (THREAD_SELF, header.stack_guard))
+
+/* Get/set the stack guard field in TCB head.  */
+#define THREAD_GET_POINTER_GUARD() \
+  THREAD_GETMEM (THREAD_SELF, header.pointer_guard)
+#define THREAD_SET_POINTER_GUARD(value) \
+  THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
+# 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/Makefile b/nptl/sysdeps/unix/sysv/linux/Makefile
index 991398242a..cfcdb6d97f 100644
--- a/nptl/sysdeps/unix/sysv/linux/Makefile
+++ b/nptl/sysdeps/unix/sysv/linux/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 2002, 2003, 2004 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 Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -24,7 +24,8 @@ sysdep_routines += register-atfork unregister-atfork libc_pthread_init \
 libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock
 
 gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
-			lowlevelbarrier.sym unwindbuf.sym
+			lowlevelbarrier.sym unwindbuf.sym \
+			lowlevelrobustlock.sym pthread-pi-defines.sym
 endif
 
 ifeq ($(subdir),posix)
@@ -32,3 +33,6 @@ CFLAGS-fork.c = -D_IO_MTSAFE_IO
 CFLAGS-getpid.o = -fomit-frame-pointer
 CFLAGS-getpid.os = -fomit-frame-pointer
 endif
+
+# Needed in both the signal and nptl subdir.
+CFLAGS-sigaction.c = -DWRAPPER_INCLUDE='<nptl/sigaction.c>'
diff --git a/nptl/sysdeps/unix/sysv/linux/aio_misc.h b/nptl/sysdeps/unix/sysv/linux/aio_misc.h
index 7b0bac75f2..406d96e865 100644
--- a/nptl/sysdeps/unix/sysv/linux/aio_misc.h
+++ b/nptl/sysdeps/unix/sysv/linux/aio_misc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
 
@@ -19,9 +19,10 @@
 
 #ifndef _AIO_MISC_H
 # include_next <aio_misc.h>
+# include <limits.h>
+# include <pthread.h>
 # include <signal.h>
 # include <sysdep.h>
-# include <pthread.h>
 
 # define aio_start_notify_thread __aio_start_notify_thread
 # define aio_create_helper_thread __aio_create_helper_thread
@@ -36,7 +37,8 @@ __aio_start_notify_thread (void)
 }
 
 extern inline int
-__aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), void *arg)
+__aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *),
+			    void *arg)
 {
   pthread_attr_t attr;
 
@@ -63,5 +65,5 @@ __aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), void *arg)
 
   (void) pthread_attr_destroy (&attr);
   return ret;
-}                                                                                 
+}
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
index d13d6e86a4..41a54d4b0d 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
@@ -1,5 +1,5 @@
 /* Machine-specific pthread type layouts.  Alpha version.
-   Copyright (C) 2003, 2004 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
@@ -43,11 +43,18 @@ typedef union
 } pthread_attr_t;
 
 
+typedef struct __pthread_internal_list
+{
+  struct __pthread_internal_list *__prev;
+  struct __pthread_internal_list *__next;
+} __pthread_list_t;
+
+
 /* Data structures for mutex handling.  The structure of the attribute
    type is deliberately not exposed.  */
 typedef union
 {
-  struct
+  struct __pthread_mutex_s
   {
     int __lock;
     unsigned int __count;
@@ -57,6 +64,8 @@ typedef union
        binary compatibility.  */
     int __kind;
     int __spins;
+    __pthread_list_t __list;
+#define __PTHREAD_MUTEX_HAVE_PREV	1
   } __data;
   char __size[__SIZEOF_PTHREAD_MUTEX_T];
   long int __align;
@@ -117,8 +126,9 @@ typedef union
     unsigned int __nr_readers_queued;
     unsigned int __nr_writers_queued;
     int __writer;
-
-    unsigned int __reserved[6];
+    int __pad1;
+    unsigned long int __pad2;
+    unsigned long int __pad3;
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
     unsigned int __flags;
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/clone.S b/nptl/sysdeps/unix/sysv/linux/alpha/clone.S
index eea1cbeed1..675a997e97 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/clone.S
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/clone.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/alpha/clone.S>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
index fd4a7ca4bb..58b4806eb2 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 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 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
@@ -31,6 +31,11 @@
 #define FUTEX_WAKE		1
 #define FUTEX_REQUEUE		3
 #define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
 
 /* Initializer for compatibility lock.	*/
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
@@ -62,6 +67,15 @@
     INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret;		      \
   })
 
+#define lll_robust_mutex_dead(futexv) \
+  do									      \
+    {									      \
+      int *__futexp = &(futexv);					      \
+      atomic_or (__futexp, FUTEX_OWNER_DIED);				      \
+      lll_futex_wake (__futexp, 1);					      \
+    }									      \
+  while (0)
+
 /* Returns non-zero if error happened, zero if success.  */
 #define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \
   ({									      \
@@ -73,6 +87,20 @@
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
   })
 
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6,				      \
+			      (futexp), FUTEX_WAKE_OP, (nr_wake),	      \
+			      (nr_wake2), (futexp2),			      \
+			      FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);		      \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
+  })
+
+
+
 
 static inline int __attribute__((always_inline))
 __lll_mutex_trylock(int *futex)
@@ -90,7 +118,16 @@ __lll_mutex_cond_trylock(int *futex)
 #define lll_mutex_cond_trylock(lock)	__lll_mutex_cond_trylock (&(lock))
 
 
+static inline int __attribute__((always_inline))
+__lll_robust_mutex_trylock(int *futex, int id)
+{
+  return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0;
+}
+#define lll_robust_mutex_trylock(lock, id) \
+  __lll_robust_mutex_trylock (&(lock), id)
+
 extern void __lll_lock_wait (int *futex) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex) attribute_hidden;
 
 static inline void __attribute__((always_inline))
 __lll_mutex_lock(int *futex)
@@ -101,6 +138,18 @@ __lll_mutex_lock(int *futex)
 #define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
 
 
+static inline int __attribute__ ((always_inline))
+__lll_robust_mutex_lock (int *futex, int id)
+{
+  int result = 0;
+  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+    result = __lll_robust_lock_wait (futex);
+  return result;
+}
+#define lll_robust_mutex_lock(futex, id) \
+  __lll_robust_mutex_lock (&(futex), id)
+
+
 static inline void __attribute__ ((always_inline))
 __lll_mutex_cond_lock (int *futex)
 {
@@ -110,8 +159,14 @@ __lll_mutex_cond_lock (int *futex)
 #define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex))
 
 
+#define lll_robust_mutex_cond_lock(futex, id) \
+  __lll_robust_mutex_lock (&(futex), (id) | FUTEX_WAITERS)
+
+
 extern int __lll_timedlock_wait (int *futex, const struct timespec *)
 	attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
+	attribute_hidden;
 
 static inline int __attribute__ ((always_inline))
 __lll_mutex_timedlock (int *futex, const struct timespec *abstime)
@@ -125,6 +180,19 @@ __lll_mutex_timedlock (int *futex, const struct timespec *abstime)
   __lll_mutex_timedlock (&(futex), abstime)
 
 
+static inline int __attribute__ ((always_inline))
+__lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
+			      int id)
+{
+  int result = 0;
+  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+    result = __lll_robust_timedlock_wait (futex, abstime);
+  return result;
+}
+#define lll_robust_mutex_timedlock(futex, abstime, id) \
+  __lll_robust_mutex_timedlock (&(futex), abstime, id)
+
+
 static inline void __attribute__ ((always_inline))
 __lll_mutex_unlock (int *futex)
 {
@@ -136,6 +204,17 @@ __lll_mutex_unlock (int *futex)
 
 
 static inline void __attribute__ ((always_inline))
+__lll_robust_mutex_unlock (int *futex, int mask)
+{
+  int val = atomic_exchange_rel (futex, 0);
+  if (__builtin_expect (val & mask, 0))
+    lll_futex_wake (futex, 1);
+}
+#define lll_robust_mutex_unlock(futex) \
+  __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS)
+
+
+static inline void __attribute__ ((always_inline))
 __lll_mutex_unlock_force (int *futex)
 {
   (void) atomic_exchange_rel (futex, 0);
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/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h
index 0bc8e048af..b639ba44af 100644
--- a/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h
+++ b/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h
@@ -3,16 +3,16 @@
    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 Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
+   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
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
+   You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If not,
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
diff --git a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
index 09f3df11cb..dd0798a073 100644
--- a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
+++ b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
@@ -1,18 +1,18 @@
 /* Define POSIX options for Linux.
-   Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-2004, 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
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
+   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
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
+   You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If not,
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
@@ -60,6 +60,9 @@
 /* X/Open realtime support is available.  */
 #define _XOPEN_REALTIME	1
 
+/* X/Open thread realtime support is available.  */
+#define _XOPEN_REALTIME_THREADS	1
+
 /* XPG4.2 shared memory is supported.  */
 #define	_XOPEN_SHM	1
 
@@ -79,6 +82,13 @@
 /* We support user-defined stacks.  */
 #define _POSIX_THREAD_ATTR_STACKADDR	200112L
 
+/* We support priority inheritence.  */
+#define _POSIX_THREAD_PRIO_INHERIT	200112L
+
+/* We support priority protection, though only for non-robust
+   mutexes.  */
+#define _POSIX_THREAD_PRIO_PROTECT	200112L
+
 /* We support POSIX.1b semaphores.  */
 #define _POSIX_SEMAPHORES	200112L
 
@@ -171,8 +181,4 @@
 /* Typed memory objects are not available.  */
 #define _POSIX_TYPED_MEMORY_OBJECTS	-1
 
-/* No support for priority inheritance or protection so far.  */
-#define _POSIX_THREAD_PRIO_INHERIT	-1
-#define _POSIX_THREAD_PRIO_PROTECT	-1
-
 #endif /* posix_opt.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/configure b/nptl/sysdeps/unix/sysv/linux/configure
deleted file mode 100644
index 229414dd74..0000000000
--- a/nptl/sysdeps/unix/sysv/linux/configure
+++ /dev/null
@@ -1,3 +0,0 @@
-# Local configure fragment for sysdeps/unix/sysv/linux.
-
-DEFINES="$DEFINES -D_LIBC_REENTRANT"
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/fork.h b/nptl/sysdeps/unix/sysv/linux/fork.h
index d093ccc907..6458977b99 100644
--- a/nptl/sysdeps/unix/sysv/linux/fork.h
+++ b/nptl/sysdeps/unix/sysv/linux/fork.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -41,7 +41,7 @@ struct fork_handler
 };
 
 /* The single linked list of all currently registered for handlers.  */
-extern struct fork_handler *__fork_handlers;
+extern struct fork_handler *__fork_handlers attribute_hidden;
 
 
 /* Function to call to unregister fork handlers.  */
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
index 4d1c9450b5..f53d0e5a72 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 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
@@ -43,11 +43,17 @@ typedef union
 } pthread_attr_t;
 
 
+typedef struct __pthread_internal_slist
+{
+  struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+
+
 /* Data structures for mutex handling.  The structure of the attribute
    type is not exposed on purpose.  */
 typedef union
 {
-  struct
+  struct __pthread_mutex_s
   {
     int __lock;
     unsigned int __count;
@@ -56,7 +62,11 @@ typedef union
        binary compatibility.  */
     int __kind;
     unsigned int __nusers;
-    int __spins;
+    __extension__ union
+    {
+      int __spins;
+      __pthread_slist_t __list;
+    };
   } __data;
   char __size[__SIZEOF_PTHREAD_MUTEX_T];
   long int __align;
@@ -155,6 +165,6 @@ typedef union
 
 
 /* Extra attributes for the cleanup functions.  */
-#define __cleanup_fct_attribute __attribute ((regparm (1)))
+#define __cleanup_fct_attribute __attribute__ ((__regparm__ (1)))
 
 #endif	/* bits/pthreadtypes.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/clone.S b/nptl/sysdeps/unix/sysv/linux/i386/clone.S
index 95c17f18e4..675a997e97 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/clone.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/clone.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/i386/clone.S>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
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 223b111083..88885b735d 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
@@ -22,7 +22,7 @@
 #ifndef UP
 # define LOCK \
 	cmpl	$0, %gs:MULTIPLE_THREADS_OFFSET; 			      \
-	je,pt	0f;							      \
+	je	0f;							      \
 	lock;								      \
 0:
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
index dc65b709a1..e2da5b04cf 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 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.
 
@@ -41,9 +41,16 @@
 	.hidden	__lll_mutex_lock_wait
 	.align	16
 __lll_mutex_lock_wait:
+	cfi_startproc
 	pushl	%edx
+	cfi_adjust_cfa_offset(4)
 	pushl	%ebx
+	cfi_adjust_cfa_offset(4)
 	pushl	%esi
+	cfi_adjust_cfa_offset(4)
+	cfi_offset(%edx, -8)
+	cfi_offset(%ebx, -12)
+	cfi_offset(%esi, -16)
 
 	movl	$2, %edx
 	movl	%ecx, %ebx
@@ -60,12 +67,19 @@ __lll_mutex_lock_wait:
 	xchgl	%eax, (%ebx)	/* NB:	 lock is implied */
 
 	testl	%eax, %eax
-	jnz,pn	1b
+	jnz	1b
 
 	popl	%esi
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%esi)
 	popl	%ebx
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%ebx)
 	popl	%edx
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%edx)
 	ret
+	cfi_endproc
 	.size	__lll_mutex_lock_wait,.-__lll_mutex_lock_wait
 
 
@@ -75,17 +89,27 @@ __lll_mutex_lock_wait:
 	.hidden	__lll_mutex_timedlock_wait
 	.align	16
 __lll_mutex_timedlock_wait:
+	cfi_startproc
 	/* Check for a valid timeout value.  */
 	cmpl	$1000000000, 4(%edx)
 	jae	3f
 
 	pushl	%edi
+	cfi_adjust_cfa_offset(4)
 	pushl	%esi
+	cfi_adjust_cfa_offset(4)
 	pushl	%ebx
+	cfi_adjust_cfa_offset(4)
 	pushl	%ebp
+	cfi_adjust_cfa_offset(4)
+	cfi_offset(%edi, -8)
+	cfi_offset(%esi, -12)
+	cfi_offset(%ebx, -16)
+	cfi_offset(%ebp, -20)
 
 	/* Stack frame for the timespec and timeval structs.  */
 	subl	$8, %esp
+	cfi_adjust_cfa_offset(8)
 
 	movl	%ecx, %ebp
 	movl	%edx, %edi
@@ -140,12 +164,29 @@ __lll_mutex_timedlock_wait:
 	jnz	7f
 
 6:	addl	$8, %esp
+	cfi_adjust_cfa_offset(-8)
 	popl	%ebp
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%ebp)
 	popl	%ebx
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%ebx)
 	popl	%esi
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%esi)
 	popl	%edi
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%edi)
 	ret
 
+3:	movl	$EINVAL, %eax
+	ret
+
+	cfi_adjust_cfa_offset(24)
+	cfi_offset(%edi, -8)
+	cfi_offset(%esi, -12)
+	cfi_offset(%ebx, -16)
+	cfi_offset(%ebp, -20)
 	/* Check whether the time expired.  */
 7:	cmpl	$-ETIMEDOUT, %ecx
 	je	5f
@@ -157,11 +198,9 @@ __lll_mutex_timedlock_wait:
 	jz	6b
 	jmp	1b
 
-3:	movl	$EINVAL, %eax
-	ret
-
 5:	movl	$ETIMEDOUT, %eax
 	jmp	6b
+	cfi_endproc
 	.size	__lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
 #endif
 
@@ -200,9 +239,16 @@ lll_unlock_wake_cb:
 	.hidden	__lll_mutex_unlock_wake
 	.align	16
 __lll_mutex_unlock_wake:
+	cfi_startproc
 	pushl	%ebx
+	cfi_adjust_cfa_offset(4)
 	pushl	%ecx
+	cfi_adjust_cfa_offset(4)
 	pushl	%edx
+	cfi_adjust_cfa_offset(4)
+	cfi_offset(%ebx, -8)
+	cfi_offset(%ecx, -12)
+	cfi_offset(%edx, -16)
 
 	movl	%eax, %ebx
 	movl	$0, (%eax)
@@ -212,9 +258,16 @@ __lll_mutex_unlock_wake:
 	ENTER_KERNEL
 
 	popl	%edx
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%edx)
 	popl	%ecx
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%ecx)
 	popl	%ebx
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%ebx)
 	ret
+	cfi_endproc
 	.size	__lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
 
 
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S
new file mode 100644
index 0000000000..73d8bc4ccc
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S
@@ -0,0 +1,227 @@
+/* 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.
+
+   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 <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevelrobustlock.h>
+
+	.text
+
+#ifndef LOCK
+# ifdef UP
+#  define LOCK
+# else
+#  define LOCK lock
+# endif
+#endif
+
+#define SYS_gettimeofday	__NR_gettimeofday
+#define SYS_futex		240
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_WAITERS		0x80000000
+#define FUTEX_OWNER_DIED	0x40000000
+
+
+	.globl	__lll_robust_mutex_lock_wait
+	.type	__lll_robust_mutex_lock_wait,@function
+	.hidden	__lll_robust_mutex_lock_wait
+	.align	16
+__lll_robust_mutex_lock_wait:
+	cfi_startproc
+	pushl	%edx
+	cfi_adjust_cfa_offset(4)
+	pushl	%ebx
+	cfi_adjust_cfa_offset(4)
+	pushl	%esi
+	cfi_adjust_cfa_offset(4)
+	cfi_offset(%edx, -8)
+	cfi_offset(%ebx, -12)
+	cfi_offset(%esi, -16)
+
+	movl	%ecx, %ebx
+	xorl	%esi, %esi	/* No timeout.  */
+	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */
+
+4:	movl	%eax, %edx
+	orl	$FUTEX_WAITERS, %edx
+
+	testl	$FUTEX_OWNER_DIED, %eax
+	jnz	3f
+
+	cmpl	%edx, %eax	/* NB:	 %edx == 2 */
+	je	1f
+
+	LOCK
+	cmpxchgl %edx, (%ebx)
+	jnz	2f
+
+1:	movl	$SYS_futex, %eax
+	ENTER_KERNEL
+
+	movl	(%ebx), %eax
+
+2:	test	%eax, %eax
+	jne	4b
+
+	movl	%gs:TID, %edx
+	orl	$FUTEX_WAITERS, %edx
+	LOCK
+	cmpxchgl %edx, (%ebx)
+	jnz	4b
+	/* NB:	 %eax == 0 */
+
+3:	popl	%esi
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%esi)
+	popl	%ebx
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%ebx)
+	popl	%edx
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%edx)
+	ret
+	cfi_endproc
+	.size	__lll_robust_mutex_lock_wait,.-__lll_robust_mutex_lock_wait
+
+
+	.globl	__lll_robust_mutex_timedlock_wait
+	.type	__lll_robust_mutex_timedlock_wait,@function
+	.hidden	__lll_robust_mutex_timedlock_wait
+	.align	16
+__lll_robust_mutex_timedlock_wait:
+	cfi_startproc
+	/* Check for a valid timeout value.  */
+	cmpl	$1000000000, 4(%edx)
+	jae	3f
+
+	pushl	%edi
+	cfi_adjust_cfa_offset(4)
+	pushl	%esi
+	cfi_adjust_cfa_offset(4)
+	pushl	%ebx
+	cfi_adjust_cfa_offset(4)
+	pushl	%ebp
+	cfi_adjust_cfa_offset(4)
+	cfi_offset(%edi, -8)
+	cfi_offset(%esi, -12)
+	cfi_offset(%ebx, -16)
+	cfi_offset(%ebp, -20)
+
+	/* Stack frame for the timespec and timeval structs.  */
+	subl	$12, %esp
+	cfi_adjust_cfa_offset(12)
+
+	movl	%ecx, %ebp
+	movl	%edx, %edi
+
+1:	movl	%eax, 8(%esp)
+
+	/* Get current time.  */
+	movl	%esp, %ebx
+	xorl	%ecx, %ecx
+	movl	$SYS_gettimeofday, %eax
+	ENTER_KERNEL
+
+	/* Compute relative timeout.  */
+	movl	4(%esp), %eax
+	movl	$1000, %edx
+	mul	%edx		/* Milli seconds to nano seconds.  */
+	movl	(%edi), %ecx
+	movl	4(%edi), %edx
+	subl	(%esp), %ecx
+	subl	%eax, %edx
+	jns	4f
+	addl	$1000000000, %edx
+	subl	$1, %ecx
+4:	testl	%ecx, %ecx
+	js	8f		/* Time is already up.  */
+
+	/* Store relative timeout.  */
+	movl	%ecx, (%esp)
+	movl	%edx, 4(%esp)
+
+	movl	%ebp, %ebx
+
+	movl	8(%esp), %edx
+	movl	%edx, %eax
+	orl	$FUTEX_WAITERS, %edx
+
+	testl	$FUTEX_OWNER_DIED, %eax
+	jnz	6f
+
+	cmpl	%eax, %edx
+	je	2f
+
+	LOCK
+	cmpxchgl %edx, (%ebx)
+	movl	$0, %ecx	/* Must use mov to avoid changing cc.  */
+	jnz	5f
+
+2:
+	/* Futex call.  */
+	movl	%esp, %esi
+	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */
+	movl	$SYS_futex, %eax
+	ENTER_KERNEL
+	movl	%eax, %ecx
+
+	movl	(%ebx), %eax
+
+5:	testl	%eax, %eax
+	jne	7f
+
+	movl	%gs:TID, %edx
+	orl	$FUTEX_WAITERS, %edx
+	LOCK
+	cmpxchgl %edx, (%ebx)
+	jnz	7f
+
+6:	addl	$12, %esp
+	cfi_adjust_cfa_offset(-12)
+	popl	%ebp
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%ebp)
+	popl	%ebx
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%ebx)
+	popl	%esi
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%esi)
+	popl	%edi
+	cfi_adjust_cfa_offset(-4)
+	cfi_restore(%edi)
+	ret
+
+3:	movl	$EINVAL, %eax
+	ret
+
+	cfi_adjust_cfa_offset(28)
+	cfi_offset(%edi, -8)
+	cfi_offset(%esi, -12)
+	cfi_offset(%ebx, -16)
+	cfi_offset(%ebp, -20)
+	/* Check whether the time expired.  */
+7:	cmpl	$-ETIMEDOUT, %ecx
+	jne	1b
+
+8:	movl	$ETIMEDOUT, %eax
+	jmp	6b
+	cfi_endproc
+	.size	__lll_robust_mutex_timedlock_wait,.-__lll_robust_mutex_timedlock_wait
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 114284c44c..fe7a8b9c66 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
@@ -82,7 +82,7 @@ pthread_barrier_wait:
 #else
 	cmpl	%edx, CURR_EVENT(%ebx)
 #endif
-	je,pn	8b
+	je	8b
 
 	/* Increment LEFT.  If this brings the count back to the
 	   initial count unlock the object.  */
@@ -92,7 +92,7 @@ pthread_barrier_wait:
 	xaddl	%edx, LEFT(%ebx)
 	subl	$1, %ecx
 	cmpl	%ecx, %edx
-	jne,pt	10f
+	jne	10f
 
 	/* Release the mutex.  We cannot release the lock before
 	   waking the waiting threads since otherwise a new thread might
@@ -131,7 +131,7 @@ pthread_barrier_wait:
 	xaddl	%edx, LEFT(%ebx)
 	subl	$1, %ecx
 	cmpl	%ecx, %edx
-	jne,pt	5f
+	jne	5f
 
 	/* Release the mutex.  We cannot release the lock before
 	   waking the waiting threads since otherwise a new thread might
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
index 5471c1c927..56f7be8246 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
@@ -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.
 
@@ -21,6 +21,7 @@
 #include <shlib-compat.h>
 #include <lowlevelcond.h>
 #include <kernel-features.h>
+#include <pthread-pi-defines.h>
 
 #ifdef UP
 # define LOCK
@@ -94,6 +95,10 @@ __pthread_cond_broadcast:
 8:	cmpl	$-1, %edi
 	je	9f
 
+	/* XXX: The kernel so far doesn't support requeue to PI futex.  */
+	testl	$PI_BIT, MUTEX_KIND(%edi)
+	jne	9f
+
 	/* Wake up all threads.  */
 	movl	$FUTEX_CMP_REQUEUE, %ecx
 	movl	$SYS_futex, %eax
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
index 3c5a1db59c..d0f931ff15 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -31,7 +31,9 @@
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
-#define FUTEX_REQUEUE		3
+#define FUTEX_WAKE_OP		5
+
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)
 
 #define EINVAL			22
 
@@ -79,21 +81,46 @@ __pthread_cond_signal:
 	addl	$1, (%ebx)
 
 	/* Wake up one thread.  */
-	movl	$FUTEX_WAKE, %ecx
+	pushl	%esi
+	pushl	%ebp
+	movl	$FUTEX_WAKE_OP, %ecx
 	movl	$SYS_futex, %eax
 	movl	$1, %edx
+	movl	$1, %esi
+	movl	$FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %ebp
+	/* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for
+	   sysenter.
+	ENTER_KERNEL  */
+	int	$0x80
+	popl	%ebp
+	popl	%esi
+
+	/* For any kind of error, we try again with WAKE.
+	   The general test also covers running on old kernels.  */
+	cmpl	$-4095, %eax
+	jae	7f
+
+6:	xorl	%eax, %eax
+	popl	%edi
+	popl	%ebx
+	ret
+
+7:	movl	$FUTEX_WAKE, %ecx
+	movl	$SYS_futex, %eax
+	/* %edx should be 1 already from $FUTEX_WAKE_OP syscall.
+	movl	$1, %edx  */
 	ENTER_KERNEL
 
 	/* Unlock.  Note that at this point %edi always points to
 	   cond_lock.  */
 4:	LOCK
 	subl	$1, (%edi)
-	jne	5f
+	je	6b
 
-6:	xorl	%eax, %eax
-	popl	%edi
-	popl	%ebx
-	ret
+	/* Unlock in loop requires wakeup.  */
+5:	movl	%edi, %eax
+	call	__lll_mutex_unlock_wake
+	jmp	6b
 
 	/* Initial locking failed.  */
 1:
@@ -105,10 +132,6 @@ __pthread_cond_signal:
 	call	__lll_mutex_lock_wait
 	jmp	2b
 
-	/* Unlock in loop requires wakeup.  */
-5:	movl	%edi, %eax
-	call	__lll_mutex_unlock_wake
-	jmp	6b
 	.size	__pthread_cond_signal, .-__pthread_cond_signal
 versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
 		  GLIBC_2_3_2)
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 699c2cb227..f481a8e43c 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 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.
 
@@ -406,12 +406,22 @@ __condvar_tw_cleanup:
 	cmpl	20(%esp), %eax
 	jne	3f
 
-	addl	$1, wakeup_seq(%ebx)
+	/* We increment the wakeup_seq counter only if it is lower than
+	   total_seq.  If this is not the case the thread was woken and
+	   then canceled.  In this case we ignore the signal.  */
+	movl	total_seq(%ebx), %eax
+	movl	total_seq+4(%ebx), %edi
+	cmpl	wakeup_seq+4(%ebx), %edi
+	jb	6f
+	ja	7f
+	cmpl	wakeup_seq(%ebx), %eax
+	jbe	7f
+
+6:	addl	$1, wakeup_seq(%ebx)
 	adcl	$0, wakeup_seq+4(%ebx)
-
 	addl	$1, cond_futex(%ebx)
 
-	addl	$1, woken_seq(%ebx)
+7:	addl	$1, woken_seq(%ebx)
 	adcl	$0, woken_seq+4(%ebx)
 
 3:	subl	$(1 << clock_bits), 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 d282785151..f16c7d9198 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 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.
 
@@ -297,12 +297,22 @@ __condvar_w_cleanup:
 	cmpl	12(%esp), %eax
 	jne	3f
 
-	addl	$1, wakeup_seq(%ebx)
+	/* We increment the wakeup_seq counter only if it is lower than
+	   total_seq.  If this is not the case the thread was woken and
+	   then canceled.  In this case we ignore the signal.  */
+	movl	total_seq(%ebx), %eax
+	movl	total_seq+4(%ebx), %edi
+	cmpl	wakeup_seq+4(%ebx), %edi
+	jb	6f
+	ja	7f
+	cmpl	wakeup_seq(%ebx), %eax
+	jbe	7f
+
+6:	addl	$1, wakeup_seq(%ebx)
 	adcl	$0, wakeup_seq+4(%ebx)
-
 	addl	$1, cond_futex(%ebx)
 
-	addl	$1, woken_seq(%ebx)
+7:	addl	$1, woken_seq(%ebx)
 	adcl	$0, woken_seq+4(%ebx)
 
 3:	subl	$(1 << clock_bits), cond_nwaiters(%ebx)
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 3d67329bd1..71e96d2228 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -65,9 +65,14 @@ __new_sem_post:
 #endif
 	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
 #if USE___THREAD
-	movl	%gs:0, %edx
-	subl	errno@gottpoff(%ebx), %edx
+# ifdef NO_TLS_DIRECT_SEG_REFS
+	movl	errno@gotntpoff(%ebx), %edx
+	addl	%gs:0, %edx
 	movl	$EINVAL, (%edx)
+# else
+	movl	errno@gotntpoff(%ebx), %edx
+	movl	$EINVAL, %gs:(%edx)
+# endif
 #else
 	call	__errno_location@plt
 	movl	$EINVAL, (%eax)
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 5b24476936..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 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.
 
@@ -49,12 +49,12 @@ sem_timedwait:
 
 	movl	(%ecx), %eax
 2:	testl	%eax, %eax
-	je,pn	1f
+	je	1f
 
 	leal	-1(%eax), %edx
 	LOCK
 	cmpxchgl %edx, (%ecx)
-	jne,pn	2b
+	jne	2b
 
 	xorl	%eax, %eax
 	ret
@@ -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
@@ -117,7 +118,7 @@ sem_timedwait:
 	call	__pthread_disable_asynccancel
 
 	testl	%esi, %esi
-	je,pt	9f
+	je	9f
 	cmpl	$-EWOULDBLOCK, %esi
 	jne	3f
 
@@ -128,7 +129,7 @@ sem_timedwait:
 	leal	-1(%eax), %ecx
 	LOCK
 	cmpxchgl %ecx, (%ebx)
-	jne,pn	8b
+	jne	8b
 
 	addl	$12, %esp
 	cfi_adjust_cfa_offset(-12)
@@ -158,9 +159,14 @@ sem_timedwait:
 #endif
 	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
 #if USE___THREAD
-	movl	%gs:0, %edx
-	subl	errno@gottpoff(%ebx), %edx
+# 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)
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S
index a7c405d95f..fbc3b3c932 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -42,7 +42,7 @@ __new_sem_trywait:
 	leal	-1(%eax), %edx
 	LOCK
 	cmpxchgl %edx, (%ecx)
-	jne,pn	2b
+	jne	2b
 	xorl	%eax, %eax
 	ret
 
@@ -55,9 +55,14 @@ __new_sem_trywait:
 #endif
 	addl	$_GLOBAL_OFFSET_TABLE_, %ecx
 #if USE___THREAD
-	movl	%gs:0, %edx
-	subl	errno@gottpoff(%ecx), %edx
+# ifdef NO_TLS_DIRECT_SEG_REFS
+	movl	errno@gotntpoff(%ecx), %edx
+	addl	%gs:0, %edx
 	movl	$EAGAIN, (%edx)
+# else
+	movl	errno@gotntpoff(%ecx), %edx
+	movl	$EAGAIN, %gs:(%edx)
+# endif
 #else
 	call	__errno_location@plt
 	movl	$EAGAIN, (%eax)
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 b7674dc3ba..b1296275d0 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -57,12 +57,12 @@ __new_sem_wait:
 	cfi_offset(6, -12)		/* %esi */
 3:	movl	(%ebx), %eax
 2:	testl	%eax, %eax
-	je,pn	1f
+	je	1f
 
 	leal	-1(%eax), %edx
 	LOCK
 	cmpxchgl %edx, (%ebx)
-	jne,pn	2b
+	jne	2b
 	xorl	%eax, %eax
 
 	movl	4(%esp), %esi
@@ -73,7 +73,7 @@ __new_sem_wait:
 	cfi_adjust_cfa_offset(-12)
 	ret
 
-	cfi_adjust_cfa_offset(8)
+	cfi_adjust_cfa_offset(12)
 	cfi_offset(3, -8)		/* %ebx */
 	cfi_offset(6, -12)		/* %esi */
 1:	call	__pthread_enable_asynccancel
@@ -102,9 +102,14 @@ __new_sem_wait:
 #endif
 	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
 #if USE___THREAD
-	movl	%gs:0, %edx
-	subl	errno@gottpoff(%ebx), %edx
+# 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)
diff --git a/nptl/sysdeps/generic/pt-raise.c b/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S
index 59d9590e6e..f768e16a7d 100644
--- a/nptl/sysdeps/generic/pt-raise.c
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -17,14 +17,4 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <pthread.h>
-#include <signal.h>
-
-
-int
-raise (sig)
-     int sig;
-{
-  /* This is what POSIX says must happen.  */
-  return pthread_kill (pthread_self (), sig);
-}
+#include "../i486/lowlevelrobustlock.S"
diff --git a/nptl/sysdeps/sh/jmpbuf-unwind.h b/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S
index cf6d25f041..f768e16a7d 100644
--- a/nptl/sysdeps/sh/jmpbuf-unwind.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S
@@ -1,6 +1,6 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -17,15 +17,4 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <setjmp.h>
-#include <stdint.h>
-#include <unwind.h>
-
-#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
-  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
-
-#define _JMPBUF_UNWINDS_ADJ(jmpbuf, address, adj) \
-  ((uintptr_t) (address) - (adj) < (uintptr_t) (jmpbuf)[0].__regs[7] - (adj))
-
-/* We use the normal lobngjmp for unwinding.  */
-#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
+#include "../i486/lowlevelrobustlock.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
index b86f11c9b4..21de09fe91 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 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.
 
@@ -35,6 +35,9 @@
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
 
 
 /* Initializer for compatibility lock.  */
@@ -65,18 +68,112 @@
 #define BUSY_WAIT_NOP          asm ("rep; nop")
 
 
+#define LLL_STUB_UNWIND_INFO_START \
+	".section	.eh_frame,\"a\",@progbits\n"		\
+"5:\t"	".long	7f-6f	# Length of Common Information Entry\n"	\
+"6:\t"	".long	0x0	# CIE Identifier Tag\n\t"		\
+	".byte	0x1	# CIE Version\n\t"			\
+	".ascii \"zR\\0\"	# CIE Augmentation\n\t"		\
+	".uleb128 0x1	# CIE Code Alignment Factor\n\t"	\
+	".sleb128 -4	# CIE Data Alignment Factor\n\t"	\
+	".byte	0x8	# CIE RA Column\n\t"			\
+	".uleb128 0x1	# Augmentation size\n\t"		\
+	".byte	0x1b	# FDE Encoding (pcrel sdata4)\n\t"	\
+	".byte	0xc	# DW_CFA_def_cfa\n\t"			\
+	".uleb128 0x4\n\t"					\
+	".uleb128 0x0\n\t"					\
+	".align 4\n"						\
+"7:\t"	".long	17f-8f	# FDE Length\n"				\
+"8:\t"	".long	8b-5b	# FDE CIE offset\n\t"			\
+	".long	1b-.	# FDE initial location\n\t"		\
+	".long	4b-1b	# FDE address range\n\t"		\
+	".uleb128 0x0	# Augmentation size\n\t"		\
+	".byte	0x16	# DW_CFA_val_expression\n\t"		\
+	".uleb128 0x8\n\t"					\
+	".uleb128 10f-9f\n"					\
+"9:\t"	".byte	0x78	# DW_OP_breg8\n\t"			\
+	".sleb128 3b-1b\n"
+#define LLL_STUB_UNWIND_INFO_END \
+	".byte	0x16	# DW_CFA_val_expression\n\t"		\
+	".uleb128 0x8\n\t"					\
+	".uleb128 12f-11f\n"					\
+"11:\t"	".byte	0x78	# DW_OP_breg8\n\t"			\
+	".sleb128 3b-2b\n"					\
+"12:\t"	".byte	0x40 + (3b-2b-1) # DW_CFA_advance_loc\n\t"	\
+	".byte	0x16	# DW_CFA_val_expression\n\t"		\
+	".uleb128 0x8\n\t"					\
+	".uleb128 16f-13f\n"					\
+"13:\t"	".byte	0x78	# DW_OP_breg8\n\t"			\
+	".sleb128 15f-14f\n\t"					\
+	".byte	0x0d	# DW_OP_const4s\n"			\
+"14:\t"	".4byte	3b-.\n\t"					\
+	".byte	0x1c	# DW_OP_minus\n\t"			\
+	".byte	0x0d	# DW_OP_const4s\n"			\
+"15:\t"	".4byte	18f-.\n\t"					\
+	".byte	0x22	# DW_OP_plus\n"				\
+"16:\t"	".align 4\n"						\
+"17:\t"	".previous\n"
+
+/* Unwind info for
+   1: lea ..., ...
+   2: call ...
+   3: jmp 18f
+   4:
+   snippet.  */
+#define LLL_STUB_UNWIND_INFO_3 \
+LLL_STUB_UNWIND_INFO_START					\
+"10:\t"	".byte	0x40 + (2b-1b) # DW_CFA_advance_loc\n\t"	\
+LLL_STUB_UNWIND_INFO_END
+
+/* Unwind info for
+   1: lea ..., ...
+   0: movl ..., ...
+   2: call ...
+   3: jmp 18f
+   4:
+   snippet.  */
+#define LLL_STUB_UNWIND_INFO_4 \
+LLL_STUB_UNWIND_INFO_START					\
+"10:\t"	".byte	0x40 + (0b-1b) # DW_CFA_advance_loc\n\t"	\
+	".byte	0x16	# DW_CFA_val_expression\n\t"		\
+	".uleb128 0x8\n\t"					\
+	".uleb128 20f-19f\n"					\
+"19:\t"	".byte	0x78	# DW_OP_breg8\n\t"			\
+	".sleb128 3b-0b\n"					\
+"20:\t"	".byte	0x40 + (2b-0b) # DW_CFA_advance_loc\n\t"	\
+LLL_STUB_UNWIND_INFO_END
+
+
 #define lll_futex_wait(futex, val) \
-  do {									      \
-    int __ignore;							      \
+  ({									      \
+    int __status;							      \
     register __typeof (val) _val asm ("edx") = (val);			      \
     __asm __volatile (LLL_EBX_LOAD					      \
 		      LLL_ENTER_KERNEL					      \
 		      LLL_EBX_LOAD					      \
-		      : "=a" (__ignore)					      \
+		      : "=a" (__status)					      \
 		      : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (0),	      \
 			"c" (FUTEX_WAIT), "d" (_val),			      \
-			"i" (offsetof (tcbhead_t, sysinfo)));		      \
-  } while (0)
+			"i" (offsetof (tcbhead_t, sysinfo))		      \
+		      : "memory");					      \
+    __status;								      \
+  })
+
+
+#define lll_futex_timed_wait(futex, val, timeout)			      \
+  ({									      \
+    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" (timeout),  \
+			"c" (FUTEX_WAIT), "d" (_val),			      \
+			"i" (offsetof (tcbhead_t, sysinfo))		      \
+		      : "memory");					      \
+    __status;								      \
+  })
 
 
 #define lll_futex_wake(futex, nr) \
@@ -121,6 +218,16 @@ extern int __lll_mutex_unlock_wake (int *__futex)
      ret; })
 
 
+#define lll_robust_mutex_trylock(futex, id) \
+  ({ int ret;								      \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1"			      \
+		       : "=a" (ret), "=m" (futex)			      \
+		       : "r" (id), "m" (futex),				      \
+			 "0" (LLL_MUTEX_LOCK_INITIALIZER)		      \
+		       : "memory");					      \
+     ret; })
+
+
 #define lll_mutex_cond_trylock(futex) \
   ({ int ret;								      \
      __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1"			      \
@@ -137,18 +244,39 @@ extern int __lll_mutex_unlock_wake (int *__futex)
 			      "jnz _L_mutex_lock_%=\n\t"		      \
 			      ".subsection 1\n\t"			      \
 			      ".type _L_mutex_lock_%=,@function\n"	      \
-			      "_L_mutex_lock_%=:\n\t"			      \
-			      "leal %2, %%ecx\n\t"			      \
-			      "call __lll_mutex_lock_wait\n\t"		      \
-			      "jmp 1f\n\t"				      \
-			      ".size _L_mutex_lock_%=,.-_L_mutex_lock_%=\n"   \
+			      "_L_mutex_lock_%=:\n"			      \
+			      "1:\tleal %2, %%ecx\n"			      \
+			      "2:\tcall __lll_mutex_lock_wait\n"	      \
+			      "3:\tjmp 18f\n"				      \
+			      "4:\t.size _L_mutex_lock_%=, 4b-1b\n\t"	      \
 			      ".previous\n"				      \
-			      "1:"					      \
+			      LLL_STUB_UNWIND_INFO_3			      \
+			      "18:"					      \
 			      : "=a" (ignore1), "=c" (ignore2), "=m" (futex)  \
 			      : "0" (0), "1" (1), "m" (futex)		      \
 			      : "memory"); })
 
 
+#define lll_robust_mutex_lock(futex, id) \
+  ({ int result, ignore;						      \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %1, %2\n\t"			      \
+		       "jnz _L_robust_mutex_lock_%=\n\t"		      \
+		       ".subsection 1\n\t"				      \
+		       ".type _L_robust_mutex_lock_%=,@function\n"	      \
+		       "_L_robust_mutex_lock_%=:\n"			      \
+		       "1:\tleal %2, %%ecx\n"				      \
+		       "2:\tcall __lll_robust_mutex_lock_wait\n"	      \
+		       "3:\tjmp 18f\n"					      \
+		       "4:\t.size _L_robust_mutex_lock_%=, 4b-1b\n\t"	      \
+		       ".previous\n"					      \
+		       LLL_STUB_UNWIND_INFO_3				      \
+		       "18:"						      \
+		       : "=a" (result), "=c" (ignore), "=m" (futex)	      \
+		       : "0" (0), "1" (id), "m" (futex)			      \
+		       : "memory");					      \
+     result; })
+
+
 /* Special version of lll_mutex_lock which causes the unlock function to
    always wakeup waiters.  */
 #define lll_mutex_cond_lock(futex) \
@@ -157,32 +285,54 @@ extern int __lll_mutex_unlock_wake (int *__futex)
 			      "jnz _L_mutex_cond_lock_%=\n\t"		      \
 			      ".subsection 1\n\t"			      \
 			      ".type _L_mutex_cond_lock_%=,@function\n"	      \
-			      "_L_mutex_cond_lock_%=:\n\t"		      \
-			      "leal %2, %%ecx\n\t"			      \
-			      "call __lll_mutex_lock_wait\n\t"		      \
-			      "jmp 1f\n\t"				      \
-			      ".size _L_mutex_cond_lock_%=,.-_L_mutex_cond_lock_%=\n"   \
+			      "_L_mutex_cond_lock_%=:\n"		      \
+			      "1:\tleal %2, %%ecx\n"			      \
+			      "2:\tcall __lll_mutex_lock_wait\n"	      \
+			      "3:\tjmp 18f\n"				      \
+			      "4:\t.size _L_mutex_cond_lock_%=, 4b-1b\n\t"    \
 			      ".previous\n"				      \
-			      "1:"					      \
+			      LLL_STUB_UNWIND_INFO_3			      \
+			      "18:"					      \
 			      : "=a" (ignore1), "=c" (ignore2), "=m" (futex)  \
 			      : "0" (0), "1" (2), "m" (futex)		      \
 			      : "memory"); })
 
 
+#define lll_robust_mutex_cond_lock(futex, id) \
+  ({ int result, ignore;						      \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %1, %2\n\t"			      \
+		       "jnz _L_robust_mutex_cond_lock_%=\n\t"		      \
+		       ".subsection 1\n\t"				      \
+		       ".type _L_robust_mutex_cond_lock_%=,@function\n"	      \
+		       "_L_robust_mutex_cond_lock_%=:\n"		      \
+		       "1:\tleal %2, %%ecx\n"				      \
+		       "2:\tcall __lll_robust_mutex_lock_wait\n"	      \
+		       "3:\tjmp 18f\n"					      \
+		       "4:\t.size _L_robust_mutex_cond_lock_%=, 4b-1b\n\t"    \
+		       ".previous\n"					      \
+		       LLL_STUB_UNWIND_INFO_3				      \
+		       "18:"						      \
+		       : "=a" (result), "=c" (ignore), "=m" (futex)	      \
+		       : "0" (0), "1" (id | FUTEX_WAITERS), "m" (futex)	      \
+		       : "memory");					      \
+     result; })
+
+
 #define lll_mutex_timedlock(futex, timeout) \
   ({ int result, ignore1, ignore2;					      \
      __asm __volatile (LOCK_INSTR "cmpxchgl %1, %3\n\t"			      \
 		       "jnz _L_mutex_timedlock_%=\n\t"			      \
 		       ".subsection 1\n\t"				      \
 		       ".type _L_mutex_timedlock_%=,@function\n"	      \
-		       "_L_mutex_timedlock_%=:\n\t"			      \
-		       "leal %3, %%ecx\n\t"				      \
-		       "movl %7, %%edx\n\t"				      \
-		       "call __lll_mutex_timedlock_wait\n\t"		      \
-		       "jmp 1f\n\t"					      \
-		       ".size _L_mutex_timedlock_%=,.-_L_mutex_timedlock_%=\n"\
+		       "_L_mutex_timedlock_%=:\n"			      \
+		       "1:\tleal %3, %%ecx\n"				      \
+		       "0:\tmovl %7, %%edx\n"				      \
+		       "2:\tcall __lll_mutex_timedlock_wait\n"		      \
+		       "3:\tjmp 18f\n"					      \
+		       "4:\t.size _L_mutex_timedlock_%=, 4b-1b\n\t"	      \
 		       ".previous\n"					      \
-		       "1:"						      \
+		       LLL_STUB_UNWIND_INFO_4				      \
+		       "18:"						      \
 		       : "=a" (result), "=c" (ignore1), "=&d" (ignore2),      \
 			 "=m" (futex)					      \
 		       : "0" (0), "1" (1), "m" (futex), "m" (timeout)	      \
@@ -190,24 +340,95 @@ extern int __lll_mutex_unlock_wake (int *__futex)
      result; })
 
 
+#define lll_robust_mutex_timedlock(futex, timeout, id) \
+  ({ int result, ignore1, ignore2;					      \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %1, %3\n\t"			      \
+		       "jnz _L_robust_mutex_timedlock_%=\n\t"		      \
+		       ".subsection 1\n\t"				      \
+		       ".type _L_robust_mutex_timedlock_%=,@function\n"	      \
+		       "_L_robust_mutex_timedlock_%=:\n"		      \
+		       "1:\tleal %3, %%ecx\n"				      \
+		       "0:\tmovl %7, %%edx\n"				      \
+		       "2:\tcall __lll_robust_mutex_timedlock_wait\n"	      \
+		       "3:\tjmp 18f\n"					      \
+		       "4:\t.size _L_robust_mutex_timedlock_%=, 4b-1b\n\t"    \
+		       ".previous\n"					      \
+		       LLL_STUB_UNWIND_INFO_4				      \
+		       "18:"						      \
+		       : "=a" (result), "=c" (ignore1), "=&d" (ignore2),      \
+			 "=m" (futex)					      \
+		       : "0" (0), "1" (id), "m" (futex), "m" (timeout)	      \
+		       : "memory");					      \
+     result; })
+
+
 #define lll_mutex_unlock(futex) \
   (void) ({ int ignore;							      \
-            __asm __volatile (LOCK_INSTR "subl $1,%0\n\t"		      \
+            __asm __volatile (LOCK_INSTR "subl $1, %0\n\t"		      \
 			      "jne _L_mutex_unlock_%=\n\t"		      \
 			      ".subsection 1\n\t"			      \
 			      ".type _L_mutex_unlock_%=,@function\n"	      \
-			      "_L_mutex_unlock_%=:\n\t"			      \
-			      "leal %0, %%eax\n\t"			      \
-			      "call __lll_mutex_unlock_wake\n\t"	      \
-			      "jmp 1f\n\t"				      \
-			      ".size _L_mutex_unlock_%=,.-_L_mutex_unlock_%=\n" \
+			      "_L_mutex_unlock_%=:\n"			      \
+			      "1:\tleal %0, %%eax\n"			      \
+			      "2:\tcall __lll_mutex_unlock_wake\n"	      \
+			      "3:\tjmp 18f\n"				      \
+			      "4:\t.size _L_mutex_unlock_%=, 4b-1b\n\t"	      \
 			      ".previous\n"				      \
-			      "1:"					      \
+			      LLL_STUB_UNWIND_INFO_3			      \
+			      "18:"					      \
 			      : "=m" (futex), "=&a" (ignore)		      \
 			      : "m" (futex)				      \
 			      : "memory"); })
 
 
+#define lll_robust_mutex_unlock(futex) \
+  (void) ({ int ignore;							      \
+            __asm __volatile (LOCK_INSTR "andl %2, %0\n\t"		      \
+			      "jne _L_robust_mutex_unlock_%=\n\t"	      \
+			      ".subsection 1\n\t"			      \
+			      ".type _L_robust_mutex_unlock_%=,@function\n"   \
+			      "_L_robust_mutex_unlock_%=:\n\t"		      \
+			      "1:\tleal %0, %%eax\n"			      \
+			      "2:\tcall __lll_mutex_unlock_wake\n"	      \
+			      "3:\tjmp 18f\n"				      \
+			      "4:\t.size _L_robust_mutex_unlock_%=, 4b-1b\n\t"\
+			      ".previous\n"				      \
+			      LLL_STUB_UNWIND_INFO_3			      \
+			      "18:"					      \
+			      : "=m" (futex), "=&a" (ignore)		      \
+			      : "i" (FUTEX_WAITERS), "m" (futex)	      \
+			      : "memory"); })
+
+
+#define lll_robust_mutex_dead(futex) \
+  (void) ({ int __ignore;						      \
+	    register int _nr asm ("edx") = 1;				      \
+	    __asm __volatile (LOCK_INSTR "orl %5, (%2)\n\t"		      \
+			      LLL_EBX_LOAD				      \
+			      LLL_ENTER_KERNEL				      \
+			      LLL_EBX_LOAD				      \
+			      : "=a" (__ignore)				      \
+			      : "0" (SYS_futex), LLL_EBX_REG (&(futex)),      \
+				"c" (FUTEX_WAKE), "d" (_nr),		      \
+				"i" (FUTEX_OWNER_DIED),			      \
+				"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)
 
@@ -250,7 +471,7 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
 # define lll_trylock(futex) \
   ({ unsigned char ret;							      \
      __asm __volatile ("cmpl $0, %%gs:%P5\n\t"				      \
-		       "je,pt 0f\n\t"					      \
+		       "je 0f\n\t"					      \
 		       "lock\n"						      \
 		       "0:\tcmpxchgl %2, %1; setne %0"			      \
 		       : "=a" (ret), "=m" (futex)			      \
@@ -264,19 +485,20 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
 # define lll_lock(futex) \
   (void) ({ int ignore1, ignore2;					      \
 	    __asm __volatile ("cmpl $0, %%gs:%P6\n\t"			      \
-			      "je,pt 0f\n\t"				      \
+			      "je 0f\n\t"				      \
 			      "lock\n"					      \
 			      "0:\tcmpxchgl %1, %2\n\t"			      \
-			      "jnz _L_mutex_lock_%=\n\t"		      \
+			      "jnz _L_lock_%=\n\t"			      \
 			      ".subsection 1\n\t"			      \
-			      ".type _L_mutex_lock_%=,@function\n"	      \
-			      "_L_mutex_lock_%=:\n\t"			      \
-			      "leal %2, %%ecx\n\t"			      \
-			      "call __lll_mutex_lock_wait\n\t"		      \
-			      "jmp 1f\n\t"				      \
-			      ".size _L_mutex_lock_%=,.-_L_mutex_lock_%=\n"   \
+			      ".type _L_lock_%=,@function\n"		      \
+			      "_L_lock_%=:\n"				      \
+			      "1:\tleal %2, %%ecx\n"			      \
+			      "2:\tcall __lll_mutex_lock_wait\n"	      \
+			      "3:\tjmp 18f\n"				      \
+			      "4:\t.size _L_lock_%=, 4b-1b\n\t"		      \
 			      ".previous\n"				      \
-			      "1:"					      \
+			      LLL_STUB_UNWIND_INFO_3			      \
+			      "18:"					      \
 			      : "=a" (ignore1), "=c" (ignore2), "=m" (futex)  \
 			      : "0" (0), "1" (1), "m" (futex),		      \
 		                "i" (offsetof (tcbhead_t, multiple_threads))  \
@@ -286,19 +508,20 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
 # define lll_unlock(futex) \
   (void) ({ int ignore;							      \
             __asm __volatile ("cmpl $0, %%gs:%P3\n\t"			      \
-			      "je,pt 0f\n\t"				      \
+			      "je 0f\n\t"				      \
 			      "lock\n"					      \
-			      "0:\tsubl $1,%0\n\t"		      \
-			      "jne _L_mutex_unlock_%=\n\t"		      \
+			      "0:\tsubl $1,%0\n\t"			      \
+			      "jne _L_unlock_%=\n\t"			      \
 			      ".subsection 1\n\t"			      \
-			      ".type _L_mutex_unlock_%=,@function\n"	      \
-			      "_L_mutex_unlock_%=:\n\t"			      \
-			      "leal %0, %%eax\n\t"			      \
-			      "call __lll_mutex_unlock_wake\n\t"	      \
-			      "jmp 1f\n\t"				      \
-			      ".size _L_mutex_unlock_%=,.-_L_mutex_unlock_%=\n" \
+			      ".type _L_unlock_%=,@function\n"		      \
+			      "_L_unlock_%=:\n"				      \
+			      "1:\tleal %0, %%eax\n"			      \
+			      "2:\tcall __lll_mutex_unlock_wake\n"	      \
+			      "3:\tjmp 18f\n\t"				      \
+			      "4:\t.size _L_unlock_%=, 4b-1b\n\t"	      \
 			      ".previous\n"				      \
-			      "1:"					      \
+			      LLL_STUB_UNWIND_INFO_3			      \
+			      "18:"					      \
 			      : "=m" (futex), "=&a" (ignore)		      \
 			      : "m" (futex),				      \
 				"i" (offsetof (tcbhead_t, multiple_threads))  \
@@ -325,12 +548,13 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
 			"1:\tmovl %1, %%eax\n\t"			      \
 			LLL_ENTER_KERNEL				      \
 			"cmpl $0, (%%ebx)\n\t"				      \
-			"jne,pn 1b\n\t"					      \
+			"jne 1b\n\t"					      \
 			LLL_EBX_LOAD					      \
 			: "=&a" (__ignore)				      \
 			: "i" (SYS_futex), LLL_EBX_REG (&tid), "S" (0),	      \
 			  "c" (FUTEX_WAIT), "d" (_tid),			      \
-			  "i" (offsetof (tcbhead_t, sysinfo)));		      \
+			  "i" (offsetof (tcbhead_t, sysinfo))		      \
+			: "memory");					      \
   } while (0)
 
 extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h b/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h
index cc3282fbdd..6557359b43 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h
@@ -1,5 +1,5 @@
 /* Uncancelable versions of cancelable interfaces.  Linux/NPTL version.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -26,13 +26,21 @@ extern int __close_nocancel (int) attribute_hidden;
 extern int __read_nocancel (int, void *, size_t) attribute_hidden;
 extern int __write_nocancel (int, const void *, size_t) attribute_hidden;
 extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden;
+extern int __openat_nocancel (int fd, const char *fname, int oflag,
+				mode_t mode) attribute_hidden;
+extern int __openat64_nocancel (int fd, const char *fname, int oflag,
+				  mode_t mode) attribute_hidden;
 #else
-#define __open_nocancel(name, ...) __open (name, __VA_ARGS__)
-#define __close_nocancel(fd) __close (fd)
-#define __read_nocancel(fd, buf, len) __read (fd, buf, len)
-#define __write_nocancel(fd, buf, len) __write (fd, buf, len)
-#define __waitpid_nocancel(pid, stat_loc, options) \
+# define __open_nocancel(name, ...) __open (name, __VA_ARGS__)
+# define __close_nocancel(fd) __close (fd)
+# define __read_nocancel(fd, buf, len) __read (fd, buf, len)
+# define __write_nocancel(fd, buf, len) __write (fd, buf, len)
+# define __waitpid_nocancel(pid, stat_loc, options) \
   __waitpid (pid, stat_loc, options)
+# define __openat_nocancel(fd, fname, oflag, mode) \
+  openat (fd, fname, oflag, mode)
+# define __openat64_nocancel(fd, fname, oflag, mode) \
+  openat64 (fd, fname, oflag, mode)
 #endif
 
 /* Uncancelable open.  */
@@ -41,6 +49,16 @@ extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden;
 #define open_not_cancel_2(name, flags) \
    __open_nocancel (name, flags)
 
+/* Uncancelable openat.  */
+#define openat_not_cancel(fd, fname, oflag, mode) \
+  __openat_nocancel (fd, fname, oflag, mode)
+#define openat_not_cancel_3(fd, fname, oflag) \
+  __openat_nocancel (fd, fname, oflag, 0)
+#define openat64_not_cancel(fd, fname, oflag, mode) \
+  __openat64_nocancel (fd, fname, oflag, mode)
+#define openat64_not_cancel_3(fd, fname, oflag) \
+  __openat64_nocancel (fd, fname, oflag, 0)
+
 /* Uncancelable close.  */
 #define close_not_cancel(fd) \
   __close_nocancel (fd)
@@ -73,3 +91,15 @@ extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden;
 # define waitpid_not_cancel(pid, stat_loc, options) \
   INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL)
 #endif
+
+/* Uncancelable pause.  */
+#define pause_not_cancel() \
+  __pause_nocancel ()
+
+/* Uncancelable nanosleep.  */
+#define nanosleep_not_cancel(requested_time, remaining) \
+  __nanosleep_nocancel (requested_time, remaining)
+
+/* Uncancelable sigsuspend.  */
+#define sigsuspend_not_cancel(set) \
+  __sigsuspend_nocancel (set)
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/smp.h b/nptl/sysdeps/unix/sysv/linux/i386/smp.h
new file mode 100644
index 0000000000..f68a0c0758
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/i386/smp.h
@@ -0,0 +1,56 @@
+/* Determine whether the host has multiple processors.  Linux version.
+   Copyright (C) 1996, 2002, 2004, 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
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <not-cancel.h>
+
+/* Test whether the machine has more than one processor.  This is not the
+   best test but good enough.  More complicated tests would require `malloc'
+   which is not available at that time.  */
+static inline int
+is_smp_system (void)
+{
+  union
+  {
+    struct utsname uts;
+    char buf[512];
+  } u;
+  char *cp;
+
+  /* Try reading the number using `sysctl' first.  */
+  if (uname (&u.uts) == 0)
+    cp = u.uts.version;
+  else
+    {
+      /* This was not successful.  Now try reading the /proc filesystem.  */
+      int fd = open_not_cancel_2 ("/proc/sys/kernel/version", O_RDONLY);
+      if (__builtin_expect (fd, 0) == -1
+	  || read_not_cancel (fd, u.buf, sizeof (u.buf)) <= 0)
+	/* This also didn't work.  We give up and say it's a UP machine.  */
+	u.buf[0] = '\0';
+
+      close_not_cancel_no_status (fd);
+      cp = u.buf;
+    }
+
+  return strstr (cp, "SMP") != NULL;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
index 8142455781..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 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.
 
@@ -29,7 +29,6 @@
 # define PSEUDO(name, syscall_name, args)				      \
   .text;								      \
   ENTRY (name)								      \
-  L(name##START):							      \
     cmpl $0, %gs:MULTIPLE_THREADS_OFFSET;				      \
     jne L(pseudo_cancel);						      \
   .type __##syscall_name##_nocancel,@function;				      \
@@ -51,258 +50,11 @@
     POPSTATE_##args							      \
     cmpl $-4095, %eax;							      \
     jae SYSCALL_ERROR_LABEL;						      \
-  L(pseudo_end):							      \
-									      \
-  /* Create unwinding information for the syscall wrapper.  */		      \
-  .section .eh_frame,"a",@progbits;					      \
-  L(STARTFRAME):							      \
-    /* Length of the CIE.  */						      \
-    .long L(ENDCIE)-L(STARTCIE);					      \
-  L(STARTCIE):								      \
-    /* CIE ID.  */							      \
-    .long 0;								      \
-    /* Version number.  */						      \
-    .byte 1;								      \
-    /* NUL-terminated augmentation string.  */				      \
-    AUGMENTATION_STRING;						      \
-    /* Code alignment factor.  */					      \
-    .uleb128 1;								      \
-    /* Data alignment factor.  */					      \
-    .sleb128 -4;							      \
-    /* Return address register column.  */				      \
-    .byte 8;								      \
-    /* Optional augmentation parameter.  */				      \
-    AUGMENTATION_PARAM							      \
-    /* Start of the table initialization.  */				      \
-    .byte 0xc;			/* DW_CFA_def_cfa */			      \
-    .uleb128 4;								      \
-    .uleb128 4;								      \
-    .byte 0x88;			/* DW_CFA_offset, column 0x8 */		      \
-    .uleb128 1;								      \
-    .align 4;								      \
-  L(ENDCIE):								      \
-    /* Length of the FDE.  */						      \
-    .long L(ENDFDE)-L(STARTFDE);					      \
-  L(STARTFDE):								      \
-    /* CIE pointer.  */							      \
-    .long L(STARTFDE)-L(STARTFRAME);					      \
-    /* Start address of the code.  */					      \
-    START_SYMBOL_REF (name);						      \
-    /* Length of the code.  */						      \
-    .long L(name##END)-L(name##START);					      \
-    /* Augmentation data.  */						      \
-    AUGMENTATION_PARAM_FDE						      \
-    /* The rest of the code depends on the number of parameters the syscall   \
-       takes.  */							      \
-    EH_FRAME_##args(name);						      \
-    .align 4;								      \
-  L(ENDFDE):								      \
-  .previous
-
-# ifdef SHARED
-/* NUL-terminated augmentation string.  Note "z" means there is an
-   augmentation value later on.  */
-#  define AUGMENTATION_STRING .string "zR"
-#  define AUGMENTATION_PARAM \
-    /* Augmentation value length.  */					      \
-    .uleb128 1;								      \
-    /* Encoding: DW_EH_PE_pcrel + DW_EH_PE_sdata4.  */			      \
-    .byte 0x1b;
-#  define AUGMENTATION_PARAM_FDE \
-    /* No augmentation data.  */					      \
-    .uleb128 0;
-#  define START_SYMBOL_REF(name) \
-    /* PC-relative start address of the code.  */			      \
-    .long L(name##START)-.
-# else
-/* No augmentation.  */
-#  define AUGMENTATION_STRING .ascii "\0"
-#  define AUGMENTATION_PARAM /* nothing */
-#  define AUGMENTATION_PARAM_FDE /* nothing */
-#  define START_SYMBOL_REF(name) \
-    /* Absolute start address of the code.  */				      \
-    .long L(name##START)
-# endif
-
-/* Callframe description for syscalls without parameters.  This is very
-   simple.  The only place the stack pointer is changed is when the old
-   cancellation state value is saved.  */
-# define EH_FRAME_0(name) \
-    .byte 0x40+L(PUSHSTATE)-L(name##START);	/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0x40+L(POPSTATE)-L(PUSHSTATE);	/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 4
-
-/* For syscalls with one and two parameters the code is the same as for
-   those which take no parameter.  */
-# define EH_FRAME_1(name) \
-    .byte 0x40+L(SAVEBX1)-L(name##START);	/* DW_CFA_advance_loc+N */    \
-    .byte 9;					/* DW_CFA_register */	      \
-    .uleb128 3;					/* %ebx */		      \
-    .uleb128 2;					/* %edx */		      \
-    .byte 0x40+L(RESTBX1)-L(SAVEBX1);		/* DW_CFA_advance_loc+N */    \
-    .byte 0xc3;					/* DW_CFA_restore %ebx */     \
-    .byte 0x40+L(PUSHSTATE)-L(RESTBX1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0x40+L(SAVEBX2)-L(PUSHSTATE);		/* DW_CFA_advance_loc+N */    \
-    .byte 9;					/* DW_CFA_register */	      \
-    .uleb128 3;					/* %ebx */		      \
-    .uleb128 2;					/* %edx */		      \
-    .byte 0x40+L(RESTBX2)-L(SAVEBX2);		/* DW_CFA_advance_loc+N */    \
-    .byte 0xc3;					/* DW_CFA_restore %ebx */     \
-    .byte 0x40+L(POPSTATE)-L(RESTBX2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 4
-
-# define EH_FRAME_2(name) EH_FRAME_1 (name)
-
-/* For syscalls with three parameters the stack pointer is changed
-   also to save the content of the %ebx register.  */
-# define EH_FRAME_3(name) \
-    .byte 0x40+L(PUSHBX1)-L(name##START);	/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0x83;					/* DW_CFA_offset %ebx */      \
-    .uleb128 2;								      \
-    .byte 0x40+L(POPBX1)-L(PUSHBX1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 4;								      \
-    .byte 0xc3;					/* DW_CFA_restore %ebx */     \
-    .byte 0x40+L(PUSHSTATE)-L(POPBX1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0x40+L(PUSHBX2)-L(PUSHSTATE);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 12;							      \
-    .byte 0x83;					/* DW_CFA_offset %ebx */      \
-    .uleb128 3;								      \
-    .byte 0x40+L(POPBX2)-L(PUSHBX2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0xc3;					/* DW_CFA_restore %ebx */     \
-    .byte 0x40+L(POPSTATE)-L(POPBX2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 4
-
-/* With four parameters the syscall wrappers have to save %ebx and %esi.  */
-# define EH_FRAME_4(name) \
-    .byte 0x40+L(PUSHSI1)-L(name##START);	/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0x86;					/* DW_CFA_offset %esi */      \
-    .uleb128 2;								      \
-    .byte 0x40+L(PUSHBX1)-L(PUSHSI1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 12;							      \
-    .byte 0x83;					/* DW_CFA_offset %ebx */      \
-    .uleb128 3;								      \
-    .byte 0x40+L(POPBX1)-L(PUSHBX1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0xc3;					/* DW_CFA_restore %ebx */     \
-    .byte 0x40+L(POPSI1)-L(POPBX1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 4;								      \
-    .byte 0xc6;					/* DW_CFA_restore %esi */     \
-    .byte 0x40+L(PUSHSTATE)-L(POPSI1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0x40+L(PUSHSI2)-L(PUSHSTATE);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 12;							      \
-    .byte 0x86;					/* DW_CFA_offset %esi */      \
-    .uleb128 3;								      \
-    .byte 0x40+L(PUSHBX2)-L(PUSHSI2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 16;							      \
-    .byte 0x83;					/* DW_CFA_offset %ebx */      \
-    .uleb128 4;								      \
-    .byte 0x40+L(POPBX2)-L(PUSHBX2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 12;							      \
-    .byte 0xc3;					/* DW_CFA_restore %ebx */     \
-    .byte 0x40+L(POPSI2)-L(POPBX2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0xc6;					/* DW_CFA_restore %esi */     \
-    .byte 0x40+L(POPSTATE)-L(POPSI2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 4
-
-/* With five parameters the syscall wrappers have to save %ebx, %esi,
-   and %edi.  */
-# define EH_FRAME_5(name) \
-    .byte 0x40+L(PUSHDI1)-L(name##START);	/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0x87;					/* DW_CFA_offset %edi */      \
-    .uleb128 2;								      \
-    .byte 0x40+L(PUSHSI1)-L(PUSHDI1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 12;							      \
-    .byte 0x86;					/* DW_CFA_offset %esi */      \
-    .uleb128 3;								      \
-    .byte 0x40+L(PUSHBX1)-L(PUSHSI1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 16;							      \
-    .byte 0x83;					/* DW_CFA_offset %ebx */      \
-    .uleb128 4;								      \
-    .byte 0x40+L(POPBX1)-L(PUSHBX1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 12;							      \
-    .byte 0xc3;					/* DW_CFA_restore %ebx */     \
-    .byte 0x40+L(POPSI1)-L(POPBX1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0xc6;					/* DW_CFA_restore %esi */     \
-    .byte 0x40+L(POPDI1)-L(POPSI1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 4;								      \
-    .byte 0xc7;					/* DW_CFA_restore %edi */     \
-    .byte 0x40+L(PUSHSTATE)-L(POPDI1);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0x40+L(PUSHDI2)-L(PUSHSTATE);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 12;							      \
-    .byte 0x87;					/* DW_CFA_offset %edi */      \
-    .uleb128 3;								      \
-    .byte 0x40+L(PUSHSI2)-L(PUSHDI2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 16;							      \
-    .byte 0x86;					/* DW_CFA_offset %esi */      \
-    .uleb128 4;								      \
-    .byte 0x40+L(PUSHBX2)-L(PUSHSI2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 20;							      \
-    .byte 0x83;					/* DW_CFA_offset %ebx */      \
-    .uleb128 5;								      \
-    .byte 0x40+L(POPBX2)-L(PUSHBX2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 16;							      \
-    .byte 0xc3;					/* DW_CFA_restore %ebx */     \
-    .byte 0x40+L(POPSI2)-L(POPBX2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 12;							      \
-    .byte 0xc6;					/* DW_CFA_restore %esi */     \
-    .byte 0x40+L(POPDI2)-L(POPSI2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 8;								      \
-    .byte 0xc7;					/* DW_CFA_restore %edi */     \
-    .byte 0x40+L(POPSTATE)-L(POPDI2);		/* DW_CFA_advance_loc+N */    \
-    .byte 14;					/* DW_CFA_def_cfa_offset */   \
-    .uleb128 4
-
-
-# undef ASM_SIZE_DIRECTIVE
-# define ASM_SIZE_DIRECTIVE(name) L(name##END): .size name,.-name;
+  L(pseudo_end):
 
 # define SAVE_OLDTYPE_0	movl %eax, %ecx;
 # define SAVE_OLDTYPE_1	SAVE_OLDTYPE_0
-# define SAVE_OLDTYPE_2	pushl %eax; L(PUSHSTATE):
+# define SAVE_OLDTYPE_2	pushl %eax; cfi_adjust_cfa_offset (4);
 # define SAVE_OLDTYPE_3	SAVE_OLDTYPE_2
 # define SAVE_OLDTYPE_4	SAVE_OLDTYPE_2
 # define SAVE_OLDTYPE_5	SAVE_OLDTYPE_2
@@ -313,11 +65,13 @@
 # define _PUSHCARGS_0	/* No arguments to push.  */
 # define _POPCARGS_0	/* No arguments to pop.  */
 
-# define PUSHCARGS_1	movl %ebx, %edx; L(SAVEBX2): PUSHCARGS_0
+# define PUSHCARGS_1	movl %ebx, %edx; cfi_register (ebx, edx); PUSHCARGS_0
 # define DOCARGS_1	_DOARGS_1 (4)
-# define POPCARGS_1	POPCARGS_0; movl %edx, %ebx; L(RESTBX2):
-# define _PUSHCARGS_1	pushl %ebx; L(PUSHBX2): _PUSHCARGS_0
-# define _POPCARGS_1	_POPCARGS_0; popl %ebx; L(POPBX2):
+# define POPCARGS_1	POPCARGS_0; movl %edx, %ebx; cfi_restore (ebx);
+# define _PUSHCARGS_1	pushl %ebx; cfi_adjust_cfa_offset (4); \
+			cfi_rel_offset (ebx, 0); _PUSHCARGS_0
+# define _POPCARGS_1	_POPCARGS_0; popl %ebx; \
+			cfi_adjust_cfa_offset (-4); cfi_restore (ebx);
 
 # define PUSHCARGS_2	PUSHCARGS_1
 # define DOCARGS_2	_DOARGS_2 (12)
@@ -334,14 +88,18 @@
 # define PUSHCARGS_4	_PUSHCARGS_4
 # define DOCARGS_4	_DOARGS_4 (28)
 # define POPCARGS_4	_POPCARGS_4
-# define _PUSHCARGS_4	pushl %esi; L(PUSHSI2): _PUSHCARGS_3
-# define _POPCARGS_4	_POPCARGS_3; popl %esi; L(POPSI2):
+# define _PUSHCARGS_4	pushl %esi; cfi_adjust_cfa_offset (4); \
+			cfi_rel_offset (esi, 0); _PUSHCARGS_3
+# define _POPCARGS_4	_POPCARGS_3; popl %esi; \
+			cfi_adjust_cfa_offset (-4); cfi_restore (esi);
 
 # define PUSHCARGS_5	_PUSHCARGS_5
 # define DOCARGS_5	_DOARGS_5 (36)
 # define POPCARGS_5	_POPCARGS_5
-# define _PUSHCARGS_5	pushl %edi; L(PUSHDI2): _PUSHCARGS_4
-# define _POPCARGS_5	_POPCARGS_4; popl %edi; L(POPDI2):
+# define _PUSHCARGS_5	pushl %edi; cfi_adjust_cfa_offset (4); \
+			cfi_rel_offset (edi, 0); _PUSHCARGS_4
+# define _POPCARGS_5	_POPCARGS_4; popl %edi; \
+			cfi_adjust_cfa_offset (-4); cfi_restore (edi);
 
 # ifdef IS_IN_libpthread
 #  define CENABLE	call __pthread_enable_asynccancel;
@@ -356,9 +114,11 @@
 #  error Unsupported library
 # endif
 # define POPSTATE_0 \
- pushl %eax; L(PUSHSTATE): movl %ecx, %eax; CDISABLE; popl %eax; L(POPSTATE):
+ pushl %eax; cfi_adjust_cfa_offset (4); movl %ecx, %eax; \
+ CDISABLE; popl %eax; cfi_adjust_cfa_offset (-4);
 # define POPSTATE_1	POPSTATE_0
-# define POPSTATE_2	xchgl (%esp), %eax; CDISABLE; popl %eax; L(POPSTATE):
+# define POPSTATE_2	xchgl (%esp), %eax; CDISABLE; popl %eax; \
+			cfi_adjust_cfa_offset (-4);
 # define POPSTATE_3	POPSTATE_2
 # define POPSTATE_4	POPSTATE_3
 # define POPSTATE_5	POPSTATE_4
@@ -377,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/i386/vfork.S b/nptl/sysdeps/unix/sysv/linux/i386/vfork.S
index 52336102c7..37f0842051 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/vfork.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/vfork.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1999,2002,2004,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
@@ -16,10 +16,17 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <tcb-offsets.h>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <vfork.S>
+#else
+
+# include <tcb-offsets.h>
 
 /* Save the PID value.  */
-#define SAVE_PID \
+# define SAVE_PID \
 	movl	%gs:PID, %edx; 						      \
 	movl	%edx, %eax;						      \
 	negl	%eax;							      \
@@ -28,11 +35,11 @@
 1:	movl	%eax, %gs:PID
 
 /* Restore the old PID value in the parent.  */
-#define RESTORE_PID \
+# define RESTORE_PID \
 	testl	%eax, %eax;						      \
 	je	1f;							      \
 	movl	%edx, %gs:PID;						      \
 1:
 
-
-#include <sysdeps/unix/sysv/linux/i386/vfork.S>
+# include_next <vfork.S>
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/__ia64_longjmp.S b/nptl/sysdeps/unix/sysv/linux/ia64/__ia64_longjmp.S
index 1ceb210c2f..a1120d4d72 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/__ia64_longjmp.S
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/__ia64_longjmp.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -102,6 +102,9 @@ LEAF(__ia64_longjmp)
 	;;
 	ld8.nta r20=[r2],16		// b4
 	ld8.nta r21=[r3],16		// b5
+#ifdef PTR_DEMANGLE
+	PTR_DEMANGLE (r16, r24)
+#endif
 	;;
 	ld8.nta r11=[r2],16		// ar.pfs
 	ld8.nta r22=[r3],56		// ar.lc
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
index afb8800ac9..892769dca4 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -43,11 +43,18 @@ typedef union
 } pthread_attr_t;
 
 
+typedef struct __pthread_internal_list
+{
+  struct __pthread_internal_list *__prev;
+  struct __pthread_internal_list *__next;
+} __pthread_list_t;
+
+
 /* Data structures for mutex handling.  The structure of the attribute
    type is not exposed on purpose.  */
 typedef union
 {
-  struct
+  struct __pthread_mutex_s
   {
     int __lock;
     unsigned int __count;
@@ -57,6 +64,8 @@ typedef union
        binary compatibility.  */
     int __kind;
     int __spins;
+    __pthread_list_t __list;
+#define __PTHREAD_MUTEX_HAVE_PREV	1
   } __data;
   char __size[__SIZEOF_PTHREAD_MUTEX_T];
   long int __align;
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/clone2.S b/nptl/sysdeps/unix/sysv/linux/ia64/clone2.S
index 8664056f27..91f28bab37 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/clone2.S
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/clone2.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/ia64/clone2.S>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone2.S>
+#else
+# define RESET_PID
+# include_next <clone2.S>
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/createthread.c b/nptl/sysdeps/unix/sysv/linux/ia64/createthread.c
index 8ac06e8101..cd5f8137d5 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/createthread.c
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/createthread.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>.
 
@@ -18,7 +18,7 @@
    02111-1307 USA.  */
 
 /* Value passed to 'clone' for initialization of the thread register.  */
-#define TLS_VALUE (pd + 1)
+#define TLS_VALUE ((char *) pd + TLS_PRE_TCB_SIZE)
 
 #define ARCH_CLONE __clone2
 
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h b/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
index af835c44b1..525b622a68 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
@@ -1,5 +1,5 @@
 /* System-specific settings for dynamic linker code.  IA-64 version.
-   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.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -57,7 +57,7 @@ extern int _dl_sysinfo_break attribute_hidden;
        ".body\n\t"				\
        "break 0x100000;\n\t"			\
        "br.ret.sptk.many b6;\n\t"		\
-       ".endp _dl_sysinfo_break"		\
+       ".endp _dl_sysinfo_break\n\t"		\
        ".previous");
 #endif
 
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h b/nptl/sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h
deleted file mode 100644
index c6ef5f7fbd..0000000000
--- a/nptl/sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <setjmp.h>
-#include <stdint.h>
-#include <unwind.h>
-
-#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
-  ({ uintptr_t _cfa = (uintptr_t) _Unwind_GetCFA (_context) - (_adj);	\
-     (_cfa < (uintptr_t)(((long *)(_jmpbuf))[0]) - (_adj)		\
-      || (_cfa == (uintptr_t)(((long *)(_jmpbuf))[0]) - (_adj)		\
-	  && (uintptr_t) _Unwind_GetBSP (_context) - (_adj)		\
-	     >= (uintptr_t)(((long *)(_jmpbuf))[17]) - (_adj)));	\
-  })
-
-#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
-  ((uintptr_t)(_address) - (_adj) < (uintptr_t)(((long *)_jmpbuf)[0]) - (_adj))
-
-/* We use a longjmp() which can cross from the alternate signal-stack
-   to the normal stack.  */
-extern void __libc_unwind_longjmp (sigjmp_buf env, int val)
-          __attribute__ ((noreturn));
-hidden_proto (__libc_unwind_longjmp)
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
index e13358ffef..8df997a262 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 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.
 
@@ -31,6 +31,11 @@
 #define FUTEX_WAKE		1
 #define FUTEX_REQUEUE		3
 #define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
 
 /* Delay in spinlock loop.  */
 #define BUSY_WAIT_NOP          asm ("hint @pause")
@@ -53,6 +58,15 @@
    _r10 == -1 ? -_retval : _retval;					\
 })
 
+#define lll_robust_mutex_dead(futexv)					\
+do									\
+  {									\
+    int *__futexp = &(futexv);						\
+    atomic_or (__futexp, FUTEX_OWNER_DIED);				\
+    DO_INLINE_SYSCALL(futex, 3, (long) __futexp, FUTEX_WAKE, 1);	\
+  }									\
+while (0)
+
 /* Returns non-zero if error happened, zero if success.  */
 #define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val)		     \
 ({									     \
@@ -62,18 +76,34 @@
    _r10 == -1;								     \
 })
 
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_wake_unlock(ftx, nr_wake, nr_wake2, ftx2)		     \
+({									     \
+   DO_INLINE_SYSCALL(futex, 6, (long) (ftx), FUTEX_WAKE_OP,		     \
+		     (int) (nr_wake), (int) (nr_wake2), (long) (ftx2),	     \
+		     FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);			     \
+   _r10 == -1;								     \
+})
+
 
 #define __lll_mutex_trylock(futex) \
   (atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0)
 #define lll_mutex_trylock(futex) __lll_mutex_trylock (&(futex))
 
 
+#define __lll_robust_mutex_trylock(futex, id) \
+  (atomic_compare_and_exchange_val_acq (futex, id, 0) != 0)
+#define lll_robust_mutex_trylock(futex, id) \
+  __lll_robust_mutex_trylock (&(futex), id)
+
+
 #define __lll_mutex_cond_trylock(futex) \
   (atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0)
 #define lll_mutex_cond_trylock(futex) __lll_mutex_cond_trylock (&(futex))
 
 
 extern void __lll_lock_wait (int *futex) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex) attribute_hidden;
 
 
 #define __lll_mutex_lock(futex)						\
@@ -85,6 +115,18 @@ extern void __lll_lock_wait (int *futex) attribute_hidden;
 #define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
 
 
+#define __lll_robust_mutex_lock(futex, id)				\
+  ({									\
+    int *__futex = (futex);						\
+    int __val = 0;							\
+									\
+    if (atomic_compare_and_exchange_bool_acq (__futex, id, 0) != 0)	\
+      __val = __lll_robust_lock_wait (__futex);				\
+    __val;								\
+  })
+#define lll_robust_mutex_lock(futex, id) __lll_robust_mutex_lock (&(futex), id)
+
+
 #define __lll_mutex_cond_lock(futex)					\
   ((void) ({								\
     int *__futex = (futex);						\
@@ -94,8 +136,24 @@ extern void __lll_lock_wait (int *futex) attribute_hidden;
 #define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex))
 
 
+#define __lll_robust_mutex_cond_lock(futex, id)				\
+  ({									\
+    int *__futex = (futex);						\
+    int __val = 0;							\
+    int __id = (id) | FUTEX_WAITERS;					\
+									\
+    if (atomic_compare_and_exchange_bool_acq (__futex, __id, 0) != 0)	\
+      __val = __lll_robust_lock_wait (__futex);				\
+    __val;								\
+  })
+#define lll_robust_mutex_cond_lock(futex, id) \
+  __lll_robust_mutex_cond_lock (&(futex), id)
+
+
 extern int __lll_timedlock_wait (int *futex, const struct timespec *)
      attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
+     attribute_hidden;
 
 
 #define __lll_mutex_timedlock(futex, abstime)				\
@@ -111,6 +169,19 @@ extern int __lll_timedlock_wait (int *futex, const struct timespec *)
   __lll_mutex_timedlock (&(futex), abstime)
 
 
+#define __lll_robust_mutex_timedlock(futex, abstime, id)		\
+  ({									\
+    int *__futex = (futex);						\
+    int __val = 0;							\
+									\
+    if (atomic_compare_and_exchange_bool_acq (__futex, id, 0) != 0)	\
+      __val = __lll_robust_timedlock_wait (__futex, abstime);		\
+    __val;								\
+  })
+#define lll_robust_mutex_timedlock(futex, abstime, id) \
+  __lll_robust_mutex_timedlock (&(futex), abstime, id)
+
+
 #define __lll_mutex_unlock(futex)			\
   ((void) ({						\
     int *__futex = (futex);				\
@@ -123,6 +194,18 @@ extern int __lll_timedlock_wait (int *futex, const struct timespec *)
   __lll_mutex_unlock(&(futex))
 
 
+#define __lll_robust_mutex_unlock(futex)		\
+  ((void) ({						\
+    int *__futex = (futex);				\
+    int __val = atomic_exchange_rel (__futex, 0);	\
+							\
+    if (__builtin_expect (__val & FUTEX_WAITERS, 0))	\
+      lll_futex_wake (__futex, 1);			\
+  }))
+#define lll_robust_mutex_unlock(futex) \
+  __lll_robust_mutex_unlock(&(futex))
+
+
 #define __lll_mutex_unlock_force(futex)		\
   ((void) ({					\
     int *__futex = (futex);			\
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/pt-initfini.c b/nptl/sysdeps/unix/sysv/linux/ia64/pt-initfini.c
index b7d4e57945..b6d2cec0d0 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/pt-initfini.c
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/pt-initfini.c
@@ -1,5 +1,5 @@
 /* Special .init and .fini section support for ia64. NPTL version.
-   Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it
@@ -38,7 +38,6 @@
 
 #include <stddef.h>
 
-#ifdef HAVE_INITFINI_ARRAY
 
 __asm__ ("\n\
 #include \"defs.h\"\n\
@@ -49,95 +48,3 @@ __asm__ ("\n\
 	.xdata8 \".init_array\",@fptr(__pthread_initialize_minimal_internal)\n\
 /*@_init_PROLOG_ENDS*/\n\
 ");
-
-#else
-
-__asm__ ("\n\
-\n\
-#include \"defs.h\"\n\
-\n\
-/*@HEADER_ENDS*/\n\
-\n\
-/*@_init_PROLOG_BEGINS*/\n\
-	.section .init\n\
-	.align 16\n\
-	.global _init#\n\
-	.proc _init#\n\
-_init:\n\
-	.prologue\n\
-	.save ar.pfs, r34\n\
-	alloc r34 = ar.pfs, 0, 3, 0, 0\n\
-	.vframe r32\n\
-	mov r32 = r12\n\
-	.save rp, r33\n\
-	mov r33 = b0\n\
-	.body\n\
-	adds r12 = -16, r12\n\
-	;;\n\
-	st8 [r12] = gp, -16\n\
-	br.call.sptk.many b0 = __pthread_initialize_minimal_internal# ;;\n\
-	;;\n\
-	adds r12 = 16, r12\n\
-	;;\n\
-	ld8 gp = [r12]\n\
-	;;\n\
-	.endp _init#\n\
-\n\
-/*@_init_PROLOG_ENDS*/\n\
-\n\
-/*@_init_EPILOG_BEGINS*/\n\
-	.section .init\n\
-	.proc _init#\n\
-	.prologue\n\
-	.save ar.pfs, r34\n\
-	.vframe r32\n\
-	.save rp, r33\n\
-	.body\n\
-	mov r12 = r32\n\
-	mov ar.pfs = r34\n\
-	mov b0 = r33\n\
-	br.ret.sptk.many b0\n\
-	.endp _init#\n\
-/*@_init_EPILOG_ENDS*/\n\
-\n\
-/*@_fini_PROLOG_BEGINS*/\n\
-	.section .fini\n\
-	.align 16\n\
-	.global _fini#\n\
-	.proc _fini#\n\
-_fini:\n\
-	.prologue\n\
-	.save ar.pfs, r34\n\
-	alloc r34 = ar.pfs, 0, 3, 0, 0\n\
-	.vframe r32\n\
-	mov r32 = r12\n\
-	.save rp, r33\n\
-	mov r33 = b0\n\
-	.body\n\
-	adds r12 = -16, r12\n\
-	;;\n\
-	.endp _fini#\n\
-\n\
-/*@_fini_PROLOG_ENDS*/\n\
-\n\
-/*@_fini_EPILOG_BEGINS*/\n\
-	.section .fini\n\
-	.proc _fini#\n\
-	.prologue\n\
-	.save ar.pfs, r34\n\
-	.vframe r32\n\
-	.save rp, r33\n\
-	.body\n\
-	mov r12 = r32\n\
-	mov ar.pfs = r34\n\
-	mov b0 = r33\n\
-	br.ret.sptk.many b0\n\
-	.endp _fini#\n\
-\n\
-/*@_fini_EPILOG_ENDS*/\n\
-\n\
-/*@TRAILER_BEGINS*/\n\
-	.weak	__gmon_start__#\n\
-");
-
-#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/ia64/unwind-forcedunwind.c b/nptl/sysdeps/unix/sysv/linux/ia64/unwind-forcedunwind.c
index fb44b426bc..d0c77a62e6 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/unwind-forcedunwind.c
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/unwind-forcedunwind.c
@@ -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.
    Contributed by Jakub Jelinek <jakub@redhat.com>.
 
@@ -34,5 +34,6 @@ _Unwind_GetBSP (struct _Unwind_Context *context)
 {
   if (__builtin_expect (libgcc_s_getbsp == NULL, 0))
     pthread_cancel_init ();
+
   return libgcc_s_getbsp (context);
 }
diff --git a/nptl/sysdeps/unix/sysv/linux/kernel-features.h b/nptl/sysdeps/unix/sysv/linux/kernel-features.h
new file mode 100644
index 0000000000..162d73e388
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/kernel-features.h
@@ -0,0 +1,6 @@
+#include_next <kernel-features.h>
+
+/* NPTL can always assume all clone thread flags work.  */
+#ifndef __ASSUME_CLONE_THREAD_FLAGS
+# define __ASSUME_CLONE_THREAD_FLAGS	1
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
index 3d1c021819..714ad49428 100644
--- a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
+++ b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -19,7 +19,7 @@
 
 #include <unistd.h>
 #include <list.h>
-#include "fork.h"
+#include <fork.h>
 #include <dl-sysdep.h>
 #include <tls.h>
 #include <string.h>
@@ -57,3 +57,11 @@ __libc_pthread_init (ptr, reclaim, functions)
   return &__libc_multiple_threads;
 #endif
 }
+
+#ifdef SHARED
+libc_freeres_fn (freeres_libptread)
+{
+  if (__libc_pthread_functions.ptr_freeres != NULL)
+    __libc_pthread_functions.ptr_freeres ();
+}
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
new file mode 100644
index 0000000000..30ef991bd0
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
@@ -0,0 +1,113 @@
+/* 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.
+
+   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 <sysdep.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+#include <pthreadP.h>
+
+
+int
+__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))
+	return oldval;
+
+      int newval = oldval | FUTEX_WAITERS;
+      if (oldval != newval
+	  && atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
+	continue;
+
+      lll_futex_wait (futex, newval);
+
+    try:
+      ;
+    }
+  while ((oldval = atomic_compare_and_exchange_val_acq (futex,
+							tid | FUTEX_WAITERS,
+							0)) != 0);
+  return 0;
+}
+
+
+int
+__lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
+{
+  /* Reject invalid timeouts.  */
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    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
+    {
+      struct timeval tv;
+      struct timespec rt;
+
+      /* Get the current time.  */
+      (void) __gettimeofday (&tv, NULL);
+
+      /* Compute relative timeout.  */
+      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+      if (rt.tv_nsec < 0)
+	{
+	  rt.tv_nsec += 1000000000;
+	  --rt.tv_sec;
+	}
+
+      /* Already timed out?  */
+      if (rt.tv_sec < 0)
+	return ETIMEDOUT;
+
+      /* Wait.  */
+      if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
+	return oldval;
+
+      int newval = oldval | FUTEX_WAITERS;
+      if (oldval != newval
+	  && atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
+	continue;
+
+      lll_futex_timed_wait (futex, newval, &rt);
+
+    try:
+      ;
+    }
+  while ((oldval = atomic_compare_and_exchange_val_acq (futex,
+							tid | FUTEX_WAITERS,
+							0)) != 0);
+
+  return 0;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym
new file mode 100644
index 0000000000..2f1e9da52b
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym
@@ -0,0 +1,6 @@
+#include <stddef.h>
+#include <pthreadP.h>
+
+--
+
+TID		offsetof (struct pthread, tid)
diff --git a/nptl/sysdeps/unix/sysv/linux/mq_notify.c b/nptl/sysdeps/unix/sysv/linux/mq_notify.c
index e9c2b6e79a..2ec11bf686 100644
--- a/nptl/sysdeps/unix/sysv/linux/mq_notify.c
+++ b/nptl/sysdeps/unix/sysv/linux/mq_notify.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contribute by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -283,5 +283,5 @@ mq_notify (mqd_t mqdes, const struct sigevent *notification)
 }
 
 #else
-# include <sysdeps/generic/mq_notify.c>
+# include <rt/mq_notify.c>
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h
new file mode 100644
index 0000000000..ab95fb57ee
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h
@@ -0,0 +1,90 @@
+/* Minimum guaranteed maximum values for system limits.  Linux/PPC version.
+   Copyright (C) 1993-1998,2000,2002-2004,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
+   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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* The kernel header pollutes the namespace with the NR_OPEN symbol
+   and defines LINK_MAX although filesystems have different maxima.  A
+   similar thing is true for OPEN_MAX: the limit can be changed at
+   runtime and therefore the macro must not be defined.  Remove this
+   after including the header if necessary.  */
+#ifndef NR_OPEN
+# define __undef_NR_OPEN
+#endif
+#ifndef LINK_MAX
+# define __undef_LINK_MAX
+#endif
+#ifndef OPEN_MAX
+# define __undef_OPEN_MAX
+#endif
+
+/* The kernel sources contain a file with all the needed information.  */
+#include <linux/limits.h>
+
+/* Have to remove NR_OPEN?  */
+#ifdef __undef_NR_OPEN
+# undef NR_OPEN
+# undef __undef_NR_OPEN
+#endif
+/* Have to remove LINK_MAX?  */
+#ifdef __undef_LINK_MAX
+# undef LINK_MAX
+# undef __undef_LINK_MAX
+#endif
+/* Have to remove OPEN_MAX?  */
+#ifdef __undef_OPEN_MAX
+# undef OPEN_MAX
+# undef __undef_OPEN_MAX
+#endif
+
+/* The number of data keys per process.  */
+#define _POSIX_THREAD_KEYS_MAX	128
+/* This is the value this implementation supports.  */
+#define PTHREAD_KEYS_MAX	1024
+
+/* Controlling the iterations of destructors for thread-specific data.  */
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS	4
+/* Number of iterations this implementation does.  */
+#define PTHREAD_DESTRUCTOR_ITERATIONS	_POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+/* The number of threads per process.  */
+#define _POSIX_THREAD_THREADS_MAX	64
+/* We have no predefined limit on the number of threads.  */
+#undef PTHREAD_THREADS_MAX
+
+/* Maximum amount by which a process can descrease its asynchronous I/O
+   priority level.  */
+#define AIO_PRIO_DELTA_MAX	20
+
+/* Minimum size for a thread.  At least two pages for systems with 64k
+   pages.  */
+#define PTHREAD_STACK_MIN	131072
+
+/* Maximum number of timer expiration overruns.  */
+#define DELAYTIMER_MAX	2147483647
+
+/* Maximum tty name length.  */
+#define TTY_NAME_MAX		32
+
+/* Maximum login name length.  This is arbitrary.  */
+#define LOGIN_NAME_MAX		256
+
+/* Maximum host name length.  */
+#define HOST_NAME_MAX		64
+
+/* Maximum message queue priority level.  */
+#define MQ_PRIO_MAX		32768
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
index 90c0695697..a7150f6aef 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 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
 
@@ -58,11 +58,25 @@ typedef union
 } pthread_attr_t;
 
 
+#if __WORDSIZE == 64
+typedef struct __pthread_internal_list
+{
+  struct __pthread_internal_list *__prev;
+  struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+  struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+
 /* Data structures for mutex handling.  The structure of the attribute
    type is deliberately not exposed.  */
 typedef union
 {
-  struct
+  struct __pthread_mutex_s
   {
     int __lock;
     unsigned int __count;
@@ -73,10 +87,18 @@ typedef union
     /* KIND must stay at this position in the structure to maintain
        binary compatibility.  */
     int __kind;
-#if __WORDSIZE != 64
+#if __WORDSIZE == 64
+    int __spins;
+    __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV	1
+#else
     unsigned int __nusers;
+    __extension__ union
+    {
+      int __spins;
+      __pthread_slist_t __list;
+    };
 #endif
-    int __spins;
   } __data;
   char __size[__SIZEOF_PTHREAD_MUTEX_T];
   long int __align;
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
index 2bee000730..0136b97595 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.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 Paul Mackerras <paulus@au.ibm.com>, 2003.
 
@@ -13,7 +13,7 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Libr	\ary; if not, write to the Free
+   License along with the GNU C Library; if not, write to the Free
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
@@ -33,6 +33,11 @@
 #define FUTEX_WAKE		1
 #define FUTEX_REQUEUE		3
 #define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
 
 /* Initializer for compatibility lock.	*/
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
@@ -67,6 +72,17 @@
     INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret;		      \
   })
 
+#define lll_robust_mutex_dead(futexv) \
+  do									      \
+    {									      \
+      INTERNAL_SYSCALL_DECL (__err);					      \
+      int *__futexp = &(futexv);					      \
+									      \
+      atomic_or (__futexp, FUTEX_OWNER_DIED);				      \
+      INTERNAL_SYSCALL (futex, __err, 4, __futexp, FUTEX_WAKE, 1, 0);	      \
+    }									      \
+  while (0)
+
 /* Returns non-zero if error happened, zero if success.  */
 #define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \
   ({									      \
@@ -79,16 +95,43 @@
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
   })
 
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+									      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6,				      \
+			      (futexp), FUTEX_WAKE_OP, (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	""
 #else
 # define __lll_acq_instr	"isync"
-# define __lll_rel_instr	"sync"
+# ifdef _ARCH_PWR4
+/*
+ * Newer powerpc64 processors support the new "light weight" sync (lwsync)
+ * So if the build is using -mcpu=[power4,power5,power5+,970] we can
+ * safely use lwsync.
+ */
+#  define __lll_rel_instr	"lwsync"
+# else
+/*
+ * Older powerpc32 processors don't support the new "light weight"
+ * sync (lwsync).  So the only safe option is to use normal sync
+ * for all powerpc32 applications.
+ */
+#  define __lll_rel_instr	"sync"
+# endif
 #endif
 
-/* Set *futex to 1 if it is 0, atomically.  Returns the old value */
-#define __lll_trylock(futex) \
+/* Set *futex to ID if it is 0, atomically.  Returns the old value */
+#define __lll_robust_trylock(futex, id) \
   ({ int __val;								      \
      __asm __volatile ("1:	lwarx	%0,0,%2\n"			      \
 		       "	cmpwi	0,%0,0\n"			      \
@@ -97,31 +140,26 @@
 		       "	bne-	1b\n"				      \
 		       "2:	" __lll_acq_instr			      \
 		       : "=&r" (__val), "=m" (*futex)			      \
-		       : "r" (futex), "r" (1), "m" (*futex)		      \
+		       : "r" (futex), "r" (id), "m" (*futex)		      \
 		       : "cr0", "memory");				      \
      __val;								      \
   })
 
+#define lll_robust_mutex_trylock(lock, id) __lll_robust_trylock (&(lock), id)
+
+/* Set *futex to 1 if it is 0, atomically.  Returns the old value */
+#define __lll_trylock(futex) __lll_robust_trylock (futex, 1)
+
 #define lll_mutex_trylock(lock)	__lll_trylock (&(lock))
 
 /* Set *futex to 2 if it is 0, atomically.  Returns the old value */
-#define __lll_cond_trylock(futex) \
-  ({ int __val;								      \
-     __asm __volatile ("1:	lwarx	%0,0,%2\n"			      \
-		       "	cmpwi	0,%0,0\n"			      \
-		       "	bne	2f\n"				      \
-		       "	stwcx.	%3,0,%2\n"			      \
-		       "	bne-	1b\n"				      \
-		       "2:	" __lll_acq_instr			      \
-		       : "=&r" (__val), "=m" (*futex)			      \
-		       : "r" (futex), "r" (2), "m" (*futex)		      \
-		       : "cr0", "memory");				      \
-     __val;								      \
-  })
+#define __lll_cond_trylock(futex) __lll_robust_trylock (futex, 2)
+
 #define lll_mutex_cond_trylock(lock)	__lll_cond_trylock (&(lock))
 
 
 extern void __lll_lock_wait (int *futex) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex) attribute_hidden;
 
 #define lll_mutex_lock(lock) \
   (void) ({								      \
@@ -131,6 +169,16 @@ extern void __lll_lock_wait (int *futex) attribute_hidden;
       __lll_lock_wait (__futex);					      \
   })
 
+#define lll_robust_mutex_lock(lock, id) \
+  ({									      \
+    int *__futex = &(lock);						      \
+    int __val = 0;							      \
+    if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id,  \
+								0), 0))	      \
+      __val = __lll_robust_lock_wait (__futex);				      \
+    __val;								      \
+  })
+
 #define lll_mutex_cond_lock(lock) \
   (void) ({								      \
     int *__futex = &(lock);						      \
@@ -139,8 +187,22 @@ extern void __lll_lock_wait (int *futex) attribute_hidden;
       __lll_lock_wait (__futex);					      \
   })
 
+#define lll_robust_mutex_cond_lock(lock, id) \
+  ({									      \
+    int *__futex = &(lock);						      \
+    int __val = 0;							      \
+    int __id = id | FUTEX_WAITERS;					      \
+    if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, __id,\
+								0), 0))	      \
+      __val = __lll_robust_lock_wait (__futex);				      \
+    __val;								      \
+  })
+
+
 extern int __lll_timedlock_wait
   (int *futex, const struct timespec *) attribute_hidden;
+extern int __lll_robust_timedlock_wait
+  (int *futex, const struct timespec *) attribute_hidden;
 
 #define lll_mutex_timedlock(lock, abstime) \
   ({									      \
@@ -152,6 +214,16 @@ extern int __lll_timedlock_wait
     __val;								      \
   })
 
+#define lll_robust_mutex_timedlock(lock, abstime, id) \
+  ({									      \
+    int *__futex = &(lock);						      \
+    int __val = 0;							      \
+    if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id,  \
+								0), 0))	      \
+      __val = __lll_robust_timedlock_wait (__futex, abstime);		      \
+    __val;								      \
+  })
+
 #define lll_mutex_unlock(lock) \
   ((void) ({								      \
     int *__futex = &(lock);						      \
@@ -160,6 +232,14 @@ extern int __lll_timedlock_wait
       lll_futex_wake (__futex, 1);					      \
   }))
 
+#define lll_robust_mutex_unlock(lock) \
+  ((void) ({								      \
+    int *__futex = &(lock);						      \
+    int __val = atomic_exchange_rel (__futex, 0);			      \
+    if (__builtin_expect (__val & FUTEX_WAITERS, 0))			      \
+      lll_futex_wake (__futex, 1);					      \
+  }))
+
 #define lll_mutex_unlock_force(lock) \
   ((void) ({								      \
     int *__futex = &(lock);						      \
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
index e19579e842..675a997e97 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
@@ -1,3 +1,9 @@
-#define RESET_PID
-#include <tcb-offsets.h>
-#include <sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
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 7f5ba4aeef..3752abc870 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
@@ -1,5 +1,5 @@
 /* Cancellable system call stubs.  Linux/PowerPC version.
-   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
 
@@ -15,8 +15,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 #include <tls.h>
@@ -30,7 +30,6 @@
 # define PSEUDO(name, syscall_name, args)				\
   .section ".text";							\
   ENTRY (name)								\
-    cfi_startproc;							\
     SINGLE_THREAD_P;							\
     bne- .Lpseudo_cancel;						\
   .type __##syscall_name##_nocancel,@function;				\
@@ -45,6 +44,7 @@
     mflr 9;								\
     stw 9,52(1);							\
     cfi_offset (lr, 4);							\
+    CGOTSETUP;								\
     DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
     CENABLE;								\
     stw 3,16(1);	/* store CENABLE return value (MASK).  */	\
@@ -58,10 +58,10 @@
     lwz 4,52(1);							\
     lwz 0,12(1);	/* restore CR/R3. */				\
     lwz 3,8(1);								\
+    CGOTRESTORE;							\
     mtlr 4;								\
     mtcr 0;								\
-    addi 1,1,48;							\
-    cfi_endproc;
+    addi 1,1,48;
 
 # define DOCARGS_0
 # define UNDOCARGS_0
@@ -84,15 +84,30 @@
 # define DOCARGS_6	stw 8,40(1); DOCARGS_5
 # define UNDOCARGS_6	lwz 8,40(1); UNDOCARGS_5
 
+# define CGOTSETUP
+# define CGOTRESTORE
+
 # ifdef IS_IN_libpthread
-#  define CENABLE	bl JUMPTARGET(__pthread_enable_asynccancel)
-#  define CDISABLE	bl JUMPTARGET(__pthread_disable_asynccancel)
+#  define CENABLE	bl __pthread_enable_asynccancel@local
+#  define CDISABLE	bl __pthread_disable_asynccancel@local
 # elif !defined NOT_IN_libc
-#  define CENABLE	bl JUMPTARGET(__libc_enable_asynccancel)
-#  define CDISABLE	bl JUMPTARGET(__libc_disable_asynccancel)
+#  define CENABLE	bl __libc_enable_asynccancel@local
+#  define CDISABLE	bl __libc_disable_asynccancel@local
 # elif defined IS_IN_librt
 #  define CENABLE	bl JUMPTARGET(__librt_enable_asynccancel)
 #  define CDISABLE	bl JUMPTARGET(__librt_disable_asynccancel)
+#  if defined HAVE_AS_REL16 && defined PIC
+#   undef CGOTSETUP
+#   define CGOTSETUP							\
+    bcl 20,31,1f;							\
+ 1: stw 30,44(1);							\
+    mflr 30;								\
+    addis 30,30,_GLOBAL_OFFSET_TABLE-1b@ha;				\
+    addi 30,30,_GLOBAL_OFFSET_TABLE-1b@l
+#   undef CGOTRESTORE
+#   define CGOTRESTORE							\
+    lwz 30,44(1)
+#  endif
 # else
 #  error Unsupported library
 # endif
@@ -113,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/clone.S b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
index f87adf4737..675a997e97 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
@@ -1,3 +1,9 @@
-#define RESET_PID
-#include <tcb-offsets.h>
-#include <sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#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 226aaafdce..707765ab58 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
@@ -1,5 +1,5 @@
 /* Cancellable system call stubs.  Linux/PowerPC64 version.
-   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 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
 
@@ -15,8 +15,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 #include <tls.h>
@@ -36,7 +36,6 @@
 # define PSEUDO(name, syscall_name, args)				\
   .section ".text";							\
   ENTRY (name)								\
-    cfi_startproc;							\
     SINGLE_THREAD_P;							\
     bne- .Lpseudo_cancel;						\
   .type DASHDASHPFX(syscall_name##_nocancel),@function;			\
@@ -66,8 +65,7 @@
     ld   3,64(1);							\
     mtlr 9;								\
     mtcr 0;								\
-    addi 1,1,128;							\
-    cfi_endproc;
+    addi 1,1,128;
 
 # define DOCARGS_0
 # define UNDOCARGS_0
@@ -119,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/pthread/sigaction.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstack.c
index 4d36150a90..8aa971ab9a 100644
--- a/nptl/sysdeps/pthread/sigaction.c
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstack.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -17,38 +17,35 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* This is tricky.  GCC doesn't like #include_next in the primary
-   source file and even if it did, the first #include_next is this
-   exact file anyway.  */
-#ifndef LIBC_SIGACTION
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include "pthreadP.h"
 
-#include <nptl/pthreadP.h>
-
-/* We use the libc implementation but we tell it to not allow
-   SIGCANCEL or SIGTIMER to be handled.  */
-# define LIBC_SIGACTION	1
-
-# include <nptl/sysdeps/pthread/sigaction.c>
 
 int
-__sigaction (sig, act, oact)
-     int sig;
-     const struct sigaction *act;
-     struct sigaction *oact;
+__pthread_attr_setstack (attr, stackaddr, stacksize)
+     pthread_attr_t *attr;
+     void *stackaddr;
+     size_t stacksize;
 {
-  if (__builtin_expect (sig == SIGCANCEL || sig == SIGSETXID, 0))
-    {
-      __set_errno (EINVAL);
-      return -1;
-    }
+  struct pthread_attr *iattr;
 
-  return __libc_sigaction (sig, act, oact);
-}
-libc_hidden_weak (__sigaction)
-weak_alias (__sigaction, sigaction)
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
 
-#else
+  /* Catch invalid sizes.  */
+  if (stacksize < 16384)
+    return EINVAL;
 
-# include_next <sigaction.c>
+#ifdef EXTRA_PARAM_CHECKS
+  EXTRA_PARAM_CHECKS;
+#endif
 
-#endif /* LIBC_SIGACTION */
+  iattr->stacksize = stacksize;
+  iattr->stackaddr = (char *) stackaddr + stacksize;
+  iattr->flags |= ATTR_FLAG_STACKADDR;
+
+  return 0;
+}
+strong_alias (__pthread_attr_setstack, pthread_attr_setstack)
diff --git a/nptl/sysdeps/alpha/jmpbuf-unwind.h b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c
index 5cef8b1cf5..ea8c95981e 100644
--- a/nptl/sysdeps/alpha/jmpbuf-unwind.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -17,15 +17,32 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <setjmp.h>
-#include <stdint.h>
-#include <unwind.h>
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include "pthreadP.h"
 
-#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
-  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
 
-#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
-  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_SP] - (_adj))
+int
+__pthread_attr_setstacksize (attr, stacksize)
+     pthread_attr_t *attr;
+     size_t stacksize;
+{
+  struct pthread_attr *iattr;
 
-/* We use the normal lobngjmp for unwinding.  */
-#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
+  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+  iattr = (struct pthread_attr *) attr;
+
+  /* Catch invalid sizes.  */
+  if (stacksize < 16384)
+    return EINVAL;
+
+  size_t ps = __getpagesize ();
+  if (stacksize < 2 * ps)
+    stacksize = 2 * ps;
+
+  iattr->stacksize = stacksize;
+
+  return 0;
+}
+strong_alias (__pthread_attr_setstacksize, pthread_attr_setstacksize)
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym b/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
new file mode 100644
index 0000000000..a1b6794260
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
@@ -0,0 +1,6 @@
+#include <pthreadP.h>
+
+-- These PI macros are used by assembly code.
+
+MUTEX_KIND	offsetof (pthread_mutex_t, __data.__kind)
+PI_BIT		PTHREAD_MUTEX_PRIO_INHERIT_NP
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c b/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c
index ca84f1c9bd..355e695ec2 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c
+++ b/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c
@@ -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 Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -27,7 +27,7 @@
 
 
 /* Defined in pthread_setaffinity.c.  */
-extern size_t __kernel_cpumask_size;
+extern size_t __kernel_cpumask_size attribute_hidden;
 extern int __determine_cpumask_size (pid_t tid);
 
 
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c b/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
new file mode 100644
index 0000000000..82c2446d55
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
@@ -0,0 +1,111 @@
+/* pthread_getcpuclockid -- Get POSIX clockid_t for a pthread_t.  Linux version
+   Copyright (C) 2000,2001,2002,2003,2004,2005 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <pthreadP.h>
+#include <sys/time.h>
+#include <tls.h>
+#include <kernel-features.h>
+#include <kernel-posix-cpu-timers.h>
+
+
+#if !(__ASSUME_POSIX_CPU_TIMERS > 0)
+int __libc_missing_posix_cpu_timers attribute_hidden;
+#endif
+#if !(__ASSUME_POSIX_TIMERS > 0)
+int __libc_missing_posix_timers attribute_hidden;
+#endif
+
+int
+pthread_getcpuclockid (threadid, clockid)
+     pthread_t threadid;
+     clockid_t *clockid;
+{
+  struct pthread *pd = (struct pthread *) threadid;
+
+  /* Make sure the descriptor is valid.  */
+  if (INVALID_TD_P (pd))
+    /* Not a valid thread handle.  */
+    return ESRCH;
+
+#ifdef __NR_clock_getres
+  /* The clockid_t value is a simple computation from the TID.
+     But we do a clock_getres call to validate it if we aren't
+     yet sure we have the kernel support.  */
+
+  const clockid_t tidclock = MAKE_THREAD_CPUCLOCK (pd->tid, CPUCLOCK_SCHED);
+
+# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
+#  if !(__ASSUME_POSIX_TIMERS > 0)
+  if (__libc_missing_posix_timers && !__libc_missing_posix_cpu_timers)
+    __libc_missing_posix_cpu_timers = 1;
+#  endif
+  if (!__libc_missing_posix_cpu_timers)
+    {
+      INTERNAL_SYSCALL_DECL (err);
+      int r = INTERNAL_SYSCALL (clock_getres, err, 2, tidclock, NULL);
+      if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+# endif
+	{
+	  *clockid = tidclock;
+	  return 0;
+	}
+
+# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
+#  if !(__ASSUME_POSIX_TIMERS > 0)
+      if (INTERNAL_SYSCALL_ERRNO (r, err) == ENOSYS)
+	{
+	  /* The kernel doesn't support these calls at all.  */
+	  __libc_missing_posix_timers = 1;
+	  __libc_missing_posix_cpu_timers = 1;
+	}
+      else
+#  endif
+	if (INTERNAL_SYSCALL_ERRNO (r, err) == EINVAL)
+	  {
+	    /* The kernel doesn't support these clocks at all.  */
+	    __libc_missing_posix_cpu_timers = 1;
+	  }
+      else
+	return INTERNAL_SYSCALL_ERRNO (r, err);
+    }
+# endif
+#endif
+
+#ifdef CLOCK_THREAD_CPUTIME_ID
+  /* We need to store the thread ID in the CLOCKID variable together
+     with a number identifying the clock.  We reserve the low 3 bits
+     for the clock ID and the rest for the thread ID.  This is
+     problematic if the thread ID is too large.  But 29 bits should be
+     fine.
+
+     If some day more clock IDs are needed the ID part can be
+     enlarged.  The IDs are entirely internal.  */
+  if (pd->tid >= 1 << (8 * sizeof (*clockid) - CLOCK_IDFIELD_SIZE))
+    return ERANGE;
+
+  /* Store the number.  */
+  *clockid = CLOCK_THREAD_CPUTIME_ID | (pd->tid << CLOCK_IDFIELD_SIZE);
+
+  return 0;
+#else
+  /* We don't have a timer for that.  */
+  return ENOENT;
+#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/pthread_mutex_cond_lock.c b/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
index 990db87416..a97351f880 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
+++ b/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
@@ -1,7 +1,8 @@
 #include <pthreadP.h>
 
-#define LLL_MUTEX_LOCK(mutex) lll_mutex_cond_lock(mutex)
-#define LLL_MUTEX_TRYLOCK(mutex) lll_mutex_cond_trylock(mutex)
+#define LLL_MUTEX_LOCK(mutex) lll_mutex_cond_lock (mutex)
+#define LLL_MUTEX_TRYLOCK(mutex) lll_mutex_cond_trylock (mutex)
+#define LLL_ROBUST_MUTEX_LOCK(mutex, id) lll_robust_mutex_cond_lock (mutex, id)
 #define __pthread_mutex_lock __pthread_mutex_cond_lock
 #define NO_INCR
 
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c b/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c
index 5b24c694a9..3776e26e4b 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c
+++ b/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c
@@ -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 Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -25,7 +25,7 @@
 #include <shlib-compat.h>
 
 
-size_t __kernel_cpumask_size;
+size_t __kernel_cpumask_size attribute_hidden;
 
 
 /* Determine the current affinity.  As a side affect we learn
diff --git a/nptl/sysdeps/unix/sysv/linux/register-atfork.c b/nptl/sysdeps/unix/sysv/linux/register-atfork.c
index 9707e4663c..cb5b2b832f 100644
--- a/nptl/sysdeps/unix/sysv/linux/register-atfork.c
+++ b/nptl/sysdeps/unix/sysv/linux/register-atfork.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,7 +20,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
-#include "fork.h"
+#include <fork.h>
 
 
 /* Lock to protect allocation and deallocation of fork handlers.  */
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/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
index 6b3618cd57..c77031d7bb 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -57,11 +57,25 @@ typedef union
 } pthread_attr_t;
 
 
+#if __WORDSIZE == 64
+typedef struct __pthread_internal_list
+{
+  struct __pthread_internal_list *__prev;
+  struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+  struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+
 /* Data structures for mutex handling.  The structure of the attribute
    type is not exposed on purpose.  */
 typedef union
 {
-  struct
+  struct __pthread_mutex_s
   {
     int __lock;
     unsigned int __count;
@@ -72,10 +86,18 @@ typedef union
     /* KIND must stay at this position in the structure to maintain
        binary compatibility.  */
     int __kind;
-#if __WORDSIZE != 64
+#if __WORDSIZE == 64
+    int __spins;
+    __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV	1
+#else
     unsigned int __nusers;
+    __extension__ union
+    {
+      int __spins;
+      __pthread_slist_t __list;
+    };
 #endif
-    int __spins;
   } __data;
   char __size[__SIZEOF_PTHREAD_MUTEX_T];
   long int __align;
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
index f4ed98a503..38d9f2ac41 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 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -30,6 +30,11 @@
 #define FUTEX_WAKE		1
 #define FUTEX_REQUEUE		3
 #define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
 
 /* Initializer for compatibility lock.	*/
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
@@ -83,6 +88,17 @@
   })
 
 
+#define lll_robust_mutex_dead(futexv) \
+  do									      \
+    {									      \
+      int *__futexp = &(futexv);					      \
+									      \
+      atomic_or (__futexp, FUTEX_OWNER_DIED);				      \
+      lll_futex_wake (__futexp, 1);					      \
+    }									      \
+  while (0)
+
+
 /* Returns non-zero if error happened, zero if success.  */
 #define lll_futex_requeue(futex, nr_wake, nr_move, mutex, val) \
   ({									      \
@@ -103,6 +119,27 @@
   })
 
 
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_wake_unlock(futex, nr_wake, nr_wake2, futex2) \
+  ({									      \
+    register unsigned long int __r2 asm ("2") = (unsigned long int) (futex);  \
+    register unsigned long int __r3 asm ("3") = FUTEX_WAKE_OP;	      \
+    register unsigned long int __r4 asm ("4") = (long int) (nr_wake);	      \
+    register unsigned long int __r5 asm ("5") = (long int) (nr_wake2);	      \
+    register unsigned long int __r6 asm ("6") = (unsigned long int) (futex2); \
+    register unsigned long int __r7 asm ("7")				      \
+      = (int) FUTEX_OP_CLEAR_WAKE_IF_GT_ONE;				      \
+    register unsigned long __result asm ("2");				      \
+									      \
+    __asm __volatile ("svc %b1"						      \
+		      : "=d" (__result)					      \
+		      : "i" (SYS_futex), "0" (__r2), "d" (__r3),	      \
+			"d" (__r4), "d" (__r5), "d" (__r6), "d" (__r7)	      \
+		      : "cc", "memory" );				      \
+    __result > -4096UL;							      \
+  })
+
+
 #define lll_compare_and_swap(futex, oldval, newval, operation) \
   do {									      \
     __typeof (futex) __futex = (futex);					      \
@@ -144,7 +181,23 @@ __lll_mutex_cond_trylock (int *futex)
 #define lll_mutex_cond_trylock(futex) __lll_mutex_cond_trylock (&(futex))
 
 
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_mutex_trylock (int *futex, int id)
+{
+    unsigned int old;
+
+    __asm __volatile ("cs %0,%3,%1"
+		       : "=d" (old), "=Q" (*futex)
+		       : "0" (0), "d" (id), "m" (*futex) : "cc", "memory" );
+    return old != 0;
+}
+#define lll_robust_mutex_trylock(futex, id) \
+  __lll_robust_mutex_trylock (&(futex), id)
+
+
 extern void __lll_lock_wait (int *futex) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex) attribute_hidden;
 
 static inline void
 __attribute__ ((always_inline))
@@ -155,6 +208,17 @@ __lll_mutex_lock (int *futex)
 }
 #define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
 
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_mutex_lock (int *futex, int id)
+{
+  int result = 0;
+  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+    result = __lll_robust_lock_wait (futex);
+  return result;
+}
+#define lll_robust_mutex_lock(futex, id) __lll_robust_mutex_lock (&(futex), id)
+
 static inline void
 __attribute__ ((always_inline))
 __lll_mutex_cond_lock (int *futex)
@@ -164,8 +228,13 @@ __lll_mutex_cond_lock (int *futex)
 }
 #define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex))
 
+#define lll_robust_mutex_cond_lock(futex, id) \
+  __lll_robust_mutex_lock (&(futex), (id) | FUTEX_WAITERS)
+
 extern int __lll_timedlock_wait
   (int *futex, const struct timespec *) attribute_hidden;
+extern int __lll_robust_timedlock_wait
+  (int *futex, const struct timespec *) attribute_hidden;
 
 static inline int
 __attribute__ ((always_inline))
@@ -179,6 +248,19 @@ __lll_mutex_timedlock (int *futex, const struct timespec *abstime)
 #define lll_mutex_timedlock(futex, abstime) \
   __lll_mutex_timedlock (&(futex), abstime)
 
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
+			      int id)
+{
+  int result = 0;
+  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+    result = __lll_robust_timedlock_wait (futex, abstime);
+  return result;
+}
+#define lll_robust_mutex_timedlock(futex, abstime, id) \
+  __lll_robust_mutex_timedlock (&(futex), abstime, id)
+
 
 static inline void
 __attribute__ ((always_inline))
@@ -197,6 +279,21 @@ __lll_mutex_unlock (int *futex)
 
 static inline void
 __attribute__ ((always_inline))
+__lll_robust_mutex_unlock (int *futex, int mask)
+{
+  int oldval;
+  int newval = 0;
+
+  lll_compare_and_swap (futex, oldval, newval, "slr %2,%2");
+  if (oldval & mask)
+    lll_futex_wake (futex, 1);
+}
+#define lll_robust_mutex_unlock(futex) \
+  __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS)
+
+
+static inline void
+__attribute__ ((always_inline))
 __lll_mutex_unlock_force (int *futex)
 {
   *futex = 0;
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/s390-32/clone.S b/nptl/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
index 682f94dae8..675a997e97 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
+++ b/nptl/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/s390/s390-32/clone.S>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#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/clone.S b/nptl/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
index 87ee2e1846..675a997e97 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
+++ b/nptl/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/s390/s390-64/clone.S>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#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/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
index 5125408dcb..969686dd5a 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 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 Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -44,11 +44,17 @@ typedef union
 } pthread_attr_t;
 
 
+typedef struct __pthread_internal_slist
+{
+  struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+
+
 /* Data structures for mutex handling.  The structure of the attribute
    type is not exposed on purpose.  */
 typedef union
 {
-  struct
+  struct __pthread_mutex_s
   {
     int __lock;
     unsigned int __count;
@@ -57,7 +63,11 @@ typedef union
        binary compatibility.  */
     int __kind;
     unsigned int __nusers;
-    int __spins;
+    __extension__ union
+    {
+      int __spins;
+      __pthread_slist_t __list;
+    };
   } __data;
   char __size[__SIZEOF_PTHREAD_MUTEX_T];
   long int __align;
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/clone.S b/nptl/sysdeps/unix/sysv/linux/sh/clone.S
index 62a11972d8..675a997e97 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/clone.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/clone.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/sh/clone.S>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
index bcb15615e5..ac3169889f 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 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005 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
@@ -32,8 +32,11 @@
 	.type	__lll_mutex_lock_wait,@function
 	.hidden	__lll_mutex_lock_wait
 	.align	5
+	cfi_startproc
 __lll_mutex_lock_wait:
 	mov.l	r8, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r8, 0)
 	mov	r4, r6
 	mov	r5, r8
 	mov	#0, r7		/* No timeout.  */
@@ -51,14 +54,15 @@ __lll_mutex_lock_wait:
 	SYSCALL_INST_PAD
 
 2:
-	mov	#2, r4
-	XCHG (r4, @r8, r2)
+	mov	#2, r6
+	XCHG (r6, @r8, r2)
 	tst	r2, r2
 	bf	1b
 
 	mov.l	@r15+, r8
 	ret
 	 mov	r2, r0
+	cfi_endproc
 	.size	__lll_mutex_lock_wait,.-__lll_mutex_lock_wait
 
 
@@ -67,6 +71,7 @@ __lll_mutex_lock_wait:
 	.type	__lll_mutex_timedlock_wait,@function
 	.hidden	__lll_mutex_timedlock_wait
 	.align	5
+	cfi_startproc
 __lll_mutex_timedlock_wait:
 	/* Check for a valid timeout value.  */
 	mov.l	@(4,r6), r1
@@ -75,14 +80,21 @@ __lll_mutex_timedlock_wait:
 	bt	3f
 
 	mov.l	r10, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r10, 0)
 	mov.l	r9, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r9, 0)
 	mov.l	r8, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r8, 0)
 	mov	r4, r10
 	mov	r6, r9
 	mov	r5, r8
 
 	/* Stack frame for the timespec and timeval structs.  */
 	add	#-8, r15
+	cfi_adjust_cfa_offset(8)
 
 1:
 	/* Get current time.  */
@@ -162,6 +174,7 @@ __lll_mutex_timedlock_wait:
 5:
 	bra	6b
 	 mov	#ETIMEDOUT, r0
+	cfi_endproc
 
 .L1k:
 	.word	1000
@@ -178,6 +191,7 @@ __lll_mutex_timedlock_wait:
 	.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
@@ -195,6 +209,7 @@ lll_unlock_wake_cb:
 1:	
 	rts
 	 nop
+	cfi_endproc
 	.size	lll_unlock_wake_cb,.-lll_unlock_wake_cb
 #endif
 
@@ -203,6 +218,7 @@ lll_unlock_wake_cb:
 	.type	__lll_mutex_unlock_wake,@function
 	.hidden	__lll_mutex_unlock_wake
 	.align	5
+	cfi_startproc
 __lll_mutex_unlock_wake:
 	mov	#FUTEX_WAKE, r5
 	mov	#1, r6		/* Wake one thread.  */
@@ -214,6 +230,7 @@ __lll_mutex_unlock_wake:
 	SYSCALL_INST_PAD
 	rts
 	 nop
+	cfi_endproc
 	.size	__lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
 
 
@@ -222,14 +239,20 @@ __lll_mutex_unlock_wake:
 	.type	__lll_timedwait_tid,@function
 	.hidden	__lll_timedwait_tid
 	.align	5
+	cfi_startproc
 __lll_timedwait_tid:
 	mov.l	r9, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r9, 0)
 	mov.l	r8, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r8, 0)
 	mov	r4, r8
 	mov	r5, r9
 
 	/* Stack frame for the timespec and timeval structs.  */
 	add	#-8, r15
+	cfi_adjust_cfa_offset(8)
 
 2:
 	/* Get current time.  */
@@ -292,6 +315,7 @@ __lll_timedwait_tid:
 6:
 	bra	3b
 	 mov	#ETIMEDOUT, r0
+	cfi_endproc
 
 .L1k2:
 	.word	1000
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
index d9376d45a0..0eb1f0114c 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 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 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
@@ -26,6 +26,9 @@
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
 
 
 /* Initializer for compatibility lock.  */
@@ -62,6 +65,28 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 	: "r0", "r1", "r2", "t", "memory"); \
      __result; })
 
+#define lll_robust_mutex_trylock(futex, id)	\
+  ({ unsigned char __result; \
+     __asm __volatile ("\
+	.align 2\n\
+	mova 1f,r0\n\
+	nop\n\
+	mov r15,r1\n\
+	mov #-8,r15\n\
+     0: mov.l @%1,r2\n\
+	cmp/eq r2,%3\n\
+	bf 1f\n\
+	mov.l %2,@%1\n\
+     1: mov r1,r15\n\
+	mov #-1,%0\n\
+	negc %0,%0"\
+	: "=r" (__result) \
+	: "r" (&(futex)), \
+	  "r" (id), \
+	  "r" (LLL_MUTEX_LOCK_INITIALIZER) \
+	: "r0", "r1", "r2", "t", "memory"); \
+     __result; })
+
 #define lll_mutex_cond_trylock(futex) \
   ({ unsigned char __result; \
      __asm __volatile ("\
@@ -102,6 +127,25 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 	    if (__result) \
 	      __lll_mutex_lock_wait (__result, __futex); })
 
+#define lll_robust_mutex_lock(futex, id)		    \
+  ({ int __result, val, *__futex = &(futex); \
+     __asm __volatile ("\
+	.align 2\n\
+	mova 1f,r0\n\
+	nop\n\
+	mov r15,r1\n\
+	mov #-8,r15\n\
+      0: mov.l @%2,%0\n\
+	tst %0,%0\n\
+	bf 1f\n\
+	mov.l %1,@%2\n\
+      1: mov r1,r15"\
+	: "=&r" (__result) : "r" (id), "r" (__futex) \
+	: "r0", "r1", "t", "memory"); \
+     if (__result) \
+       __result = __lll_robust_mutex_lock_wait (__result, __futex); \
+     __result; })
+
 /* Special version of lll_mutex_lock which causes the unlock function to
    always wakeup waiters.  */
 #define lll_mutex_cond_lock(futex) \
@@ -122,6 +166,25 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 	    if (__result) \
 	      __lll_mutex_lock_wait (__result, __futex); })
 
+#define lll_robust_mutex_cond_lock(futex, id)	    \
+  ({ int __result, val, *__futex = &(futex); \
+     __asm __volatile ("\
+	.align 2\n\
+	mova 1f,r0\n\
+	nop\n\
+	mov r15,r1\n\
+	mov #-8,r15\n\
+     0: mov.l @%2,%0\n\
+	tst %0,%0\n\
+	bf 1f\n\
+	mov.l %1,@%2\n\
+     1: mov r1,r15"\
+	: "=&r" (__result) : "r" (id | FUTEX_WAITERS), "r" (__futex) \
+	: "r0", "r1", "t", "memory"); \
+      if (__result) \
+	__result = __lll_robust_mutex_lock_wait (__result, __futex); \
+      __result; })
+
 #define lll_mutex_timedlock(futex, timeout) \
   ({ int __result, val, *__futex = &(futex); \
      __asm __volatile ("\
@@ -141,6 +204,26 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
       __result = __lll_mutex_timedlock_wait (__result, __futex, timeout); \
     __result; })
 
+#define lll_robust_mutex_timedlock(futex, timeout, id)	\
+  ({ int __result, val, *__futex = &(futex); \
+     __asm __volatile ("\
+	.align 2\n\
+	mova 1f,r0\n\
+	nop\n\
+	mov r15,r1\n\
+	mov #-8,r15\n\
+     0: mov.l @%2,%0\n\
+	tst %0,%0\n\
+	bf 1f\n\
+	mov.l %1,@%2\n\
+     1: mov r1,r15"\
+	: "=&r" (__result) : "r" (id), "r" (__futex) \
+	: "r0", "r1", "t", "memory"); \
+    if (__result) \
+      __result = __lll_robust_mutex_timedlock_wait (__result, __futex, \
+						    timeout);	       \
+    __result; })
+
 #define lll_mutex_unlock(futex) \
   (void) ({ int __result, *__futex = &(futex); \
 	    __asm __volatile ("\
@@ -157,6 +240,37 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 	    if (__result) \
 	      __lll_mutex_unlock_wake (__futex); })
 
+#define lll_robust_mutex_unlock(futex) \
+  (void) ({ int __result, *__futex = &(futex); \
+	    __asm __volatile ("\
+		.align 2\n\
+		mova 1f,r0\n\
+		mov r15,r1\n\
+		mov #-6,r15\n\
+	     0: mov.l @%1,%0\n\
+		and %2,%0\n\
+		mov.l %0,@%1\n\
+	     1: mov r1,r15"\
+		: "=&r" (__result) : "r" (__futex), "r" (FUTEX_TID_MASK) \
+		: "r0", "r1", "memory");	\
+	    if (__result) \
+	      __lll_mutex_unlock_wake (__futex); })
+
+#define lll_robust_mutex_dead(futex) \
+  (void) ({ int __ignore, *__futex = &(futex); \
+	    __asm __volatile ("\
+		.align 2\n\
+		mova 1f,r0\n\
+		mov r15,r1\n\
+		mov #-6,r15\n\
+	     0: mov.l @%1,%0\n\
+		or %2,%0\n\
+		mov.l %0,@%1\n\
+	     1: mov r1,r15"\
+		: "=&r" (__ignore) : "r" (__futex), "r" (FUTEX_OWNER_DIED) \
+		: "r0", "r1", "memory");	\
+	    lll_futex_wake (__futex, 1); })
+
 #define lll_mutex_islocked(futex) \
   (futex != 0)
 
@@ -181,19 +295,37 @@ typedef int lll_lock_t;
 # endif
 
 #define lll_futex_wait(futex, val) \
-  do {									      \
-    int __ignore;							      \
+  ({									      \
+    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" (__ignore)					      \
+		      : "=z" (__status)					      \
 		      : "r" (__r3), "r" (__r4), "r" (__r5),		      \
 			"r" (__r6), "r" (__r7)				      \
 		      : "memory", "t");					      \
-  } while (0)
+    __status;								      \
+  })
+
+
+#define lll_futex_timed_wait(futex, val, timeout) \
+  ({									      \
+    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") = (timeout);			      \
+    __asm __volatile (SYSCALL_WITH_INST_PAD				      \
+		      : "=z" (__status)					      \
+		      : "r" (__r3), "r" (__r4), "r" (__r5),		      \
+			"r" (__r6), "r" (__r7)				      \
+		      : "memory", "t");					      \
+    __status;								      \
+  })
 
 
 #define lll_futex_wake(futex, nr) \
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
new file mode 100644
index 0000000000..c57d3cff18
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
@@ -0,0 +1,224 @@
+/* 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
+   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 <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevelrobustlock.h>
+#include "lowlevel-atomic.h"
+
+	.text
+
+#define SYS_gettimeofday	__NR_gettimeofday
+#define SYS_futex		240
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_WAITERS		0x80000000
+#define FUTEX_OWNER_DIED	0x40000000
+
+
+	.globl	__lll_robust_mutex_lock_wait
+	.type	__lll_robust_mutex_lock_wait,@function
+	.hidden	__lll_robust_mutex_lock_wait
+	.align	5
+	cfi_startproc
+__lll_robust_mutex_lock_wait:
+	mov.l	r8, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r8, 0)
+	mov	r5, r8
+	mov	#0, r7		/* No timeout.  */
+	mov	#FUTEX_WAIT, r5
+
+4:
+	mov	r4, r6
+	mov.l	.L_FUTEX_WAITERS, r0
+	or	r0, r6
+	shlr	r0		/* r0 = FUTEX_OWNER_DIED */
+	tst	r0, r4
+	bf/s	3f
+	 cmp/eq	r4, r6
+	bt	1f
+
+	CMPXCHG (r4, @r8, r6, r2)
+	bf	2f
+
+1:
+	mov	r8, r4
+	mov	#SYS_futex, r3
+	extu.b	r3, r3
+	trapa	#0x14
+	SYSCALL_INST_PAD
+
+	mov.l	@r8, r2
+
+2:
+	tst	r2, r2
+	bf/s	4b
+	 mov	r2, r4
+
+	stc	gbr, r1
+	mov.w	.Ltidoff, r2
+	add	r2, r1
+	mov.l	@r1, r6
+	mov	#0, r3
+	CMPXCHG (r3, @r8, r6, r4)
+	bf	4b
+	mov	#0, r4
+
+3:
+	mov.l	@r15+, r8
+	ret
+	 mov	r4, r0
+	cfi_endproc
+	.align	2
+.L_FUTEX_WAITERS:
+	.long	FUTEX_WAITERS
+.Ltidoff:
+	.word	TID - TLS_PRE_TCB_SIZE
+	.size	__lll_robust_mutex_lock_wait,.-__lll_robust_mutex_lock_wait
+
+
+	.globl	__lll_robust_mutex_timedlock_wait
+	.type	__lll_robust_mutex_timedlock_wait,@function
+	.hidden	__lll_robust_mutex_timedlock_wait
+	.align	5
+	cfi_startproc
+__lll_robust_mutex_timedlock_wait:
+	/* Check for a valid timeout value.  */
+	mov.l	@(4,r6), r1
+	mov.l	.L1g, r0
+	cmp/hs	r0, r1
+	bt	3f
+
+	mov.l	r10, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r10, 0)
+	mov.l	r9, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r9, 0)
+	mov.l	r8, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r8, 0)
+	mov	r4, r10
+	mov	r6, r9
+	mov	r5, r8
+
+	/* Stack frame for the timespec and timeval structs.  */
+	add	#-8, r15
+	cfi_adjust_cfa_offset(8)
+
+1:
+	/* Get current time.  */
+	mov	r15, r4
+	mov	#0, r5
+	mov	#SYS_gettimeofday, r3
+	trapa	#0x12
+	SYSCALL_INST_PAD
+
+	/* Compute relative timeout.  */
+	mov.l	@(4,r15), r0
+	mov.w	.L1k, r1
+	dmulu.l	r0, r1		/* Micro seconds to nano seconds.  */
+	mov.l	@r9, r2
+	mov.l	@(4,r9), r3
+	mov.l	@r15, r0
+	sts	macl, r1
+	sub	r0, r2
+	clrt
+	subc	r1, r3
+	bf	4f
+	mov.l	.L1g, r1
+	add	r1, r3
+	add	#-1, r2
+4:
+	cmp/pz	r2
+	bf	8f		/* Time is already up.  */
+
+	mov.l	r2, @r15	/* Store relative timeout.  */
+	mov.l	r3, @(4,r15)
+
+	mov	r10, r6
+	mov.l	.L_FUTEX_WAITERS2, r0
+	or	r0, r6
+	shlr	r0		/* r0 = FUTEX_OWNER_DIED */
+	tst	r0, r4
+	bf/s	6f
+	 cmp/eq	r4, r6
+	bt	2f
+
+	CMPXCHG (r4, @r8, r6, r2)
+	bf/s	5f
+	 mov	#0, r5
+
+2:
+	mov	r8, r4
+	mov	#FUTEX_WAIT, r5
+	mov	r10, r6
+	mov	r15, r7
+	mov	#SYS_futex, r3
+	extu.b	r3, r3
+	trapa	#0x14
+	SYSCALL_INST_PAD
+	mov	r0, r5
+
+	mov.l	@r8, r2
+
+5:
+	tst	r2, r2
+	bf/s	7f
+	 mov	r2, r10
+
+	stc	gbr, r1
+	mov.w	.Ltidoff2, r2
+	add	r2, r1
+	mov.l	@r1, r4
+	mov	#0, r3
+	CMPXCHG (r3, @r8, r4, r10)
+	bf	7f
+	mov	#0, r0
+
+6:
+	add	#8, r15
+	mov.l	@r15+, r8
+	mov.l	@r15+, r9
+	rts
+	 mov.l	@r15+, r10
+
+7:
+	/* Check whether the time expired.  */
+	mov	#-ETIMEDOUT, r1
+	cmp/eq	r5, r1
+	bf	1b
+
+8:
+	bra	6b
+	 mov	#ETIMEDOUT, r0
+3:
+	rts
+	 mov	#EINVAL, r0
+	cfi_endproc
+	.align	2
+.L_FUTEX_WAITERS2:
+	.long	FUTEX_WAITERS
+.L1g:
+	.long	1000000000
+.Ltidoff2:
+	.word	TID - TLS_PRE_TCB_SIZE
+.L1k:
+	.word	1000
+	.size	__lll_robust_mutex_timedlock_wait,.-__lll_robust_mutex_timedlock_wait
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
index 6bd6e60ec1..56f0aa95de 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
@@ -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.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -20,6 +20,7 @@
 #include <shlib-compat.h>
 #include <lowlevelcond.h>
 #include <kernel-features.h>
+#include <pthread-pi-defines.h>
 #include "lowlevel-atomic.h"
 
 #define SYS_futex		240
@@ -98,6 +99,11 @@ __pthread_cond_broadcast:
 	bt/s	9f
 	 add	#cond_futex, r4
 
+	/* XXX: The kernel so far doesn't support requeue to PI futex.  */
+	mov.l	@(MUTEX_KIND,r9), r0
+	tst	#PI_BIT, r0
+	bf	9f
+
 	/* Wake up all threads.  */
 	mov	#FUTEX_CMP_REQUEUE, r5
 	mov	#1, r6
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 74206a71ec..6c782c8a76 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 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 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
@@ -521,6 +521,21 @@ __condvar_tw_cleanup:
 	mov	#1, r2
 	mov	#0, r3
 
+	/* We increment the wakeup_seq counter only if it is lower than
+	   total_seq.  If this is not the case the thread was woken and
+	   then canceled.  In this case we ignore the signal.  */
+	mov.l	@(total_seq+4,r8), r0
+	mov.l	@(wakeup_seq+4,r8), r1
+	cmp/hi	r1, r0
+	bt/s	6f
+	 cmp/hi	r0, r1
+	bt	7f
+	mov.l	@(total_seq,r8), r0
+	mov.l	@(wakeup_seq,r8), r1
+	cmp/hs	r0, r1
+	bt	7f
+
+6:
 	clrt
 	mov.l	@(wakeup_seq,r8),r0
 	mov.l	@(wakeup_seq+4,r8),r1
@@ -532,6 +547,7 @@ __condvar_tw_cleanup:
 	add	r2, r0
 	mov.l	r0,@(cond_futex,r8)
 
+7:
 	clrt
 	mov.l	@(woken_seq,r8),r0
 	mov.l	@(woken_seq+4,r8),r1
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 2d6b685668..6c59f3e6c0 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 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 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
@@ -385,6 +385,21 @@ __condvar_w_cleanup:
 	mov	#1, r2
 	mov	#0, r3
 
+	/* We increment the wakeup_seq counter only if it is lower than
+	   total_seq.  If this is not the case the thread was woken and
+	   then canceled.  In this case we ignore the signal.  */
+	mov.l	@(total_seq+4,r8), r0
+	mov.l	@(wakeup_seq+4,r8), r1
+	cmp/hi	r1, r0
+	bt/s	6f
+	 cmp/hi	r0, r1
+	bt	7f
+	mov.l	@(total_seq,r8), r0
+	mov.l	@(wakeup_seq,r8), r1
+	cmp/hs	r0, r1
+	bt	7f
+
+6:
 	clrt
 	mov.l	@(wakeup_seq,r8),r0
 	mov.l	@(wakeup_seq+4,r8),r1
@@ -396,6 +411,7 @@ __condvar_w_cleanup:
 	add	r2, r0
 	mov.l	r0,@(cond_futex,r8)
 
+7:
 	clrt
 	mov.l	@(woken_seq,r8),r0
 	mov.l	@(woken_seq+4,r8),r1
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h
index 8cdcac5560..90be7bd8d0 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h
@@ -1,4 +1,4 @@
 /*  4 instruction cycles not accessing cache and TLB are needed after
     trapa instruction to avoid an SH-4 silicon bug.  */
 #define NEED_SYSCALL_INST_PAD
-#include <sysdeps/unix/sysv/linux/sh/lowlevellock.h>
+#include_next <lowlevellock.h>
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
index fc3c2340b6..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 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
@@ -49,27 +49,32 @@
     .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
  .Lpseudo_cancel: \
     sts.l pr,@-r15; \
- .LCFI0: \
+    cfi_adjust_cfa_offset (4); \
+    cfi_rel_offset (pr, 0); \
     add _IMM16,r15; \
+    cfi_adjust_cfa_offset (16); \
     SAVE_ARGS_##args; \
- .LCFI1: \
     CENABLE; \
     LOAD_ARGS_##args; \
     add _IMP16,r15; \
- .LCFI2: \
+    cfi_adjust_cfa_offset (-16); \
     lds.l @r15+,pr; \
- .LCFI3: \
+    cfi_adjust_cfa_offset (-4); \
+    cfi_restore (pr); \
     DO_CALL(syscall_name, args); \
     SYSCALL_INST_PAD; \
     sts.l pr,@-r15; \
- .LCFI4: \
+    cfi_adjust_cfa_offset (4); \
+    cfi_rel_offset (pr, 0); \
     mov.l r0,@-r15; \
- .LCFI5: \
+    cfi_adjust_cfa_offset (4); \
+    cfi_rel_offset (r0, 0); \
     CDISABLE; \
     mov.l @r15+,r0; \
- .LCFI6: \
+    cfi_adjust_cfa_offset (-4); \
     lds.l @r15+,pr; \
- .LCFI7: \
+    cfi_adjust_cfa_offset (-4); \
+    cfi_restore (pr); \
     mov r0,r1; \
     mov _IMM12,r2; \
     shad r2,r1; \
@@ -78,106 +83,17 @@
     bf .Lpseudo_end; \
  .Lsyscall_error: \
     SYSCALL_ERROR_HANDLER; \
- .Lpseudo_end: \
- /* Create unwinding information for the syscall wrapper.  */ \
- .section .eh_frame,"a",@progbits; \
- .Lframe1: \
-    .ualong .LECIE1-.LSCIE1; \
- .LSCIE1: \
-    .ualong 0x0; \
-    .byte   0x1; \
-    AUGMENTATION_STRING; \
-    .uleb128 0x1; \
-    .sleb128 -4; \
-    .byte   0x11; \
-    AUGMENTATION_PARAM; \
-    .byte   0xc; \
-    .uleb128 0xf; \
-    .uleb128 0x0; \
-    .align 2; \
- .LECIE1: \
- .LSFDE1: \
-    .ualong .LEFDE1-.LASFDE1; \
- .LASFDE1: \
-    .ualong .LASFDE1-.Lframe1; \
-    START_SYMBOL_REF; \
-    .ualong .Lpseudo_end - .Lpseudo_start; \
-    AUGMENTATION_PARAM_FDE; \
-    .byte   0x4; \
-    .ualong .LCFI0-.Lpseudo_start; \
-    .byte   0xe; \
-    .uleb128 0x4; \
-    .byte   0x91; \
-    .uleb128 0x1; \
-    .byte   0x4; \
-    .ualong .LCFI1-.LCFI0; \
-    .byte   0xe; \
-    .uleb128 0x14; \
-    FRAME_REG_##args; \
-    .byte   0x4; \
-    .ualong .LCFI2-.LCFI1; \
-    .byte   0xe; \
-    .uleb128 0x4; \
-    .byte   0x4; \
-    .ualong .LCFI3-.LCFI2; \
-    .byte   0xe; \
-    .uleb128 0x0; \
-    .byte   0xd1; \
-    .byte   0x4; \
-    .ualong .LCFI4-.LCFI3; \
-    .byte   0xe; \
-    .uleb128 0x4; \
-    .byte   0x91; \
-    .uleb128 0x1; \
-    .byte   0x4; \
-    .ualong .LCFI5-.LCFI4; \
-    .byte   0xe; \
-    .uleb128 0x8; \
-    .byte   0x80; \
-    .uleb128 0x2; \
-    .byte   0x4; \
-    .ualong .LCFI6-.LCFI5; \
-    .byte   0xe; \
-    .uleb128 0x4; \
-    .byte   0xc0; \
-    .byte   0x4; \
-    .ualong .LCFI7-.LCFI6; \
-    .byte   0xe; \
-    .uleb128 0x0; \
-    .byte   0xd1; \
-    .align 2; \
- .LEFDE1: \
- .previous
-
-# ifdef SHARED
-#  define AUGMENTATION_STRING .string "zR"
-#  define AUGMENTATION_PARAM .uleb128 1; .byte 0x1b
-#  define AUGMENTATION_PARAM_FDE .uleb128 0
-#  define START_SYMBOL_REF .long .Lpseudo_start-.
-# else
-#  define AUGMENTATION_STRING .ascii "\0"
-#  define AUGMENTATION_PARAM
-#  define AUGMENTATION_PARAM_FDE
-#  define START_SYMBOL_REF .long .Lpseudo_start
-# endif
-
-# define FRAME_REG_0	/* Nothing.  */
-# define FRAME_REG_1	FRAME_REG_0; .byte 0x84; .uleb128 5
-# define FRAME_REG_2	FRAME_REG_1; .byte 0x85; .uleb128 4
-# define FRAME_REG_3	FRAME_REG_2; .byte 0x86; .uleb128 3
-# define FRAME_REG_4	FRAME_REG_3; .byte 0x87; .uleb128 2
-# define FRAME_REG_5	FRAME_REG_4
-# define FRAME_REG_6	FRAME_REG_5
+ .Lpseudo_end:
 
 # undef PSEUDO_END
 # define PSEUDO_END(sym) \
   END (sym)
 
 # define SAVE_ARGS_0	/* Nothing.  */
-# define SAVE_ARGS_1	SAVE_ARGS_0; mov.l r4,@(0,r15)
-# define SAVE_ARGS_2	SAVE_ARGS_1; mov.l r5,@(4,r15)
-# define SAVE_ARGS_3	SAVE_ARGS_2; mov.l r6,@(8,r15)
-# define SAVE_ARGS_4	SAVE_ARGS_3; mov.l r7,@(12,r15)
+# define SAVE_ARGS_1	SAVE_ARGS_0; mov.l r4,@(0,r15); cfi_offset (r4,-4)
+# define SAVE_ARGS_2	SAVE_ARGS_1; mov.l r5,@(4,r15); cfi_offset (r5,-8)
+# define SAVE_ARGS_3	SAVE_ARGS_2; mov.l r6,@(8,r15); cfi_offset (r6,-12)
+# define SAVE_ARGS_4	SAVE_ARGS_3; mov.l r7,@(12,r15); cfi_offset (r7,-16)
 # define SAVE_ARGS_5	SAVE_ARGS_4
 # define SAVE_ARGS_6	SAVE_ARGS_5
 
@@ -245,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/sleep.c b/nptl/sysdeps/unix/sysv/linux/sleep.c
index c56b49b39f..2dce3210ca 100644
--- a/nptl/sysdeps/unix/sysv/linux/sleep.c
+++ b/nptl/sysdeps/unix/sysv/linux/sleep.c
@@ -1,2 +1,10 @@
-#include <nptl/pthreadP.h>
-#include <sysdeps/unix/sysv/linux/sleep.c>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <sleep.c>
+#else
+/* This defines the CANCELLATION_P macro, which sleep.c checks for.  */
+# include <pthreadP.h>
+# include_next <sleep.c>
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/smp.h b/nptl/sysdeps/unix/sysv/linux/smp.h
index 4f4d358d32..fcc34f7681 100644
--- a/nptl/sysdeps/unix/sysv/linux/smp.h
+++ b/nptl/sysdeps/unix/sysv/linux/smp.h
@@ -1,5 +1,5 @@
 /* Determine whether the host has multiple processors.  Linux version.
-   Copyright (C) 1996, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996, 2002, 2004, 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
@@ -17,36 +17,12 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/sysctl.h>
-#include <not-cancel.h>
-
 /* Test whether the machine has more than one processor.  This is not the
    best test but good enough.  More complicated tests would require `malloc'
    which is not available at that time.  */
 static inline int
 is_smp_system (void)
 {
-  static const int sysctl_args[] = { CTL_KERN, KERN_VERSION };
-  char buf[512];
-  size_t reslen = sizeof (buf);
-
-  /* Try reading the number using `sysctl' first.  */
-  if (__sysctl ((int *) sysctl_args,
-		sizeof (sysctl_args) / sizeof (sysctl_args[0]),
-		buf, &reslen, NULL, 0) < 0)
-    {
-      /* This was not successful.  Now try reading the /proc filesystem.  */
-      int fd = open_not_cancel_2 ("/proc/sys/kernel/version", O_RDONLY);
-      if (__builtin_expect (fd, 0) == -1
-	  || (reslen = read_not_cancel (fd, buf, sizeof (buf))) <= 0)
-	/* This also didn't work.  We give up and say it's a UP machine.  */
-	buf[0] = '\0';
-
-      close_not_cancel_no_status (fd);
-    }
-
-  return strstr (buf, "SMP") != NULL;
+  /* Assume all machines are SMP and/or CMT and/or SMT.  */
+  return 1;
 }
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/Makefile b/nptl/sysdeps/unix/sysv/linux/sparc/Makefile
new file mode 100644
index 0000000000..e98c9bd866
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/Makefile
@@ -0,0 +1,2 @@
+# pull in __syscall_error routine
+libpthread-routines += sysdep
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
index 3c5a289445..e734c1205e 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
@@ -1,5 +1,5 @@
 /* Machine-specific pthread type layouts.  SPARC version.
-   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -58,11 +58,25 @@ typedef union
 } pthread_attr_t;
 
 
+#if __WORDSIZE == 64
+typedef struct __pthread_internal_list
+{
+  struct __pthread_internal_list *__prev;
+  struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+  struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+
 /* Data structures for mutex handling.  The structure of the attribute
    type is deliberately not exposed.  */
 typedef union
 {
-  struct
+  struct __pthread_mutex_s
   {
     int __lock;
     unsigned int __count;
@@ -73,10 +87,18 @@ typedef union
     /* KIND must stay at this position in the structure to maintain
        binary compatibility.  */
     int __kind;
-#if __WORDSIZE != 64
+#if __WORDSIZE == 64
+    int __spins;
+    __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV	1
+#else
     unsigned int __nusers;
+    __extension__ union
+    {
+      int __spins;
+      __pthread_slist_t __list;
+    };
 #endif
-    int __spins;
   } __data;
   char __size[__SIZEOF_PTHREAD_MUTEX_T];
   long int __align;
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
index 4626aec524..5013922a2f 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 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.
 
@@ -30,6 +30,11 @@
 #define FUTEX_WAKE		1
 #define FUTEX_REQUEUE		3
 #define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
 
 /* Initializer for compatibility lock.	*/
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
@@ -76,15 +81,38 @@
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
   })
 
+#define lll_robust_mutex_dead(futexv) \
+  do									      \
+    {									      \
+      int *__futexp = &(futexv);					      \
+      atomic_or (__futexp, FUTEX_OWNER_DIED);				      \
+      lll_futex_wake (__futexp, 1);					      \
+    }									      \
+  while (0)
+
+/* Returns non-zero if error happened, zero if success.  */
 #ifdef __sparc32_atomic_do_lock
-#error SPARC < v9 does not support compare and swap which is essential for futex based locking
+/* Avoid FUTEX_WAKE_OP if supporting pre-v9 CPUs.  */
+# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) 1
+#else
+# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+									      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6,				      \
+			      (futexp), FUTEX_WAKE_OP, (nr_wake),	      \
+			      (nr_wake2), (futexp2),			      \
+			      FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);		      \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
+  })
 #endif
 
 static inline int
 __attribute__ ((always_inline))
 __lll_mutex_trylock (int *futex)
 {
-  return atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0;
+  return atomic_compare_and_exchange_val_24_acq (futex, 1, 0) != 0;
 }
 #define lll_mutex_trylock(futex) __lll_mutex_trylock (&(futex))
 
@@ -92,47 +120,71 @@ static inline int
 __attribute__ ((always_inline))
 __lll_mutex_cond_trylock (int *futex)
 {
-  return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0;
+  return atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0;
 }
 #define lll_mutex_cond_trylock(futex) __lll_mutex_cond_trylock (&(futex))
 
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_mutex_trylock (int *futex, int id)
+{
+  return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0;
+}
+#define lll_robust_mutex_trylock(futex, id) \
+  __lll_robust_mutex_trylock (&(futex), id)
 
-extern void __lll_lock_wait (int *futex) attribute_hidden;
 
+extern void __lll_lock_wait (int *futex) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex) attribute_hidden;
 
 static inline void
 __attribute__ ((always_inline))
 __lll_mutex_lock (int *futex)
 {
-  int val = atomic_compare_and_exchange_val_acq (futex, 1, 0);
+  int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);
 
   if (__builtin_expect (val != 0, 0))
     __lll_lock_wait (futex);
 }
 #define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
 
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_mutex_lock (int *futex, int id)
+{
+  int result = 0;
+  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+    result = __lll_robust_lock_wait (futex);
+  return result;
+}
+#define lll_robust_mutex_lock(futex, id) \
+  __lll_robust_mutex_lock (&(futex), id)
 
 static inline void
 __attribute__ ((always_inline))
 __lll_mutex_cond_lock (int *futex)
 {
-  int val = atomic_compare_and_exchange_val_acq (futex, 2, 0);
+  int val = atomic_compare_and_exchange_val_24_acq (futex, 2, 0);
 
   if (__builtin_expect (val != 0, 0))
     __lll_lock_wait (futex);
 }
 #define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex))
 
+#define lll_robust_mutex_cond_lock(futex, id) \
+  __lll_robust_mutex_lock (&(futex), (id) | FUTEX_WAITERS)
+
 
 extern int __lll_timedlock_wait (int *futex, const struct timespec *)
      attribute_hidden;
-
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
+     attribute_hidden;
 
 static inline int
 __attribute__ ((always_inline))
 __lll_mutex_timedlock (int *futex, const struct timespec *abstime)
 {
-  int val = atomic_compare_and_exchange_val_acq (futex, 1, 0);
+  int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);
   int result = 0;
 
   if (__builtin_expect (val != 0, 0))
@@ -142,18 +194,39 @@ __lll_mutex_timedlock (int *futex, const struct timespec *abstime)
 #define lll_mutex_timedlock(futex, abstime) \
   __lll_mutex_timedlock (&(futex), abstime)
 
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
+			      int id)
+{
+  int result = 0;
+  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+    result = __lll_robust_timedlock_wait (futex, abstime);
+  return result;
+}
+#define lll_robust_mutex_timedlock(futex, abstime, id) \
+  __lll_robust_mutex_timedlock (&(futex), abstime, id)
+
 #define lll_mutex_unlock(lock) \
   ((void) ({								      \
     int *__futex = &(lock);						      \
-    int __val = atomic_exchange_rel (__futex, 0);			      \
+    int __val = atomic_exchange_24_rel (__futex, 0);			      \
     if (__builtin_expect (__val > 1, 0))				      \
       lll_futex_wake (__futex, 1);					      \
   }))
 
+#define lll_robust_mutex_unlock(lock) \
+  ((void) ({								      \
+    int *__futex = &(lock);						      \
+    int __val = atomic_exchange_rel (__futex, 0);			      \
+    if (__builtin_expect (__val & FUTEX_WAITERS, 0))			      \
+      lll_futex_wake (__futex, 1);					      \
+  }))
+
 #define lll_mutex_unlock_force(lock) \
   ((void) ({								      \
     int *__futex = &(lock);						      \
-    (void) atomic_exchange_rel (__futex, 0);				      \
+    (void) atomic_exchange_24_rel (__futex, 0);				      \
     lll_futex_wake (__futex, 1);					      \
   }))
 
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
index da6197c00d..675a997e97 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/sparc/sparc32/clone.S>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c
new file mode 100644
index 0000000000..a7611d6a88
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c
@@ -0,0 +1,131 @@
+/* low level locking for pthread library.  SPARC version.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+
+
+void
+__lll_lock_wait (int *futex)
+{
+  do
+    {
+      int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1);
+      if (oldval != 0)
+	lll_futex_wait (futex, 2);
+    }
+  while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0);
+}
+
+
+int
+__lll_timedlock_wait (int *futex, const struct timespec *abstime)
+{
+  /* Reject invalid timeouts.  */
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    return EINVAL;
+
+  do
+    {
+      struct timeval tv;
+      struct timespec rt;
+
+      /* Get the current time.  */
+      (void) __gettimeofday (&tv, NULL);
+
+      /* Compute relative timeout.  */
+      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+      if (rt.tv_nsec < 0)
+	{
+	  rt.tv_nsec += 1000000000;
+	  --rt.tv_sec;
+	}
+
+      /* Already timed out?  */
+      if (rt.tv_sec < 0)
+	return ETIMEDOUT;
+
+      /* Wait.  */
+      int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1);
+      if (oldval != 0)
+	lll_futex_timed_wait (futex, 2, &rt);
+    }
+  while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0);
+
+  return 0;
+}
+
+
+/* These don't get included in libc.so  */
+#ifdef IS_IN_libpthread
+int
+lll_unlock_wake_cb (int *futex)
+{
+  int val = atomic_exchange_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;
+
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    return EINVAL;
+
+  /* Repeat until thread terminated.  */
+  while ((tid = *tidp) != 0)
+    {
+      struct timeval tv;
+      struct timespec rt;
+
+      /* Get the current time.  */
+      (void) __gettimeofday (&tv, NULL);
+
+      /* Compute relative timeout.  */
+      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+      if (rt.tv_nsec < 0)
+	{
+	  rt.tv_nsec += 1000000000;
+	  --rt.tv_sec;
+	}
+
+      /* Already timed out?  */
+      if (rt.tv_sec < 0)
+	return ETIMEDOUT;
+
+      /* Wait until thread terminates.  */
+      if (lll_futex_timed_wait (tidp, tid, &rt) == -ETIMEDOUT)
+	return ETIMEDOUT;
+    }
+
+  return 0;
+}
+
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S
index 55229c9e66..fb01242b53 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S
@@ -21,6 +21,7 @@
 #include <tcb-offsets.h>
 
 	.text
+	.globl		__syscall_error
 ENTRY(__vfork)
 	ld	[%g7 + PID], %o5
 	sub	%g0, %o5, %o4
@@ -28,15 +29,17 @@ ENTRY(__vfork)
 
 	LOADSYSCALL(vfork)
 	ta	0x10
-	bcs,a	__syscall_error_handler
-	 st	%o5, [%g7 + PID]
-	SYSCALL_ERROR_HANDLER
-	sub	%o1, 1, %o1
+	bcc	2f
+	 mov	%o7, %g1
+	st	%o5, [%g7 + PID]
+	call	__syscall_error
+	 mov	%g1, %o7
+2:	sub	%o1, 1, %o1
 	andcc	%o0, %o1, %o0
 	bne,a	1f
 	 st	%o5, [%g7 + PID]
 1:	retl
 	 nop
+END(__vfork)
 
-PSEUDO_END (__vfork)
 weak_alias (__vfork, vfork)
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_init.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_init.c
new file mode 100644
index 0000000000..bbd08d0041
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_init.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 2002, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+struct sparc_pthread_barrier
+{
+  struct pthread_barrier b;
+  unsigned char left_lock;
+  unsigned char pshared;
+};
+
+int
+pthread_barrier_init (barrier, attr, count)
+     pthread_barrier_t *barrier;
+     const pthread_barrierattr_t *attr;
+     unsigned int count;
+{
+  struct sparc_pthread_barrier *ibarrier;
+
+  if (__builtin_expect (count == 0, 0))
+    return EINVAL;
+
+  struct pthread_barrierattr *iattr = (struct pthread_barrierattr *) attr;
+  if (iattr != NULL)
+    {
+      if (iattr->pshared != PTHREAD_PROCESS_PRIVATE
+	  && __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0))
+	/* Invalid attribute.  */
+	return EINVAL;
+    }
+
+  ibarrier = (struct sparc_pthread_barrier *) barrier;
+
+  /* Initialize the individual fields.  */
+  ibarrier->b.lock = LLL_LOCK_INITIALIZER;
+  ibarrier->b.left = count;
+  ibarrier->b.init_count = count;
+  ibarrier->b.curr_event = 0;
+  ibarrier->left_lock = 0;
+  ibarrier->pshared = (iattr && iattr->pshared == PTHREAD_PROCESS_SHARED);
+
+  return 0;
+}
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
new file mode 100644
index 0000000000..4dfd11dcbe
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <pthreadP.h>
+
+struct sparc_pthread_barrier
+{
+  struct pthread_barrier b;
+  unsigned char left_lock;
+  unsigned char pshared;
+};
+
+/* Wait on barrier.  */
+int
+pthread_barrier_wait (barrier)
+     pthread_barrier_t *barrier;
+{
+  struct sparc_pthread_barrier *ibarrier
+    = (struct sparc_pthread_barrier *) barrier;
+  int result = 0;
+
+  /* Make sure we are alone.  */
+  lll_lock (ibarrier->b.lock);
+
+  /* One more arrival.  */
+  --ibarrier->b.left;
+
+  /* Are these all?  */
+  if (ibarrier->b.left == 0)
+    {
+      /* Yes. Increment the event counter to avoid invalid wake-ups and
+	 tell the current waiters that it is their turn.  */
+      ++ibarrier->b.curr_event;
+
+      /* Wake up everybody.  */
+      lll_futex_wake (&ibarrier->b.curr_event, INT_MAX);
+
+      /* This is the thread which finished the serialization.  */
+      result = PTHREAD_BARRIER_SERIAL_THREAD;
+    }
+  else
+    {
+      /* The number of the event we are waiting for.  The barrier's event
+	 number must be bumped before we continue.  */
+      unsigned int event = ibarrier->b.curr_event;
+
+      /* Before suspending, make the barrier available to others.  */
+      lll_unlock (ibarrier->b.lock);
+
+      /* Wait for the event counter of the barrier to change.  */
+      do
+	lll_futex_wait (&ibarrier->b.curr_event, event);
+      while (event == ibarrier->b.curr_event);
+    }
+
+  /* Make sure the init_count is stored locally or in a register.  */
+  unsigned int init_count = ibarrier->b.init_count;
+
+  /* If this was the last woken thread, unlock.  */
+  if (__atomic_is_v9 || ibarrier->pshared == 0)
+    {
+      if (atomic_increment_val (&ibarrier->b.left) == init_count)
+	/* We are done.  */
+	lll_unlock (ibarrier->b.lock);
+    }
+  else
+    {
+      unsigned int left;
+      /* Slightly more complicated.  On pre-v9 CPUs, atomic_increment_val
+	 is only atomic for threads within the same process, not for
+	 multiple processes.  */
+      __sparc32_atomic_do_lock24 (&ibarrier->left_lock);
+      left = ++ibarrier->b.left;
+      __sparc32_atomic_do_unlock24 (&ibarrier->left_lock);
+      if (left == init_count)
+        /* We are done.  */
+        lll_unlock (ibarrier->b.lock);
+    }
+
+  return result;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_init.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_init.c
new file mode 100644
index 0000000000..dffd8c7efa
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_init.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 2002, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <semaphore.h>
+#include <lowlevellock.h>
+#include <shlib-compat.h>
+#include "semaphoreP.h"
+
+struct sparc_sem
+{
+  struct sem s;
+  unsigned char lock;
+};
+
+
+int
+__new_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 sparc_sem *isem = (struct sparc_sem *) sem;
+
+  /* Use the value the user provided.  */
+  isem->s.count = value;
+
+  isem->lock = 0;
+
+  /* We can completely ignore the PSHARED parameter since inter-process
+     use needs no special preparation.  */
+
+  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)
+compat_symbol (libpthread, __old_sem_init, sem_init, GLIBC_2_0);
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c
new file mode 100644
index 0000000000..be1cc60b11
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c
@@ -0,0 +1,54 @@
+/* sem_post -- post to a POSIX semaphore.  SPARC version.
+   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.
+
+   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 <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+#include <shlib-compat.h>
+
+int
+__new_sem_post (sem_t *sem)
+{
+  int *futex = (int *) sem, nr;
+
+  if (__atomic_is_v9)
+    nr = atomic_increment_val (futex);
+  else
+    {
+      __sparc32_atomic_do_lock24 (futex + 1);
+      nr = ++*futex;
+      __sparc32_atomic_do_unlock24 (futex + 1);
+    }
+  int err = lll_futex_wake (futex, nr);
+  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)
+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/sparc/sparc32/sem_timedwait.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
new file mode 100644
index 0000000000..efcc9e9aa8
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
@@ -0,0 +1,117 @@
+/* sem_timedwait -- wait on a semaphore.  SPARC version.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+#include <pthreadP.h>
+#include <shlib-compat.h>
+
+
+int
+sem_timedwait (sem_t *sem, const struct timespec *abstime)
+{
+  /* First check for cancellation.  */
+  CANCELLATION_P (THREAD_SELF);
+
+  int *futex = (int *) sem;
+  int val;
+  int err;
+
+  if (*futex > 0)
+    {
+      if (__atomic_is_v9)
+	val = atomic_decrement_if_positive (futex);
+      else
+	{
+	  __sparc32_atomic_do_lock24 (futex + 1);
+	  val = *futex;
+	  if (val > 0)
+	    *futex = val - 1;
+	  __sparc32_atomic_do_unlock24 (futex + 1);
+	}
+      if (val > 0)
+	return 0;
+    }
+
+  err = -EINVAL;
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    goto error_return;
+
+  do
+    {
+      struct timeval tv;
+      struct timespec rt;
+      int sec, nsec;
+
+      /* Get the current time.  */
+      __gettimeofday (&tv, NULL);
+
+      /* Compute relative timeout.  */
+      sec = abstime->tv_sec - tv.tv_sec;
+      nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+      if (nsec < 0)
+	{
+	  nsec += 1000000000;
+	  --sec;
+	}
+
+      /* Already timed out?  */
+      err = -ETIMEDOUT;
+      if (sec < 0)
+	goto error_return;
+
+      /* Do wait.  */
+      rt.tv_sec = sec;
+      rt.tv_nsec = nsec;
+
+      /* Enable asynchronous cancellation.  Required by the standard.  */
+      int oldtype = __pthread_enable_asynccancel ();
+
+      err = lll_futex_timed_wait (futex, 0, &rt);
+
+      /* Disable asynchronous cancellation.  */
+      __pthread_disable_asynccancel (oldtype);
+
+      if (err != 0 && err != -EWOULDBLOCK)
+	goto error_return;
+
+      if (__atomic_is_v9)
+	val = atomic_decrement_if_positive (futex);
+      else
+	{
+	  __sparc32_atomic_do_lock24 (futex + 1);
+	  val = *futex;
+	  if (val > 0)
+	    *futex = val - 1;
+	  __sparc32_atomic_do_unlock24 (futex + 1);
+	}
+    }
+  while (val <= 0);
+
+  return 0;
+
+ error_return:
+  __set_errno (-err);
+  return -1;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c
new file mode 100644
index 0000000000..429494e257
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c
@@ -0,0 +1,59 @@
+/* sem_trywait -- wait on a semaphore.  SPARC version.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+#include <shlib-compat.h>
+
+
+int
+__new_sem_trywait (sem_t *sem)
+{
+  int *futex = (int *) sem;
+  int val;
+
+  if (*futex > 0)
+    {
+      if (__atomic_is_v9)
+	val = atomic_decrement_if_positive (futex);
+      else
+	{
+	  __sparc32_atomic_do_lock24 (futex + 1);
+	  val = *futex;
+	  if (val > 0)
+	    *futex = val - 1;
+	  __sparc32_atomic_do_unlock24 (futex + 1);
+	}
+      if (val > 0)
+	return 0;
+    }
+
+  __set_errno (EAGAIN);
+  return -1;
+}
+versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1);
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
+strong_alias (__new_sem_trywait, __old_sem_trywait)
+compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0);
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
new file mode 100644
index 0000000000..d9fcdcd4ee
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
@@ -0,0 +1,74 @@
+/* sem_wait -- wait on a semaphore.  SPARC version.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+#include <pthreadP.h>
+#include <shlib-compat.h>
+
+
+int
+__new_sem_wait (sem_t *sem)
+{
+  /* First check for cancellation.  */
+  CANCELLATION_P (THREAD_SELF);
+
+  int *futex = (int *) sem;
+  int err;
+
+  do
+    {
+      int val;
+      if (__atomic_is_v9)
+	val = atomic_decrement_if_positive (futex);
+      else
+	{
+	  __sparc32_atomic_do_lock24 (futex + 1);
+	  val = *futex;
+	  if (val > 0)
+	    *futex = val - 1;
+	  __sparc32_atomic_do_unlock24 (futex + 1);
+	}
+      if (val > 0)
+	return 0;
+
+      /* Enable asynchronous cancellation.  Required by the standard.  */
+      int oldtype = __pthread_enable_asynccancel ();
+
+      err = lll_futex_wait (futex, 0);
+
+      /* Disable asynchronous cancellation.  */
+      __pthread_disable_asynccancel (oldtype);
+    }
+  while (err == 0 || err == -EWOULDBLOCK);
+
+  __set_errno (-err);
+  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/sparc/sparc32/sparcv9/pthread_barrier_init.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_init.c
new file mode 100644
index 0000000000..b2b842336e
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_init.c
@@ -0,0 +1 @@
+#include "../../../../../../../pthread_barrier_init.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c
new file mode 100644
index 0000000000..7613863bba
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c
@@ -0,0 +1 @@
+#include "../../../../../../pthread/pthread_barrier_wait.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_init.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_init.c
new file mode 100644
index 0000000000..b2ebc4cbb5
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_init.c
@@ -0,0 +1 @@
+#include "../../../../../../../sem_init.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c
new file mode 100644
index 0000000000..4a6eac88f5
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c
@@ -0,0 +1 @@
+#include "../../../sem_post.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c
new file mode 100644
index 0000000000..b2526db02c
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c
@@ -0,0 +1 @@
+#include "../../../sem_timedwait.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_trywait.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_trywait.c
new file mode 100644
index 0000000000..aae46f725e
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_trywait.c
@@ -0,0 +1 @@
+#include "../../../sem_trywait.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c
new file mode 100644
index 0000000000..31157f636f
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c
@@ -0,0 +1 @@
+#include "../../../sem_wait.c"
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 5edf4b3772..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.
 
@@ -26,55 +26,48 @@
 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
 
 # undef PSEUDO
-# define PSEUDO(name, syscall_name, args)				      \
-	.text;								      \
-ENTRY(name)								      \
-	ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;			      \
-	cmp %g1, 0;							      \
-	bne 1f;								      \
-.type	__##syscall_name##_nocancel,@function;				      \
-.globl	__##syscall_name##_nocancel;					      \
-__##syscall_name##_nocancel:						      \
-	 mov SYS_ify(syscall_name), %g1;				      \
-	ta 0x10;							      \
-	bcs __syscall_error_handler;					      \
-	 nop;								      \
-.size	__##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	      \
-	.subsection 2;							      \
-	cfi_startproc;							      \
-1:	save %sp, -96, %sp;						      \
-	cfi_def_cfa_register (%fp);					      \
-	cfi_window_save;						      \
-	cfi_register (%o7, %i7);					      \
-	CENABLE;							      \
-	 nop;								      \
-	mov %o0, %l0;							      \
-	COPY_ARGS_##args						      \
-	mov SYS_ify(syscall_name), %g1;					      \
-	ta 0x10;							      \
-	bcs __syscall_error_handler2;					      \
-	 mov %o0, %l1;							      \
-	CDISABLE;							      \
-	 mov %l0, %o0;							      \
-	jmpl %i7 + 8, %g0;						      \
-	 restore %g0, %l1, %o0;						      \
-	cfi_endproc;							      \
-	.previous;							      \
-	SYSCALL_ERROR_HANDLER						      \
-	SYSCALL_ERROR_HANDLER2
+# define PSEUDO(name, syscall_name, args)	\
+	.text;					\
+	.globl		__syscall_error;	\
+ENTRY(name)					\
+	ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\
+	cmp %g1, 0;				\
+	bne 1f;					\
+.type	__##syscall_name##_nocancel,@function;	\
+.globl	__##syscall_name##_nocancel;		\
+__##syscall_name##_nocancel:			\
+	 mov SYS_ify(syscall_name), %g1;	\
+	ta 0x10;				\
+	bcc 8f;					\
+	 mov %o7, %g1;				\
+	call __syscall_error;			\
+	 mov %g1, %o7;				\
+8:	jmpl %o7 + 8, %g0;			\
+	 nop;					\
+.size	__##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\
+1:	save %sp, -96, %sp;			\
+	cfi_def_cfa_register(%fp);		\
+	cfi_window_save;			\
+	cfi_register(%o7, %i7);			\
+	CENABLE;				\
+	 nop;					\
+	mov %o0, %l0;				\
+	COPY_ARGS_##args			\
+	mov SYS_ify(syscall_name), %g1;		\
+	ta 0x10;				\
+	bcc 1f;					\
+	 mov %o0, %l1;				\
+	CDISABLE;				\
+	 mov %l0, %o0;				\
+	call __syscall_error;			\
+	 mov %l1, %o0;				\
+	b 2f;					\
+	 mov -1, %l1;				\
+1:	CDISABLE;				\
+	 mov %l0, %o0;				\
+2:	jmpl %i7 + 8, %g0;			\
+	 restore %g0, %l1, %o0;
 
-#define SYSCALL_ERROR_HANDLER2						      \
-SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2)			      \
-	.global __errno_location;					      \
-        .type   __errno_location,@function;				      \
-	CDISABLE;							      \
-	 mov	%l0, %o0;						      \
-	call	__errno_location;					      \
-	 nop;								      \
-	st	%l1, [%o0];						      \
-	jmpl	%i7 + 8, %g0;						      \
-	 restore %g0, -1, %o0;						      \
-	.previous;
 
 # ifdef IS_IN_libpthread
 #  define CENABLE	call __pthread_enable_asynccancel
@@ -111,3 +104,9 @@ SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2)			      \
 # 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/vfork.S b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
index 7229608142..a8e4dd5a43 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
@@ -21,6 +21,7 @@
 #include <tcb-offsets.h>
 
 	.text
+	.globl		__syscall_error
 ENTRY(__vfork)
 	ld	[%g7 + PID], %o5
 	cmp	%o5, 0
@@ -31,16 +32,18 @@ ENTRY(__vfork)
 
 	LOADSYSCALL(vfork)
 	ta	0x10
-	bcs,a	__syscall_error_handler
-	 st	%o5, [%g7 + PID]
-	SYSCALL_ERROR_HANDLER
-	sub	%o1, 1, %o1
+	bcc	2f
+	 mov	%o7, %g1
+	st	%o5, [%g7 + PID]
+	call	__syscall_error
+	 mov	%g1, %o7
+2:	sub	%o1, 1, %o1
 	andcc	%o0, %o1, %o0
 	bne,a	1f
 	 st	%o5, [%g7 + PID]
 1:	retl
 	 nop
+END(__vfork)
 
-PSEUDO_END (__vfork)
 libc_hidden_def (__vfork)
 weak_alias (__vfork, vfork)
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
new file mode 100644
index 0000000000..675a997e97
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
@@ -0,0 +1,9 @@
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S b/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S
index e9018b2e99..8941043c3a 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S
@@ -21,6 +21,7 @@
 #include <tcb-offsets.h>
 
 	.text
+	.globl	__syscall_error
 ENTRY(__vfork)
 	ld	[%g7 + PID], %o5
 	sub	%g0, %o5, %o4
@@ -28,15 +29,17 @@ ENTRY(__vfork)
 
 	LOADSYSCALL(vfork)
 	ta	0x6d
-	bcs,a,pn %xcc, __syscall_error_handler
-	 st	%o5, [%g7 + PID]
-	SYSCALL_ERROR_HANDLER
-	sub	%o1, 1, %o1
+	bcc,pt	%xcc, 2f
+	 mov	%o7, %g1
+	st	%o5, [%g7 + PID]
+	call	__syscall_error
+	 mov	%g1, %o7
+2:	sub	%o1, 1, %o1
 	andcc	%o0, %o1, %o0
 	bne,a,pt %icc, 1f
 	 st	%o5, [%g7 + PID]
 1:	retl
 	 nop
+END(__vfork)
 
-PSEUDO_END (__vfork)
 weak_alias (__vfork, vfork)
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 d8c65aeffd..2c76d01715 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/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.
 
@@ -26,49 +26,46 @@
 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
 
 # undef PSEUDO
-# define PSEUDO(name, syscall_name, args)				      \
-	.text;								      \
-ENTRY(name)								      \
-	ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;			      \
-	brnz,pn %g1, 1f;						      \
-.type	__##syscall_name##_nocancel,@function;				      \
-.globl	__##syscall_name##_nocancel;					      \
-__##syscall_name##_nocancel:						      \
-	 mov SYS_ify(syscall_name), %g1;				      \
-	ta 0x6d;							      \
-	bcs,pn %xcc, __syscall_error_handler;				      \
-	 nop;								      \
-.size	__##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	      \
-	.subsection 2;							      \
-1:	save %sp, -192, %sp;						      \
-	CENABLE;							      \
-	 nop;								      \
-	mov %o0, %l0;							      \
-	COPY_ARGS_##args						      \
-	mov SYS_ify(syscall_name), %g1;					      \
-	ta 0x6d;							      \
-	bcs,pn %xcc, __syscall_error_handler2;				      \
-	 mov %o0, %l1;							      \
-	CDISABLE;							      \
-	 mov %l0, %o0;							      \
-	jmpl %i7 + 8, %g0;						      \
-	 restore %g0, %l1, %o0;						      \
-	.previous;							      \
-	SYSCALL_ERROR_HANDLER						      \
-	SYSCALL_ERROR_HANDLER2
-
-#define SYSCALL_ERROR_HANDLER2						      \
-SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2)			      \
-	.global __errno_location;					      \
-        .type   __errno_location,@function;				      \
-	CDISABLE;							      \
-	 mov	%l0, %o0;						      \
-	call	__errno_location;					      \
-	 nop;								      \
-	st	%l1, [%o0];						      \
-	jmpl	%i7 + 8, %g0;						      \
-	 restore %g0, -1, %o0;						      \
-	.previous;
+# define PSEUDO(name, syscall_name, args)	\
+	.text;					\
+	.globl		__syscall_error;	\
+ENTRY(name)					\
+	ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\
+	brnz,pn %g1, 1f;			\
+.type	__##syscall_name##_nocancel,@function;	\
+.globl	__##syscall_name##_nocancel;		\
+__##syscall_name##_nocancel:			\
+	 mov SYS_ify(syscall_name), %g1;	\
+	ta 0x6d;				\
+	bcc,pt %xcc, 8f;			\
+	 mov %o7, %g1;				\
+	call __syscall_error;			\
+	 mov %g1, %o7;				\
+8:	jmpl %o7 + 8, %g0;			\
+	 nop;					\
+.size	__##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\
+1:	save %sp, -192, %sp;			\
+	cfi_def_cfa_register(%fp);		\
+	cfi_window_save;			\
+	cfi_register(%o7, %i7);			\
+	CENABLE;				\
+	 nop;					\
+	mov %o0, %l0;				\
+	COPY_ARGS_##args			\
+	mov SYS_ify(syscall_name), %g1;		\
+	ta 0x6d;				\
+	bcc,pt %xcc, 1f;			\
+	 mov %o0, %l1;				\
+	CDISABLE;				\
+	 mov %l0, %o0;				\
+	call __syscall_error;			\
+	 mov %l1, %o0;				\
+	ba,pt %xcc, 2f;				\
+	 mov -1, %l1;				\
+1:	CDISABLE;				\
+	 mov %l0, %o0;				\
+2:	jmpl %i7 + 8, %g0;			\
+	 restore %g0, %l1, %o0;
 
 # ifdef IS_IN_libpthread
 #  define CENABLE	call __pthread_enable_asynccancel
@@ -105,3 +102,9 @@ SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2)			      \
 # 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/vfork.S b/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
index d6b2455d43..5597574304 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
@@ -21,6 +21,7 @@
 #include <tcb-offsets.h>
 
 	.text
+	.globl	__syscall_error
 ENTRY(__vfork)
 	ld	[%g7 + PID], %o5
 	sethi	%hi(0x80000000), %o3
@@ -31,16 +32,18 @@ ENTRY(__vfork)
 
 	LOADSYSCALL(vfork)
 	ta	0x6d
-	bcs,a,pn %xcc, __syscall_error_handler
-	 st	%o5, [%g7 + PID]
-	SYSCALL_ERROR_HANDLER
-	sub	%o1, 1, %o1
+	bcc,pt	%xcc, 2f
+	 mov	%o7, %g1
+	st	%o5, [%g7 + PID]
+	call	__syscall_error
+	 mov	%g1, %o7
+2:	sub	%o1, 1, %o1
 	andcc	%o0, %o1, %o0
 	bne,a,pt %icc, 1f
 	 st	%o5, [%g7 + PID]
 1:	retl
 	 nop
+END(__vfork)
 
-PSEUDO_END (__vfork)
 libc_hidden_def (__vfork)
 weak_alias (__vfork, vfork)
diff --git a/nptl/sysdeps/unix/sysv/linux/timer_create.c b/nptl/sysdeps/unix/sysv/linux/timer_create.c
index ca6ff6c7ef..5e99513950 100644
--- a/nptl/sysdeps/unix/sysv/linux/timer_create.c
+++ b/nptl/sysdeps/unix/sysv/linux/timer_create.c
@@ -28,6 +28,7 @@
 #include <internaltypes.h>
 #include <nptl/pthreadP.h>
 #include "kernel-posix-timers.h"
+#include "kernel-posix-cpu-timers.h"
 
 
 #ifdef __NR_timer_create
@@ -58,6 +59,12 @@ timer_create (clock_id, evp, timerid)
   if  (__no_posix_timers >= 0)
 # endif
     {
+      clockid_t syscall_clockid = (clock_id == CLOCK_PROCESS_CPUTIME_ID
+				   ? MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED)
+				   : clock_id == CLOCK_THREAD_CPUTIME_ID
+				   ? MAKE_THREAD_CPUCLOCK (0, CPUCLOCK_SCHED)
+				   : clock_id);
+
       /* If the user wants notification via a thread we need to handle
 	 this special.  */
       if (evp == NULL
@@ -88,7 +95,7 @@ timer_create (clock_id, evp, timerid)
 	    }
 
 	  kernel_timer_t ktimerid;
-	  int retval = INLINE_SYSCALL (timer_create, 3, clock_id, evp,
+	  int retval = INLINE_SYSCALL (timer_create, 3, syscall_clockid, evp,
 				       &ktimerid);
 
 # ifndef __ASSUME_POSIX_TIMERS
@@ -196,8 +203,8 @@ timer_create (clock_id, evp, timerid)
 	      /* Create the timer.  */
 	      INTERNAL_SYSCALL_DECL (err);
 	      int res;
-	      res = INTERNAL_SYSCALL (timer_create, err, 3, clock_id, &sev,
-				      &newp->ktimerid);
+	      res = INTERNAL_SYSCALL (timer_create, err, 3,
+				      syscall_clockid, &sev, &newp->ktimerid);
 	      if (! INTERNAL_SYSCALL_ERROR_P (res, err))
 		{
 		  *timerid = (timer_t) newp;
diff --git a/nptl/sysdeps/unix/sysv/linux/timer_routines.c b/nptl/sysdeps/unix/sysv/linux/timer_routines.c
index 23c800f98e..a5eb442251 100644
--- a/nptl/sysdeps/unix/sysv/linux/timer_routines.c
+++ b/nptl/sysdeps/unix/sysv/linux/timer_routines.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -27,6 +27,13 @@
 #include "kernel-posix-timers.h"
 
 
+struct thread_start_data
+{
+  void (*thrfunc) (sigval_t);
+  sigval_t sival;
+};
+
+
 #ifdef __NR_timer_create
 /* Helper thread to call the user-provided function.  */
 static void *
@@ -40,10 +47,16 @@ timer_sigev_thread (void *arg)
   INTERNAL_SYSCALL_DECL (err);
   INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, NULL, _NSIG / 8);
 
-  struct timer *tk = (struct timer *) arg;
+  struct thread_start_data *td = (struct thread_start_data *) arg;
+
+  void (*thrfunc) (sigval_t) = td->thrfunc;
+  sigval_t sival = td->sival;
+
+  /* The TD object was allocated in timer_helper_thread.  */
+  free (td);
 
   /* Call the user-provided function.  */
-  tk->thrfunc (tk->sival);
+  thrfunc (sival);
 
   return NULL;
 }
@@ -53,10 +66,11 @@ timer_sigev_thread (void *arg)
 static void *
 timer_helper_thread (void *arg)
 {
-  /* Wait for the SIGTIMER signal and none else.  */
+  /* Wait for the SIGTIMER signal, allowing the setXid signal, and
+     none else.  */
   sigset_t ss;
   sigemptyset (&ss);
-  sigaddset (&ss, SIGTIMER);
+  __sigaddset (&ss, SIGTIMER);
 
   /* Endless loop of waiting for signals.  The loop is only ended when
      the thread is canceled.  */
@@ -81,10 +95,19 @@ timer_helper_thread (void *arg)
 	  if (si.si_code == SI_TIMER)
 	    {
 	      struct timer *tk = (struct timer *) si.si_ptr;
-
-	      /* That the signal we are waiting for.  */
-	      pthread_t th;
-	      (void) pthread_create (&th, &tk->attr, timer_sigev_thread, tk);
+	      struct thread_start_data *td = malloc (sizeof (*td));
+
+	      /* There is not much we can do if the allocation fails.  */
+	      if (td != NULL)
+		{
+		  /* That is the signal we are waiting for.  */
+		  td->thrfunc = tk->thrfunc;
+		  td->sival = tk->sival;
+
+		  pthread_t th;
+		  (void) pthread_create (&th, &tk->attr, timer_sigev_thread,
+					 td);
+		}
 	    }
 	  else if (si.si_code == SI_TKILL)
 	    /* The thread is canceled.  */
@@ -121,10 +144,11 @@ __start_helper_thread (void)
   (void) pthread_attr_init (&attr);
   (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
 
-  /* Block all signals in the helper thread.  To do this thoroughly we
-     temporarily have to block all signals here.  The helper can lose
-     wakeups if SIGCANCEL is not blocked throughout, but sigfillset omits
-     it.  So, we add it back explicitly here.  */
+  /* Block all signals in the helper thread but SIGSETXID.  To do this
+     thoroughly we temporarily have to block all signals here.  The
+     helper can lose wakeups if SIGCANCEL is not blocked throughout,
+     but sigfillset omits it SIGSETXID.  So, we add SIGCANCEL back
+     explicitly here.  */
   sigset_t ss;
   sigset_t oss;
   sigfillset (&ss);
diff --git a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c b/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
index 72c8d615eb..964f5b7094 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -19,7 +19,7 @@
 
 #include <errno.h>
 #include <stdlib.h>
-#include "fork.h"
+#include <fork.h>
 #include <atomic.h>
 
 
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 92fb08c951..693387a266 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 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 Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -57,11 +57,25 @@ typedef union
 } pthread_attr_t;
 
 
+#if __WORDSIZE == 64
+typedef struct __pthread_internal_list
+{
+  struct __pthread_internal_list *__prev;
+  struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+  struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+
 /* Data structures for mutex handling.  The structure of the attribute
    type is not exposed on purpose.  */
 typedef union
 {
-  struct
+  struct __pthread_mutex_s
   {
     int __lock;
     unsigned int __count;
@@ -72,10 +86,18 @@ typedef union
     /* KIND must stay at this position in the structure to maintain
        binary compatibility.  */
     int __kind;
-#if __WORDSIZE != 64
+#if __WORDSIZE == 64
+    int __spins;
+    __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV	1
+#else
     unsigned int __nusers;
+    __extension__ union
+    {
+      int __spins;
+      __pthread_slist_t __list;
+    };
 #endif
-    int __spins;
   } __data;
   char __size[__SIZEOF_PTHREAD_MUTEX_T];
   long int __align;
@@ -192,4 +214,9 @@ typedef union
 #endif
 
 
+#if __WORDSIZE == 32
+/* Extra attributes for the cleanup functions.  */
+# define __cleanup_fct_attribute __attribute__ ((__regparm__ (1)))
+#endif
+
 #endif	/* bits/pthreadtypes.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S b/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
index dfa6adb3e2..675a997e97 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/x86_64/clone.S>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
index d5c9345558..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 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.
 
@@ -43,17 +43,25 @@
 	.hidden	__lll_mutex_lock_wait
 	.align	16
 __lll_mutex_lock_wait:
+	cfi_startproc
 	pushq	%r10
+	cfi_adjust_cfa_offset(8)
 	pushq	%rdx
-
+	cfi_adjust_cfa_offset(8)
+	cfi_offset(%r10, -16)
+	cfi_offset(%rdx, -24)
 	xorq	%r10, %r10	/* No timeout.  */
 	movl	$2, %edx
-	movq	%r10, %rsi	/* movq $FUTEX_WAIT, %rsi */
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
 
 	cmpl	%edx, %eax	/* NB:	 %edx == 2 */
 	jne	2f
 
-1:	movq	$SYS_futex, %rax
+1:	movl	$SYS_futex, %eax
 	syscall
 
 2:	movl	%edx, %eax
@@ -63,8 +71,13 @@ __lll_mutex_lock_wait:
 	jnz	1b
 
 	popq	%rdx
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%rdx)
 	popq	%r10
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r10)
 	retq
+	cfi_endproc
 	.size	__lll_mutex_lock_wait,.-__lll_mutex_lock_wait
 
 
@@ -74,18 +87,30 @@ __lll_mutex_lock_wait:
 	.hidden	__lll_mutex_timedlock_wait
 	.align	16
 __lll_mutex_timedlock_wait:
+	cfi_startproc
 	/* Check for a valid timeout value.  */
 	cmpq	$1000000000, 8(%rdx)
 	jae	3f
 
 	pushq	%r8
+	cfi_adjust_cfa_offset(8)
 	pushq	%r9
+	cfi_adjust_cfa_offset(8)
 	pushq	%r12
+	cfi_adjust_cfa_offset(8)
 	pushq	%r13
+	cfi_adjust_cfa_offset(8)
 	pushq	%r14
+	cfi_adjust_cfa_offset(8)
+	cfi_offset(%r8, -16)
+	cfi_offset(%r9, -24)
+	cfi_offset(%r12, -32)
+	cfi_offset(%r13, -40)
+	cfi_offset(%r14, -48)
 
 	/* Stack frame for the timespec and timeval structs.  */
 	subq	$16, %rsp
+	cfi_adjust_cfa_offset(16)
 
 	movq	%rdi, %r12
 	movq	%rdx, %r13
@@ -93,7 +118,7 @@ __lll_mutex_timedlock_wait:
 1:
 	/* Get current time.  */
 	movq	%rsp, %rdi
-	xorq	%rsi, %rsi
+	xorl	%esi, %esi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
 	/* This is a regular function call, all caller-save registers
 	   might be clobbered.  */
@@ -101,7 +126,7 @@ __lll_mutex_timedlock_wait:
 
 	/* Compute relative timeout.  */
 	movq	8(%rsp), %rax
-	movq	$1000, %rdi
+	movl	$1000, %edi
 	mul	%rdi		/* Milli seconds to nano seconds.  */
 	movq	(%r13), %rdi
 	movq	8(%r13), %rsi
@@ -126,26 +151,50 @@ __lll_mutex_timedlock_wait:
 	je	8f
 
 	movq	%rsp, %r10
-	xorq	%rsi, %rsi	/* movq $FUTEX_WAIT, %rsi */
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
 	movq	%r12, %rdi
-	movq	$SYS_futex, %rax
+	movl	$SYS_futex, %eax
 	syscall
 	movq	%rax, %rcx
 
 8:				/* NB: %edx == 2 */
 	xorl	%eax, %eax
 	LOCK
-	cmpxchgl %edx, (%rdi)
+	cmpxchgl %edx, (%r12)
 	jnz	7f
 
 6:	addq	$16, %rsp
+	cfi_adjust_cfa_offset(-16)
 	popq	%r14
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r14)
 	popq	%r13
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r13)
 	popq	%r12
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r12)
 	popq	%r9
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r9)
 	popq	%r8
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r8)
 	retq
 
+3:	movl	$EINVAL, %eax
+	retq
+
+	cfi_adjust_cfa_offset(56)
+	cfi_offset(%r8, -16)
+	cfi_offset(%r9, -24)
+	cfi_offset(%r12, -32)
+	cfi_offset(%r13, -40)
+	cfi_offset(%r14, -48)
 	/* Check whether the time expired.  */
 7:	cmpq	$-ETIMEDOUT, %rcx
 	je	5f
@@ -157,11 +206,9 @@ __lll_mutex_timedlock_wait:
 	jz	6b
 	jmp	1b
 
-3:	movl	$EINVAL, %eax
-	retq
-
 5:	movl	$ETIMEDOUT, %eax
 	jmp	6b
+	cfi_endproc
 	.size	__lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
 #endif
 
@@ -191,18 +238,28 @@ lll_unlock_wake_cb:
 	.hidden	__lll_mutex_unlock_wake
 	.align	16
 __lll_mutex_unlock_wake:
+	cfi_startproc
 	pushq	%rsi
+	cfi_adjust_cfa_offset(8)
 	pushq	%rdx
+	cfi_adjust_cfa_offset(8)
+	cfi_offset(%rsi, -16)
+	cfi_offset(%rdx, -24)
 
 	movl	$0, (%rdi)
-	movq	$FUTEX_WAKE, %rsi
+	movl	$FUTEX_WAKE, %esi
 	movl	$1, %edx	/* Wake one thread.  */
-	movq	$SYS_futex, %rax
+	movl	$SYS_futex, %eax
 	syscall
 
 	popq	%rdx
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%rdx)
 	popq	%rsi
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%rsi)
 	retq
+	cfi_endproc
 	.size	__lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
 
 
@@ -222,13 +279,13 @@ __lll_timedwait_tid:
 
 	/* Get current time.  */
 2:	movq	%rsp, %rdi
-	xorq	%rsi, %rsi
+	xorl	%esi, %esi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
 	callq	*%rax
 
 	/* Compute relative timeout.  */
 	movq	8(%rsp), %rax
-	movq	$1000, %rdi
+	movl	$1000, %edi
 	mul	%rdi		/* Milli seconds to nano seconds.  */
 	movq	(%r13), %rdi
 	movq	8(%r13), %rsi
@@ -248,9 +305,13 @@ __lll_timedwait_tid:
 	jz	4f
 
 	movq	%rsp, %r10
-	xorq	%rsi, %rsi	/* movq $FUTEX_WAIT, %rsi */
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
 	movq	%r12, %rdi
-	movq	$SYS_futex, %rax
+	movl	$SYS_futex, %eax
 	syscall
 
 	cmpl	$0, (%rdi)
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index 40c2518af6..97085bf018 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.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 Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -35,6 +35,9 @@
 #define SYS_futex		202
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
 
 
 /* Initializer for compatibility lock.  */
@@ -46,17 +49,130 @@
 #define BUSY_WAIT_NOP          asm ("rep; nop")
 
 
+#define LLL_STUB_UNWIND_INFO_START \
+	".section	.eh_frame,\"a\",@progbits\n" 		\
+"7:\t"	".long	9f-8f	# Length of Common Information Entry\n" \
+"8:\t"	".long	0x0	# CIE Identifier Tag\n\t" 		\
+	".byte	0x1	# CIE Version\n\t" 			\
+	".ascii \"zR\\0\"	# CIE Augmentation\n\t" 	\
+	".uleb128 0x1	# CIE Code Alignment Factor\n\t" 	\
+	".sleb128 -8	# CIE Data Alignment Factor\n\t" 	\
+	".byte	0x10	# CIE RA Column\n\t" 			\
+	".uleb128 0x1	# Augmentation size\n\t" 		\
+	".byte	0x1b	# FDE Encoding (pcrel sdata4)\n\t" 	\
+	".byte	0x12	# DW_CFA_def_cfa_sf\n\t" 		\
+	".uleb128 0x7\n\t" 					\
+	".sleb128 16\n\t" 					\
+	".align 8\n" 						\
+"9:\t"	".long	23f-10f	# FDE Length\n" 			\
+"10:\t"	".long	10b-7b	# FDE CIE offset\n\t" 			\
+	".long	1b-.	# FDE initial location\n\t" 		\
+	".long	6b-1b	# FDE address range\n\t" 		\
+	".uleb128 0x0	# Augmentation size\n\t" 		\
+	".byte	0x16	# DW_CFA_val_expression\n\t" 		\
+	".uleb128 0x10\n\t" 					\
+	".uleb128 12f-11f\n" 					\
+"11:\t"	".byte	0x80	# DW_OP_breg16\n\t" 			\
+	".sleb128 4b-1b\n"
+#define LLL_STUB_UNWIND_INFO_END \
+	".byte	0x16	# DW_CFA_val_expression\n\t" 		\
+	".uleb128 0x10\n\t" 					\
+	".uleb128 14f-13f\n" 					\
+"13:\t"	".byte	0x80	# DW_OP_breg16\n\t" 			\
+	".sleb128 4b-2b\n" 					\
+"14:\t"	".byte	0x40 + (3b-2b) # DW_CFA_advance_loc\n\t" 	\
+	".byte	0x0e	# DW_CFA_def_cfa_offset\n\t" 		\
+	".uleb128 0\n\t" 					\
+	".byte	0x16	# DW_CFA_val_expression\n\t" 		\
+	".uleb128 0x10\n\t" 					\
+	".uleb128 16f-15f\n" 					\
+"15:\t"	".byte	0x80	# DW_OP_breg16\n\t" 			\
+	".sleb128 4b-3b\n" 					\
+"16:\t"	".byte	0x40 + (4b-3b-1) # DW_CFA_advance_loc\n\t" 	\
+	".byte	0x0e	# DW_CFA_def_cfa_offset\n\t" 		\
+	".uleb128 128\n\t" 					\
+	".byte	0x16	# DW_CFA_val_expression\n\t" 		\
+	".uleb128 0x10\n\t" 					\
+	".uleb128 20f-17f\n" 					\
+"17:\t"	".byte	0x80	# DW_OP_breg16\n\t" 			\
+	".sleb128 19f-18f\n\t" 					\
+	".byte	0x0d	# DW_OP_const4s\n" 			\
+"18:\t"	".4byte	4b-.\n\t" 					\
+	".byte	0x1c	# DW_OP_minus\n\t" 			\
+	".byte	0x0d	# DW_OP_const4s\n" 			\
+"19:\t"	".4byte	24f-.\n\t" 					\
+	".byte	0x22	# DW_OP_plus\n" 			\
+"20:\t"	".byte	0x40 + (5b-4b+1) # DW_CFA_advance_loc\n\t" 	\
+	".byte	0x13	# DW_CFA_def_cfa_offset_sf\n\t" 	\
+	".sleb128 16\n\t" 					\
+	".byte	0x16	# DW_CFA_val_expression\n\t" 		\
+	".uleb128 0x10\n\t" 					\
+	".uleb128 22f-21f\n" 					\
+"21:\t"	".byte	0x80	# DW_OP_breg16\n\t" 			\
+	".sleb128 4b-5b\n" 					\
+"22:\t"	".align 8\n" 						\
+"23:\t"	".previous\n"
+
+/* Unwind info for
+   1: leaq ..., %rdi
+   2: subq $128, %rsp
+   3: callq ...
+   4: addq $128, %rsp
+   5: jmp 24f
+   6:
+   snippet.  */
+#define LLL_STUB_UNWIND_INFO_5 \
+LLL_STUB_UNWIND_INFO_START					\
+"12:\t"	".byte	0x40 + (2b-1b) # DW_CFA_advance_loc\n\t" 	\
+LLL_STUB_UNWIND_INFO_END
+
+/* Unwind info for
+   1: leaq ..., %rdi
+   0: movq ..., %rdx
+   2: subq $128, %rsp
+   3: callq ...
+   4: addq $128, %rsp
+   5: jmp 24f
+   6:
+   snippet.  */
+#define LLL_STUB_UNWIND_INFO_6 \
+LLL_STUB_UNWIND_INFO_START					\
+"12:\t"	".byte	0x40 + (0b-1b) # DW_CFA_advance_loc\n\t" 	\
+	".byte	0x16	# DW_CFA_val_expression\n\t" 		\
+	".uleb128 0x10\n\t" 					\
+	".uleb128 26f-25f\n" 					\
+"25:\t"	".byte	0x80	# DW_OP_breg16\n\t" 			\
+	".sleb128 4b-0b\n" 					\
+"26:\t"	".byte	0x40 + (2b-0b) # DW_CFA_advance_loc\n\t" 	\
+LLL_STUB_UNWIND_INFO_END
+
+
 #define lll_futex_wait(futex, val) \
-  do {									      \
-    int __ignore;							      \
+  ({									      \
+    int __status;							      \
     register __typeof (val) _val asm ("edx") = (val);			      \
     __asm __volatile ("xorq %%r10, %%r10\n\t"				      \
 		      "syscall"						      \
-		      : "=a" (__ignore)					      \
+		      : "=a" (__status)					      \
 		      : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT),	      \
 			"d" (_val)					      \
 		      : "memory", "cc", "r10", "r11", "cx");		      \
-  } while (0)
+    __status;								      \
+  })
+
+
+#define lll_futex_timed_wait(futex, val, timeout)			      \
+  ({									      \
+    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),	      \
+		        "d" (_val), "r" (__to)				      \
+		      : "memory", "cc", "r11", "cx");			      \
+    __status;								      \
+  })
 
 
 #define lll_futex_wake(futex, nr) \
@@ -96,6 +212,16 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
      ret; })
 
 
+#define lll_robust_mutex_trylock(futex, id)				      \
+  ({ int ret;								      \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1"			      \
+		       : "=a" (ret), "=m" (futex)			      \
+		       : "r" (id), "m" (futex),				      \
+			 "0" (LLL_MUTEX_LOCK_INITIALIZER)		      \
+		       : "memory");					      \
+     ret; })
+
+
 #define lll_mutex_cond_trylock(futex) \
   ({ int ret;								      \
      __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1"			      \
@@ -110,51 +236,109 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
   (void) ({ int ignore1, ignore2, ignore3;				      \
 	    __asm __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t"		      \
 			      "jnz 1f\n\t"				      \
-			      ".subsection 1\n"				      \
-			      "1:\tleaq %2, %%rdi\n\t"			      \
-			      "subq $128, %%rsp\n\t"			      \
-			      "callq __lll_mutex_lock_wait\n\t"		      \
-			      "addq $128, %%rsp\n\t"			      \
-			      "jmp 2f\n\t"				      \
+			      ".subsection 1\n\t"			      \
+			      ".type  _L_mutex_lock_%=, @function\n"	      \
+			      "_L_mutex_lock_%=:\n"			      \
+			      "1:\tleaq %2, %%rdi\n"			      \
+			      "2:\tsubq $128, %%rsp\n"			      \
+			      "3:\tcallq __lll_mutex_lock_wait\n"	      \
+			      "4:\taddq $128, %%rsp\n"			      \
+			      "5:\tjmp 24f\n"				      \
+			      "6:\t.size _L_mutex_lock_%=, 6b-1b\n\t"	      \
 			      ".previous\n"				      \
-			      "2:"					      \
+			      LLL_STUB_UNWIND_INFO_5			      \
+			      "24:"					      \
 			      : "=S" (ignore1), "=&D" (ignore2), "=m" (futex),\
 				"=a" (ignore3)				      \
 			      : "0" (1), "m" (futex), "3" (0)		      \
 			      : "cx", "r11", "cc", "memory"); })
 
 
+#define lll_robust_mutex_lock(futex, id) \
+  ({ int result, ignore1, ignore2;					      \
+    __asm __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t"			      \
+		      "jnz 1f\n\t"					      \
+		      ".subsection 1\n\t"				      \
+		      ".type  _L_robust_mutex_lock_%=, @function\n"	      \
+		      "_L_robust_mutex_lock_%=:\n"			      \
+		      "1:\tleaq %2, %%rdi\n"				      \
+		      "2:\tsubq $128, %%rsp\n"				      \
+		      "3:\tcallq __lll_robust_mutex_lock_wait\n"	      \
+		      "4:\taddq $128, %%rsp\n"				      \
+		      "5:\tjmp 24f\n"					      \
+		      "6:\t.size _L_robust_mutex_lock_%=, 6b-1b\n\t"	      \
+		      ".previous\n"					      \
+		      LLL_STUB_UNWIND_INFO_5				      \
+		      "24:"						      \
+		      : "=S" (ignore1), "=&D" (ignore2), "=m" (futex),	      \
+			"=a" (result)					      \
+		      : "0" (id), "m" (futex), "3" (0)			      \
+		      : "cx", "r11", "cc", "memory");			      \
+    result; })
+
+
 #define lll_mutex_cond_lock(futex) \
   (void) ({ int ignore1, ignore2, ignore3;				      \
 	    __asm __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t"		      \
 			      "jnz 1f\n\t"				      \
-			      ".subsection 1\n"				      \
-			      "1:\tleaq %2, %%rdi\n\t"			      \
-			      "subq $128, %%rsp\n\t"			      \
-			      "callq __lll_mutex_lock_wait\n\t"		      \
-			      "addq $128, %%rsp\n\t"			      \
-			      "jmp 2f\n\t"				      \
+			      ".subsection 1\n\t"			      \
+			      ".type  _L_mutex_cond_lock_%=, @function\n"     \
+			      "_L_mutex_cond_lock_%=:\n"		      \
+			      "1:\tleaq %2, %%rdi\n"			      \
+			      "2:\tsubq $128, %%rsp\n"			      \
+			      "3:\tcallq __lll_mutex_lock_wait\n"	      \
+			      "4:\taddq $128, %%rsp\n"			      \
+			      "5:\tjmp 24f\n"				      \
+			      "6:\t.size _L_mutex_cond_lock_%=, 6b-1b\n\t"    \
 			      ".previous\n"				      \
-			      "2:"					      \
+			      LLL_STUB_UNWIND_INFO_5			      \
+			      "24:"					      \
 			      : "=S" (ignore1), "=&D" (ignore2), "=m" (futex),\
 				"=a" (ignore3)				      \
 			      : "0" (2), "m" (futex), "3" (0)		      \
 			      : "cx", "r11", "cc", "memory"); })
 
 
+#define lll_robust_mutex_cond_lock(futex, id) \
+  ({ int result, ignore1, ignore2;					      \
+    __asm __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t"			      \
+		      "jnz 1f\n\t"					      \
+		      ".subsection 1\n\t"				      \
+		      ".type  _L_robust_mutex_cond_lock_%=, @function\n"      \
+		      "_L_robust_mutex_cond_lock_%=:\n"			      \
+		      "1:\tleaq %2, %%rdi\n"				      \
+		      "2:\tsubq $128, %%rsp\n"				      \
+		      "3:\tcallq __lll_robust_mutex_lock_wait\n"	      \
+		      "4:\taddq $128, %%rsp\n"				      \
+		      "5:\tjmp 24f\n"					      \
+		      "6:\t.size _L_robust_mutex_cond_lock_%=, 6b-1b\n\t"     \
+		      ".previous\n"					      \
+		      LLL_STUB_UNWIND_INFO_5				      \
+		      "24:"						      \
+		      : "=S" (ignore1), "=&D" (ignore2), "=m" (futex),	      \
+			"=a" (result)					      \
+		      : "0" (id | FUTEX_WAITERS), "m" (futex), "3" (0)	      \
+		      : "cx", "r11", "cc", "memory");			      \
+    result; })
+
+
 #define lll_mutex_timedlock(futex, timeout) \
   ({ int result, ignore1, ignore2, ignore3;				      \
      __asm __volatile (LOCK_INSTR "cmpxchgl %2, %4\n\t"			      \
 		       "jnz 1f\n\t"					      \
-		       ".subsection 1\n"				      \
-		       "1:\tleaq %4, %%rdi\n\t"				      \
-		       "movq %8, %%rdx\n\t"				      \
-		       "subq $128, %%rsp\n\t"				      \
-		       "callq __lll_mutex_timedlock_wait\n\t"		      \
-		       "addq $128, %%rsp\n\t"				      \
-		       "jmp 2f\n\t"					      \
+		       ".subsection 1\n\t"				      \
+		       ".type  _L_mutex_timedlock_%=, @function\n"	      \
+		       "_L_mutex_timedlock_%=:\n"			      \
+		       "1:\tleaq %4, %%rdi\n"				      \
+		       "0:\tmovq %8, %%rdx\n"				      \
+		       "2:\tsubq $128, %%rsp\n"				      \
+		       "3:\tcallq __lll_mutex_timedlock_wait\n"		      \
+		       "4:\taddq $128, %%rsp\n"				      \
+		       "5:\tjmp 24f\n"					      \
+		       "6:\t.size _L_mutex_timedlock_%=, 6b-1b\n\t"	      \
 		       ".previous\n"					      \
-		       "2:"						      \
+		       LLL_STUB_UNWIND_INFO_6				      \
+		       "24:"						      \
 		       : "=a" (result), "=&D" (ignore1), "=S" (ignore2),      \
 			 "=&d" (ignore3), "=m" (futex)			      \
 		       : "0" (0), "2" (1), "m" (futex), "m" (timeout)	      \
@@ -162,23 +346,83 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
      result; })
 
 
+#define lll_robust_mutex_timedlock(futex, timeout, id) \
+  ({ int result, ignore1, ignore2, ignore3;				      \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %2, %4\n\t"			      \
+		       "jnz 1f\n\t"					      \
+		       ".subsection 1\n\t"				      \
+		       ".type  _L_robust_mutex_timedlock_%=, @function\n"     \
+		       "_L_robust_mutex_timedlock_%=:\n"		      \
+		       "1:\tleaq %4, %%rdi\n"				      \
+		       "0:\tmovq %8, %%rdx\n"				      \
+		       "2:\tsubq $128, %%rsp\n"				      \
+		       "3:\tcallq __lll_robust_mutex_timedlock_wait\n"	      \
+		       "4:\taddq $128, %%rsp\n"				      \
+		       "5:\tjmp 24f\n"					      \
+		       "6:\t.size _L_robust_mutex_timedlock_%=, 6b-1b\n\t"    \
+		       ".previous\n"					      \
+		       LLL_STUB_UNWIND_INFO_6				      \
+		       "24:"						      \
+		       : "=a" (result), "=&D" (ignore1), "=S" (ignore2),      \
+			 "=&d" (ignore3), "=m" (futex)			      \
+		       : "0" (0), "2" (id), "m" (futex), "m" (timeout)	      \
+		       : "memory", "cx", "cc", "r10", "r11");		      \
+     result; })
+
+
 #define lll_mutex_unlock(futex) \
   (void) ({ int ignore;							      \
             __asm __volatile (LOCK_INSTR "decl %0\n\t"			      \
 			      "jne 1f\n\t"				      \
-			      ".subsection 1\n"				      \
-			      "1:\tleaq %0, %%rdi\n\t"			      \
-			      "subq $128, %%rsp\n\t"			      \
-			      "callq __lll_mutex_unlock_wake\n\t"	      \
-			      "addq $128, %%rsp\n\t"			      \
-			      "jmp 2f\n\t"				      \
+			      ".subsection 1\n\t"			      \
+			      ".type  _L_mutex_unlock_%=, @function\n"	      \
+			      "_L_mutex_unlock_%=:\n"			      \
+			      "1:\tleaq %0, %%rdi\n"			      \
+			      "2:\tsubq $128, %%rsp\n"			      \
+			      "3:\tcallq __lll_mutex_unlock_wake\n"	      \
+			      "4:\taddq $128, %%rsp\n"			      \
+			      "5:\tjmp 24f\n"				      \
+			      "6:\t.size _L_mutex_unlock_%=, 6b-1b\n\t"	      \
 			      ".previous\n"				      \
-			      "2:"					      \
+			      LLL_STUB_UNWIND_INFO_5			      \
+			      "24:"					      \
 			      : "=m" (futex), "=&D" (ignore)		      \
 			      : "m" (futex)				      \
 			      : "ax", "cx", "r11", "cc", "memory"); })
 
 
+#define lll_robust_mutex_unlock(futex) \
+  (void) ({ int ignore;							      \
+	    __asm __volatile (LOCK_INSTR "andl %2, %0\n\t"		      \
+			      "jne 1f\n\t"				      \
+			      ".subsection 1\n\t"			      \
+			      ".type  _L_robust_mutex_unlock_%=, @function\n" \
+			      "_L_robust_mutex_unlock_%=:\n"		      \
+			      "1:\tleaq %0, %%rdi\n"			      \
+			      "2:\tsubq $128, %%rsp\n"			      \
+			      "3:\tcallq __lll_mutex_unlock_wake\n"	      \
+			      "4:\taddq $128, %%rsp\n"			      \
+			      "5:\tjmp 24f\n"				      \
+			      "6:\t.size _L_robust_mutex_unlock_%=, 6b-1b\n\t"\
+			      ".previous\n"				      \
+			      LLL_STUB_UNWIND_INFO_5			      \
+			      "24:"					      \
+			      : "=m" (futex), "=&D" (ignore)		      \
+			      : "i" (FUTEX_WAITERS), "m" (futex)	      \
+			      : "ax", "cx", "r11", "cc", "memory"); })
+
+
+#define lll_robust_mutex_dead(futex) \
+  (void) ({ int ignore;		     \
+	    __asm __volatile (LOCK_INSTR "orl %3, (%2)\n\t"		      \
+			      "syscall"					      \
+			      : "=m" (futex), "=a" (ignore)		      \
+			      : "D" (&(futex)), "i" (FUTEX_OWNER_DIED),	      \
+				"S" (FUTEX_WAKE), "1" (__NR_futex),	      \
+				"d" (1)					      \
+			      : "cx", "r11", "cc", "memory"); })
+
+
 #define lll_mutex_islocked(futex) \
   (futex != LLL_MUTEX_LOCK_INITIALIZER)
 
@@ -237,17 +481,21 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
 			      "je 0f\n\t"				      \
 			      "lock; cmpxchgl %0, %2\n\t"		      \
 			      "jnz 1f\n\t"				      \
-		  	      "jmp 2f\n"				      \
+		  	      "jmp 24f\n"				      \
 			      "0:\tcmpxchgl %0, %2\n\t"			      \
 			      "jnz 1f\n\t"				      \
-			      ".subsection 1\n"				      \
-			      "1:\tleaq %2, %%rdi\n\t"			      \
-			      "subq $128, %%rsp\n\t"			      \
-			      "callq __lll_mutex_lock_wait\n\t"		      \
-			      "addq $128, %%rsp\n\t"			      \
-			      "jmp 2f\n\t"				      \
+			      ".subsection 1\n\t"			      \
+			      ".type  _L_lock_%=, @function\n"		      \
+			      "_L_lock_%=:\n"				      \
+			      "1:\tleaq %2, %%rdi\n"			      \
+			      "2:\tsubq $128, %%rsp\n"			      \
+			      "3:\tcallq __lll_mutex_lock_wait\n"	      \
+			      "4:\taddq $128, %%rsp\n"			      \
+			      "5:\tjmp 24f\n"				      \
+			      "6:\t.size _L_lock_%=, 6b-1b\n\t"		      \
 			      ".previous\n"				      \
-			      "2:"					      \
+			      LLL_STUB_UNWIND_INFO_5			      \
+			      "24:"					      \
 			      : "=S" (ignore1), "=&D" (ignore2), "=m" (futex),\
 				"=a" (ignore3)				      \
 			      : "0" (1), "m" (futex), "3" (0)		      \
@@ -260,17 +508,21 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
 			      "je 0f\n\t"				      \
 			      "lock; decl %0\n\t"			      \
 			      "jne 1f\n\t"				      \
-		  	      "jmp 2f\n"				      \
+		  	      "jmp 24f\n"				      \
 			      "0:\tdecl %0\n\t"				      \
 			      "jne 1f\n\t"				      \
-			      ".subsection 1\n"				      \
-			      "1:\tleaq %0, %%rdi\n\t"			      \
-			      "subq $128, %%rsp\n\t"			      \
-			      "callq __lll_mutex_unlock_wake\n\t"	      \
-			      "addq $128, %%rsp\n\t"			      \
-			      "jmp 2f\n\t"				      \
+			      ".subsection 1\n\t"			      \
+			      ".type  _L_unlock_%=, @function\n"	      \
+			      "_L_unlock_%=:\n"				      \
+			      "1:\tleaq %0, %%rdi\n"			      \
+			      "2:\tsubq $128, %%rsp\n"			      \
+			      "3:\tcallq __lll_mutex_unlock_wake\n"	      \
+			      "4:\taddq $128, %%rsp\n"			      \
+			      "5:\tjmp 24f\n"				      \
+			      "6:\t.size _L_unlock_%=, 6b-1b\n\t"	      \
 			      ".previous\n"				      \
-			      "2:"					      \
+			      LLL_STUB_UNWIND_INFO_5			      \
+			      "24:"					      \
 			      : "=m" (futex), "=&D" (ignore)		      \
 			      : "m" (futex)				      \
 			      : "ax", "cx", "r11", "cc", "memory"); })
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
new file mode 100644
index 0000000000..69243950d7
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
@@ -0,0 +1,229 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevelrobustlock.h>
+
+	.text
+
+#ifndef LOCK
+# ifdef UP
+#  define LOCK
+# else
+#  define LOCK lock
+# endif
+#endif
+
+#define SYS_futex		202
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_WAITERS		0x80000000
+#define FUTEX_OWNER_DIED	0x40000000
+
+/* For the calculation see asm/vsyscall.h.  */
+#define VSYSCALL_ADDR_vgettimeofday	0xffffffffff600000
+
+
+	.globl	__lll_robust_mutex_lock_wait
+	.type	__lll_robust_mutex_lock_wait,@function
+	.hidden	__lll_robust_mutex_lock_wait
+	.align	16
+__lll_robust_mutex_lock_wait:
+	cfi_startproc
+	pushq	%r10
+	cfi_adjust_cfa_offset(8)
+	pushq	%rdx
+	cfi_adjust_cfa_offset(8)
+	cfi_offset(%r10, -16)
+	cfi_offset(%rdx, -24)
+
+	xorq	%r10, %r10	/* No timeout.  */
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
+
+4:	movl	%eax, %edx
+	orl	$FUTEX_WAITERS, %edx
+
+	testl	$FUTEX_OWNER_DIED, %eax
+	jnz	3f
+
+	cmpl	%edx, %eax
+	je	1f
+
+	LOCK
+	cmpxchgl %edx, (%rdi)
+	jnz	2f
+
+1:	movl	$SYS_futex, %eax
+	syscall
+
+	movl	(%rdi), %eax
+
+2:	testl	%eax, %eax
+	jne	4b
+
+	movl	%fs:TID, %edx
+	orl	$FUTEX_WAITERS, %edx
+	LOCK
+	cmpxchgl %edx, (%rdi)
+	jnz	4b
+	/* NB:	 %rax == 0 */
+
+3:	popq	%rdx
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%rdx)
+	popq	%r10
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r10)
+	retq
+	cfi_endproc
+	.size	__lll_robust_mutex_lock_wait,.-__lll_robust_mutex_lock_wait
+
+
+	.globl	__lll_robust_mutex_timedlock_wait
+	.type	__lll_robust_mutex_timedlock_wait,@function
+	.hidden	__lll_robust_mutex_timedlock_wait
+	.align	16
+__lll_robust_mutex_timedlock_wait:
+	cfi_startproc
+	/* Check for a valid timeout value.  */
+	cmpq	$1000000000, 8(%rdx)
+	jae	3f
+
+	pushq	%r8
+	cfi_adjust_cfa_offset(8)
+	pushq	%r9
+	cfi_adjust_cfa_offset(8)
+	pushq	%r12
+	cfi_adjust_cfa_offset(8)
+	pushq	%r13
+	cfi_adjust_cfa_offset(8)
+	cfi_offset(%r8, -16)
+	cfi_offset(%r9, -24)
+	cfi_offset(%r12, -32)
+	cfi_offset(%r13, -40)
+
+	/* Stack frame for the timespec and timeval structs.  */
+	subq	$24, %rsp
+	cfi_adjust_cfa_offset(24)
+
+	movq	%rdi, %r12
+	movq	%rdx, %r13
+
+1:	movq	%rax, 16(%rsp)
+
+	/* Get current time.  */
+	movq	%rsp, %rdi
+	xorl	%esi, %esi
+	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
+	/* This is a regular function call, all caller-save registers
+	   might be clobbered.  */
+	callq	*%rax
+
+	/* Compute relative timeout.  */
+	movq	8(%rsp), %rax
+	movl	$1000, %edi
+	mul	%rdi		/* Milli seconds to nano seconds.  */
+	movq	(%r13), %rdi
+	movq	8(%r13), %rsi
+	subq	(%rsp), %rdi
+	subq	%rax, %rsi
+	jns	4f
+	addq	$1000000000, %rsi
+	decq	%rdi
+4:	testq	%rdi, %rdi
+	js	8f		/* Time is already up.  */
+
+	/* Futex call.  */
+	movq	%rdi, (%rsp)	/* Store relative timeout.  */
+	movq	%rsi, 8(%rsp)
+
+	movq	16(%rsp), %rdx
+	movl	%edx, %eax
+	orl	$FUTEX_WAITERS, %edx
+
+	testl	$FUTEX_OWNER_DIED, %eax
+	jnz	6f
+
+	cmpl	%eax, %edx
+	je	2f
+
+	LOCK
+	cmpxchgl %edx, (%r12)
+	movq	$0, %rcx	/* Must use mov to avoid changing cc.  */
+	jnz	5f
+
+2:	movq	%rsp, %r10
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
+	movq	%r12, %rdi
+	movl	$SYS_futex, %eax
+	syscall
+	movq	%rax, %rcx
+
+	movl	(%r12), %eax
+
+5:	testl	%eax, %eax
+	jne	7f
+
+	movl	%fs:TID, %edx
+	orl	$FUTEX_WAITERS, %edx
+	LOCK
+	cmpxchgl %edx, (%r12)
+	jnz	7f
+
+6:	addq	$24, %rsp
+	cfi_adjust_cfa_offset(-24)
+	popq	%r13
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r13)
+	popq	%r12
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r12)
+	popq	%r9
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r9)
+	popq	%r8
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r8)
+	retq
+
+3:	movl	$EINVAL, %eax
+	retq
+
+	cfi_adjust_cfa_offset(56)
+	cfi_offset(%r8, -16)
+	cfi_offset(%r9, -24)
+	cfi_offset(%r12, -32)
+	cfi_offset(%r13, -40)
+	/* Check whether the time expired.  */
+7:	cmpq	$-ETIMEDOUT, %rcx
+	jne	1b
+
+8:	movl	$ETIMEDOUT, %eax
+	jmp	6b
+	cfi_endproc
+	.size	__lll_robust_mutex_timedlock_wait,.-__lll_robust_mutex_timedlock_wait
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 e1593f32ff..fa8125dd87 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -63,9 +63,14 @@ pthread_barrier_wait:
 
 	/* Wait for the remaining threads.  The call will return immediately
 	   if the CURR_EVENT memory has meanwhile been changed.  */
-7:	xorq	%rsi, %rsi		/* movq $FUTEX_WAIT, %rsi */
+7:
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
 	xorq	%r10, %r10
-8:	movq	$SYS_futex, %rax
+8:	movl	$SYS_futex, %eax
 	syscall
 
 	/* Don't return on spurious wakeups.  The syscall does not change
@@ -110,8 +115,8 @@ pthread_barrier_wait:
 	/* Wake up all waiters.  The count is a signed number in the kernel
 	   so 0x7fffffff is the highest value.  */
 	movl	$0x7fffffff, %edx
-	movq	$FUTEX_WAKE, %rsi
-	movq	$SYS_futex, %rax
+	movl	$FUTEX_WAKE, %esi
+	movl	$SYS_futex, %eax
 	syscall
 
 	/* Increment LEFT.  If this brings the count back to the
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
index e8d7bd9bb6..006de2696e 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 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 Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -21,6 +21,7 @@
 #include <shlib-compat.h>
 #include <lowlevelcond.h>
 #include <kernel-features.h>
+#include <pthread-pi-defines.h>
 
 #ifdef UP
 # define LOCK
@@ -80,11 +81,15 @@ __pthread_cond_broadcast:
 8:	cmpq	$-1, %r8
 	je	9f
 
+	/* XXX: The kernel so far doesn't support requeue to PI futex.  */
+	testl	$PI_BIT, MUTEX_KIND(%r8)
+	jne	9f
+
 	/* Wake up all threads.  */
-	movq	$FUTEX_CMP_REQUEUE, %rsi
-	movq	$SYS_futex, %rax
+	movl	$FUTEX_CMP_REQUEUE, %esi
+	movl	$SYS_futex, %eax
 	movl	$1, %edx
-	movq	$0x7fffffff, %r10
+	movl	$0x7fffffff, %r10d
 	syscall
 
 	/* For any kind of error, which mainly is EAGAIN, we try again
@@ -128,9 +133,9 @@ __pthread_cond_broadcast:
 	jmp	8b
 
 9:	/* The futex requeue functionality is not available.  */
-	movq	$0x7fffffff, %rdx
-	movq	$FUTEX_WAKE, %rsi
-	movq	$SYS_futex, %rax
+	movl	$0x7fffffff, %edx
+	movl	$FUTEX_WAKE, %esi
+	movl	$SYS_futex, %eax
 	syscall
 	jmp	10b
 	.size	__pthread_cond_broadcast, .-__pthread_cond_broadcast
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
index 62bb74cc1a..3dbb9e81e3 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -31,7 +31,9 @@
 #define SYS_futex		202
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
-#define FUTEX_REQUEUE		3
+#define FUTEX_WAKE_OP		5
+
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)
 
 #define EINVAL			22
 
@@ -66,9 +68,30 @@ __pthread_cond_signal:
 	addl	$1, (%rdi)
 
 	/* Wake up one thread.  */
-	movq	$FUTEX_WAKE, %rsi
-	movq	$SYS_futex, %rax
-	movq	$1, %rdx
+	movl	$FUTEX_WAKE_OP, %esi
+	movl	$SYS_futex, %eax
+	movl	$1, %edx
+	movl	$1, %r10d
+#if cond_lock != 0
+	addq	$cond_lock, %r8
+#endif
+	movl	$FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %r9d
+	syscall
+#if cond_lock != 0
+	subq	$cond_lock, %r8
+#endif
+	/* For any kind of error, we try again with WAKE.
+	   The general test also covers running on old kernels.  */
+	cmpq	$-4095, %rax
+	jae	7f
+
+	xorl	%eax, %eax
+	retq
+
+7:	movl	$FUTEX_WAKE, %esi
+	movl	$SYS_futex, %eax
+	/* %rdx should be 1 already from $FUTEX_WAKE_OP syscall.
+	movl	$1, %edx  */
 	syscall
 
 	/* Unlock.  */
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 67bec6caa7..ad3ae1e76e 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -56,7 +56,7 @@ __pthread_cond_timedwait:
 .Lsubq:
 
 	cmpq	$1000000000, 8(%rdx)
-	movq	$EINVAL, %rax
+	movl	$EINVAL, %eax
 	jae	18f
 
 	/* Stack frame:
@@ -102,7 +102,7 @@ __pthread_cond_timedwait:
 
 	/* Unlock the mutex.  */
 2:	movq	16(%rsp), %rdi
-	xorq	%rsi, %rsi
+	xorl	%esi, %esi
 	callq	__pthread_mutex_unlock_usercnt
 
 	testl	%eax, %eax
@@ -141,7 +141,7 @@ __pthread_cond_timedwait:
 	/* Only clocks 0 and 1 are allowed so far.  Both are handled in the
 	   kernel.  */
 	leaq	24(%rsp), %rsi
-	movq	$__NR_clock_gettime, %rax
+	movl	$__NR_clock_gettime, %eax
 	syscall
 # ifndef __ASSUME_POSIX_TIMERS
 	cmpq	$-ENOSYS, %rax
@@ -155,13 +155,13 @@ __pthread_cond_timedwait:
 	subq	32(%rsp), %rdx
 #else
 	leaq	24(%rsp), %rdi
-	xorq	%rsi, %rsi
+	xorl	%esi, %esi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
 	callq	*%rax
 
 	/* Compute relative timeout.  */
 	movq	32(%rsp), %rax
-	movq	$1000, %rdx
+	movl	$1000, %edx
 	mul	%rdx		/* Milli seconds to nano seconds.  */
 	movq	(%r13), %rcx
 	movq	8(%r13), %rdx
@@ -195,10 +195,14 @@ __pthread_cond_timedwait:
 	movl	%eax, (%rsp)
 
 	leaq	24(%rsp), %r10
-	xorq	%rsi, %rsi	/* movq $FUTEX_WAIT, %rsi */
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
 	movq	%r12, %rdx
 	addq	$cond_futex, %rdi
-	movq	$SYS_futex, %rax
+	movl	$SYS_futex, %eax
 	syscall
 	movq	%rax, %r14
 
@@ -237,7 +241,7 @@ __pthread_cond_timedwait:
 
 13:	incq	wakeup_seq(%rdi)
 	incl	cond_futex(%rdi)
-	movq	$ETIMEDOUT, %r14
+	movl	$ETIMEDOUT, %r14d
 	jmp	14f
 
 23:	xorq	%r14, %r14
@@ -256,8 +260,8 @@ __pthread_cond_timedwait:
 	jne	25f
 
 	addq	$cond_nwaiters, %rdi
-	movq	$SYS_futex, %rax
-	movq	$FUTEX_WAKE, %rsi
+	movl	$SYS_futex, %eax
+	movl	$FUTEX_WAKE, %esi
 	movl	$1, %edx
 	syscall
 	subq	$cond_nwaiters, %rdi
@@ -349,13 +353,13 @@ __pthread_cond_timedwait:
 #if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
 	/* clock_gettime not available.  */
 19:	leaq	24(%rsp), %rdi
-	xorq	%rsi, %rsi
+	xorl	%esi, %esi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
 	callq	*%rax
 
 	/* Compute relative timeout.  */
 	movq	32(%rsp), %rax
-	movq	$1000, %rdx
+	movl	$1000, %edx
 	mul	%rdx		/* Milli seconds to nano seconds.  */
 	movq	(%r13), %rcx
 	movq	8(%r13), %rdx
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 f5de0a280c..969e80da2a 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 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 Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -67,9 +67,15 @@ __condvar_cleanup:
 	cmpl	4(%r8), %edx
 	jne	3f
 
+	/* We increment the wakeup_seq counter only if it is lower than
+	   total_seq.  If this is not the case the thread was woken and
+	   then canceled.  In this case we ignore the signal.  */
+	movq	total_seq(%rdi), %rax
+	cmpq	wakeup_seq(%rdi), %rax
+	jbe	6f
 	incq	wakeup_seq(%rdi)
-	incq	woken_seq(%rdi)
 	incl	cond_futex(%rdi)
+6:	incq	woken_seq(%rdi)
 
 3:	subl	$(1 << clock_bits), cond_nwaiters(%rdi)
 
@@ -82,12 +88,12 @@ __condvar_cleanup:
 	jne	4f
 
 	addq	$cond_nwaiters, %rdi
-	movq	$SYS_futex, %rax
-	movq	$FUTEX_WAKE, %rsi
+	movl	$SYS_futex, %eax
+	movl	$FUTEX_WAKE, %esi
 	movl	$1, %edx
 	syscall
 	subq	$cond_nwaiters, %rdi
-	movq	$1, %r12
+	movl	$1, %r12d
 
 4:	LOCK
 #if cond_lock == 0
@@ -105,9 +111,9 @@ __condvar_cleanup:
 2:	testq	%r12, %r12
 	jnz	5f
 	addq	$cond_futex, %rdi
-	movq	$FUTEX_WAKE, %rsi
+	movl	$FUTEX_WAKE, %esi
 	movl	$0x7fffffff, %edx
-	movq	$SYS_futex, %rax
+	movl	$SYS_futex, %eax
 	syscall
 
 5:	movq	16(%r8), %rdi
@@ -170,7 +176,7 @@ __pthread_cond_wait:
 
 	/* Unlock the mutex.  */
 2:	movq	16(%rsp), %rdi
-	xorq	%rsi, %rsi
+	xorl	%esi, %esi
 	callq	__pthread_mutex_unlock_usercnt
 
 	testl	%eax, %eax
@@ -215,8 +221,12 @@ __pthread_cond_wait:
 	xorq	%r10, %r10
 	movq	%r12, %rdx
 	addq	$cond_futex-cond_lock, %rdi
-	movq	$SYS_futex, %rax
-	movq	%r10, %rsi	/* movq $FUTEX_WAIT, %rsi */
+	movl	$SYS_futex, %eax
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
 	syscall
 
 	movl	(%rsp), %edi
@@ -262,8 +272,8 @@ __pthread_cond_wait:
 	jne	17f
 
 	addq	$cond_nwaiters, %rdi
-	movq	$SYS_futex, %rax
-	movq	$FUTEX_WAKE, %rsi
+	movl	$SYS_futex, %eax
+	movl	$FUTEX_WAKE, %esi
 	movl	$1, %edx
 	syscall
 	subq	$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 3fec0f4205..9db5516913 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -74,17 +74,23 @@ __pthread_once:
 	jnz	3f	/* Different for generation -> run initializer.  */
 
 	/* Somebody else got here first.  Wait.  */
-	movq	%r10, %rsi		/* movq $FUTEX_WAIT, %rsi */
-	movq	$SYS_futex, %rax
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
+	movl	$SYS_futex, %eax
 	syscall
 	jmp	6b
 
 	/* Preserve the pointer to the control variable.  */
 3:	pushq	%rdi
 .Lpush_rdi:
+	pushq	%rdi
+.Lpush_rdi2:
 
 .LcleanupSTART:
-	callq	*8(%rsp)
+	callq	*16(%rsp)
 .LcleanupEND:
 
 	/* Get the control variable address back.  */
@@ -95,15 +101,18 @@ __pthread_once:
 	LOCK
 	incl	(%rdi)
 
+	addq	$8, %rsp
+.Ladd1:
+
 	/* Wake up all other threads.  */
 	movl	$0x7fffffff, %edx
 	movl	$FUTEX_WAKE, %esi
-	movq	$SYS_futex, %rax
+	movl	$SYS_futex, %eax
 	syscall
 
 4:	addq	$8, %rsp
-.Ladd:
-	xorq	%rax, %rax
+.Ladd2:
+	xorl	%eax, %eax
 	retq
 
 	.size	__pthread_once,.-__pthread_once
@@ -124,8 +133,8 @@ clear_once_control:
 	movl	$0, (%rdi)
 
 	movl	$0x7fffffff, %edx
-	movq	$FUTEX_WAKE, %rsi
-	movq	$SYS_futex, %rax
+	movl	$FUTEX_WAKE, %esi
+	movl	$SYS_futex, %eax
 	syscall
 
 	movq	%r8, %rdi
@@ -220,20 +229,28 @@ clear_once_control:
 	.byte	14				# DW_CFA_def_cfa_offset
 	.uleb128 24
 	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lpop_rdi-.Lpush_rdi
+	.long	.Lpush_rdi2-.Lpush_rdi
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 32
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Lpop_rdi-.Lpush_rdi2
+	.byte	14				# DW_CFA_def_cfa_offset
+	.uleb128 24
+	.byte	4				# DW_CFA_advance_loc4
+	.long	.Ladd1-.Lpop_rdi
 	.byte	14				# DW_CFA_def_cfa_offset
 	.uleb128 16
 	.byte	4				# DW_CFA_advance_loc4
-	.long	.Ladd-.Lpop_rdi
+	.long	.Ladd2-.Ladd1
 	.byte	14				# DW_CFA_def_cfa_offset
 	.uleb128 8
 	.byte	4				# DW_CFA_advance_loc4
-	.long	clear_once_control-.Ladd
+	.long	clear_once_control-.Ladd2
 	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 24
+	.uleb128 32
 #if 0
 	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lpop_rdi2-clear_once_control
+	.long	.Lpop_rdi3-clear_once_control
 	.byte	14				# DW_CFA_def_cfa_offset
 	.uleb128 16
 #endif
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 43c8cae34c..5e9d8fb1d6 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -74,8 +74,12 @@ __pthread_rwlock_rdlock:
 	jne	10f
 
 11:	addq	$READERS_WAKEUP, %rdi
-	movq	%r10, %rsi	/* movq $FUTEX_WAIT, %rsi */
-	movq	$SYS_futex, %rax
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
+	movl	$SYS_futex, %eax
 	syscall
 
 	subq	$READERS_WAKEUP, %rdi
@@ -94,7 +98,7 @@ __pthread_rwlock_rdlock:
 13:	decl	READERS_QUEUED(%rdi)
 	jmp	2b
 
-5:	xorq	%rdx, %rdx
+5:	xorl	%edx, %edx
 	incl	NR_READERS(%rdi)
 	je	8f
 9:	LOCK
@@ -122,7 +126,7 @@ __pthread_rwlock_rdlock:
 14:	cmpl	%fs:TID, %eax
 	jne	3b
 	/* Deadlock detected.  */
-	movq	$EDEADLK, %rdx
+	movl	$EDEADLK, %edx
 	jmp	9b
 
 6:
@@ -137,12 +141,12 @@ __pthread_rwlock_rdlock:
 
 	/* Overflow.  */
 8:	decl	NR_READERS(%rdi)
-	movq	$EAGAIN, %rdx
+	movl	$EAGAIN, %edx
 	jmp	9b
 
 	/* Overflow.  */
 4:	decl	READERS_QUEUED(%rdi)
-	movq	$EAGAIN, %rdx
+	movl	$EAGAIN, %edx
 	jmp	9b
 
 10:
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 aadc90c974..b44660418a 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -90,13 +90,13 @@ pthread_rwlock_timedrdlock:
 
 	/* Get current time.  */
 11:	movq	%rsp, %rdi
-	xorq	%rsi, %rsi
+	xorl	%esi, %esi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
 	callq	*%rax
 
 	/* Compute relative timeout.  */
 	movq	8(%rsp), %rax
-	movq	$1000, %rdi
+	movl	$1000, %edi
 	mul	%rdi		/* Milli seconds to nano seconds.  */
 	movq	(%r13), %rcx
 	movq	8(%r13), %rdi
@@ -112,11 +112,15 @@ pthread_rwlock_timedrdlock:
 	movq	%rcx, (%rsp)	/* Store relative timeout.  */
 	movq	%rdi, 8(%rsp)
 
-	xorq	%rsi, %rsi	/* movq $FUTEX_WAIT, %rsi */
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
 	movq	%rsp, %r10
 	movl	%r14d, %edx
 	leaq	READERS_WAKEUP(%r12), %rdi
-	movq	$SYS_futex, %rax
+	movl	$SYS_futex, %eax
 	syscall
 	movq	%rax, %rdx
 17:
@@ -136,11 +140,11 @@ pthread_rwlock_timedrdlock:
 	cmpq	$-ETIMEDOUT, %rdx
 	jne	2b
 
-18:	movq	$ETIMEDOUT, %rdx
+18:	movl	$ETIMEDOUT, %edx
 	jmp	9f
 
 
-5:	xorq	%rdx, %rdx
+5:	xorl	%edx, %edx
 	incl	NR_READERS(%r12)
 	je	8f
 9:	LOCK
@@ -168,7 +172,7 @@ pthread_rwlock_timedrdlock:
 
 14:	cmpl	%fs:TID, %eax
 	jne	3b
-	movq	$EDEADLK, %rdx
+	movl	$EDEADLK, %edx
 	jmp	9b
 
 6:
@@ -182,12 +186,12 @@ pthread_rwlock_timedrdlock:
 
 	/* Overflow.  */
 8:	decl	NR_READERS(%r12)
-	movq	$EAGAIN, %rdx
+	movl	$EAGAIN, %edx
 	jmp	9b
 
 	/* Overflow.  */
 4:	decl	READERS_QUEUED(%r12)
-	movq	$EAGAIN, %rdx
+	movl	$EAGAIN, %edx
 	jmp	9b
 
 10:
@@ -211,6 +215,6 @@ pthread_rwlock_timedrdlock:
 16:	movq	$-ETIMEDOUT, %rdx
 	jmp	17b
 
-19:	movq	$EINVAL, %rdx
+19:	movl	$EINVAL, %edx
 	jmp	9b
 	.size	pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock
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 ccaef47070..525e5b6b93 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -86,13 +86,13 @@ pthread_rwlock_timedwrlock:
 
 	/* Get current time.  */
 11:	movq	%rsp, %rdi
-	xorq	%rsi, %rsi
+	xorl	%esi, %esi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
 	callq	*%rax
 
 	/* Compute relative timeout.  */
 	movq	8(%rsp), %rax
-	movq	$1000, %rdi
+	movl	$1000, %edi
 	mul	%rdi		/* Milli seconds to nano seconds.  */
 	movq	(%r13), %rcx
 	movq	8(%r13), %rdi
@@ -108,11 +108,15 @@ pthread_rwlock_timedwrlock:
 	movq	%rcx, (%rsp)	/* Store relative timeout.  */
 	movq	%rdi, 8(%rsp)
 
-	xorq	%rsi, %rsi	/* movq $FUTEX_WAIT, %rsi */
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
 	movq	%rsp, %r10
 	movl	%r14d, %edx
 	leaq	WRITERS_WAKEUP(%r12), %rdi
-	movq	$SYS_futex, %rax
+	movl	$SYS_futex, %eax
 	syscall
 	movq	%rax, %rdx
 17:
@@ -132,11 +136,11 @@ pthread_rwlock_timedwrlock:
 	cmpq	$-ETIMEDOUT, %rdx
 	jne	2b
 
-18:	movq	$ETIMEDOUT, %rdx
+18:	movl	$ETIMEDOUT, %edx
 	jmp	9f
 
 
-5:	xorq	%rdx, %rdx
+5:	xorl	%edx, %edx
 	movl	%fs:TID, %eax
 	movl	%eax, WRITER(%r12)
 9:	LOCK
@@ -164,7 +168,7 @@ pthread_rwlock_timedwrlock:
 
 14:	cmpl	%fs:TID, %eax
 	jne	3b
-20:	movq	$EDEADLK, %rdx
+20:	movl	$EDEADLK, %edx
 	jmp	9b
 
 6:
@@ -178,7 +182,7 @@ pthread_rwlock_timedwrlock:
 
 	/* Overflow.  */
 4:	decl	WRITERS_QUEUED(%r12)
-	movq	$EAGAIN, %rdx
+	movl	$EAGAIN, %edx
 	jmp	9b
 
 10:
@@ -202,6 +206,6 @@ pthread_rwlock_timedwrlock:
 16:	movq	$-ETIMEDOUT, %rdx
 	jmp	17b
 
-19:	movq	$EINVAL, %rdx
+19:	movl	$EINVAL, %edx
 	jmp	9b
 	.size	pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock
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 ac69fc0eae..3a6b9f0bad 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -56,7 +56,7 @@ __pthread_rwlock_unlock:
 
 5:	movl	$0, WRITER(%rdi)
 
-	movq	$1, %rsi
+	movl	$1, %esi
 	leaq	WRITERS_WAKEUP(%rdi), %r10
 	movq	%rsi, %rdx
 	cmpl	$0, WRITERS_QUEUED(%rdi)
@@ -78,11 +78,11 @@ __pthread_rwlock_unlock:
 #endif
 	jne	7f
 
-8:	movq	$SYS_futex, %rax
+8:	movl	$SYS_futex, %eax
 	movq	%r10, %rdi
 	syscall
 
-	xorq	%rax, %rax
+	xorl	%eax, %eax
 	retq
 
 	.align	16
@@ -94,7 +94,7 @@ __pthread_rwlock_unlock:
 #endif
 	jne	3f
 
-4:	xorq	%rax, %rax
+4:	xorl	%eax, %eax
 	retq
 
 1:
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 1fcb07eaef..0e82f890aa 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -72,8 +72,12 @@ __pthread_rwlock_wrlock:
 	jne	10f
 
 11:	addq	$WRITERS_WAKEUP, %rdi
-	movq	%r10, %rsi	/* movq $FUTEX_WAIT, %rsi */
-	movq	$SYS_futex, %rax
+#if FUTEX_WAIT == 0
+	xorl	%esi, %esi
+#else
+	movl	$FUTEX_WAIT, %esi
+#endif
+	movl	$SYS_futex, %eax
 	syscall
 
 	subq	$WRITERS_WAKEUP, %rdi
@@ -92,7 +96,7 @@ __pthread_rwlock_wrlock:
 13:	decl	WRITERS_QUEUED(%rdi)
 	jmp	2b
 
-5:	xorq	%rdx, %rdx
+5:	xorl	%edx, %edx
 	movl	%fs:TID, %eax
 	movl	%eax, WRITER(%rdi)
 9:	LOCK
@@ -119,7 +123,7 @@ __pthread_rwlock_wrlock:
 
 14:	cmpl	%fs:TID, %eax
 	jne	3b
-	movq	$EDEADLK, %rdx
+	movl	$EDEADLK, %edx
 	jmp	9b
 
 6:
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 21ec6fd226..7f608a5974 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -41,8 +41,8 @@ sem_post:
 	LOCK
 	xaddl	%edx, (%rdi)
 
-	movq	$SYS_futex, %rax
-	movq	$FUTEX_WAKE, %rsi
+	movl	$SYS_futex, %eax
+	movl	$FUTEX_WAKE, %esi
 	incl	%edx
 	syscall
 
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 d90e03b55b..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 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,17 +79,14 @@ sem_timedwait:
 	cfi_offset(14, -24)		/* %r14 */
 	jae	6f
 
-7:	call	__pthread_enable_asynccancel
-	movl	%eax, 16(%rsp)
-
-	xorq	%rsi, %rsi
+7:	xorl	%esi, %esi
 	movq	%rsp, %rdi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
 	callq	*%rax
 
 	/* Compute relative timeout.  */
 	movq	8(%rsp), %rax
-	movq	$1000, %rdi
+	movl	$1000, %edi
 	mul	%rdi		/* Milli seconds to nano seconds.  */
 	movq	(%r13), %rdi
 	movq	8(%r13), %rsi
@@ -105,10 +102,13 @@ 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
-	xorq	%rsi, %rsi
-	movq	$SYS_futex, %rax
+	xorl	%esi, %esi
+	movl	$SYS_futex, %eax
 	xorl	%edx, %edx
 	syscall
 	movq	%rax, %r14
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 31271bb94c..6b77dfc0d8 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 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -56,4 +56,3 @@ sem_trywait:
 	orl	$-1, %eax
 	retq
 	.size	sem_trywait,.-sem_trywait
-	versioned_symbol(libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1)
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 76957bc139..63ecd063ab 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -77,7 +77,7 @@ sem_wait:
 	movl	%eax, %r8d
 
 	xorq	%r10, %r10
-	movq	$SYS_futex, %rax
+	movl	$SYS_futex, %eax
 	movq	%r13, %rdi
 	movq	%r10, %rsi
 	movq	%r10, %rdx
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 d47c1b80dc..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 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.
 
@@ -48,7 +48,7 @@
     POPARGS_##args							      \
     /* The return value from CENABLE is argument for CDISABLE.  */	      \
     movq %rax, (%rsp);							      \
-    movq $SYS_ify (syscall_name), %rax;					      \
+    movl $SYS_ify (syscall_name), %eax;					      \
     syscall;								      \
     movq (%rsp), %rdi;							      \
     /* Save %rax since it's the error code from the syscall.  */	      \
@@ -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/unix/sysv/linux/x86_64/vfork.S b/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S
index f68d40439e..9a9912ca85 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S
@@ -16,9 +16,16 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <tcb-offsets.h>
+/* We want an #include_next, but we are the main source file.
+   So, #include ourselves and in that incarnation we can use #include_next.  */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <vfork.S>
+#else
 
-#define SAVE_PID \
+# include <tcb-offsets.h>
+
+# define SAVE_PID \
 	movl	%fs:PID, %esi;						      \
 	movl	$0x80000000, %ecx;					      \
 	movl	%esi, %edx;						      \
@@ -26,10 +33,11 @@
 	cmove	%ecx, %edx;						      \
 	movl	%edx, %fs:PID
 
-#define RESTORE_PID \
+# define RESTORE_PID \
 	testq	%rax, %rax;						      \
 	je	1f;							      \
 	movl	%esi, %fs:PID;						      \
 1:
 
-#include <sysdeps/unix/sysv/linux/x86_64/vfork.S>
+# include_next <vfork.S>
+#endif
diff --git a/nptl/sysdeps/x86_64/jmpbuf-unwind.h b/nptl/sysdeps/x86_64/jmpbuf-unwind.h
deleted file mode 100644
index 345ed557c5..0000000000
--- a/nptl/sysdeps/x86_64/jmpbuf-unwind.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <setjmp.h>
-#include <stdint.h>
-#include <unwind.h>
-
-#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
-  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
-
-#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
-  ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_RSP] - (_adj))
-
-/* We use the normal lobngjmp for unwinding.  */
-#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/nptl/sysdeps/x86_64/tcb-offsets.sym b/nptl/sysdeps/x86_64/tcb-offsets.sym
index 8118d2df8b..a9ede75c96 100644
--- a/nptl/sysdeps/x86_64/tcb-offsets.sym
+++ b/nptl/sysdeps/x86_64/tcb-offsets.sym
@@ -10,3 +10,4 @@ CLEANUP			offsetof (struct pthread, cleanup)
 CLEANUP_PREV		offsetof (struct _pthread_cleanup_buffer, __prev)
 MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
 MULTIPLE_THREADS_OFFSET	offsetof (tcbhead_t, multiple_threads)
+POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
index 3d6111f4e3..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 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
@@ -20,8 +20,9 @@
 #ifndef _TLS_H
 #define _TLS_H	1
 
-#include <asm/prctl.h>	/* For ARCH_SET_FS.  */
 #ifndef __ASSEMBLER__
+# include <asm/prctl.h>	/* For ARCH_SET_FS.  */
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 # include <stdlib.h>
@@ -31,7 +32,11 @@
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
@@ -42,6 +47,10 @@ 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;
 } tcbhead_t;
 
 #else /* __ASSEMBLER__ */
@@ -77,11 +86,13 @@ typedef struct
 # endif
 #endif
 
-/* This is the size of the initial TCB.  */
-# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+/* This is the size of the initial TCB.  Can't be just sizeof (tcbhead_t),
+   because NPTL getpid, __libc_alloca_cutoff etc. need (almost) the whole
+   struct pthread even when not linked with -lpthread.  */
+# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
 
 /* Alignment requirements for the initial TCB.  */
-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
 
 /* This is the size of the TCB.  */
 # define TLS_TCB_SIZE sizeof (struct pthread)
@@ -313,6 +324,42 @@ typedef struct
      __res; })
 
 
+/* Set the stack guard field in TCB head.  */
+# define THREAD_SET_STACK_GUARD(value) \
+    THREAD_SETMEM (THREAD_SELF, header.stack_guard, value)
+# define THREAD_COPY_STACK_GUARD(descr) \
+    ((descr)->header.stack_guard					      \
+     = THREAD_GETMEM (THREAD_SELF, header.stack_guard))
+
+
+/* Set the pointer guard field in the TCB head.  */
+#define THREAD_SET_POINTER_GUARD(value) \
+  THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
+#define THREAD_COPY_POINTER_GUARD(descr) \
+  ((descr)->header.pointer_guard					      \
+   = 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 */