summary refs log tree commit diff
path: root/nptl/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps')
-rw-r--r--nptl/sysdeps/alpha/tls.h28
-rw-r--r--nptl/sysdeps/i386/tls.h26
-rw-r--r--nptl/sysdeps/ia64/pthread_spin_unlock.c4
-rw-r--r--nptl/sysdeps/ia64/tls.h28
-rw-r--r--nptl/sysdeps/powerpc/tls.h28
-rw-r--r--nptl/sysdeps/pthread/pthread_barrier_wait.c77
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_broadcast.c86
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_signal.c61
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_timedwait.c214
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_wait.c191
-rw-r--r--nptl/sysdeps/pthread/pthread_getcpuclockid.c57
-rw-r--r--nptl/sysdeps/pthread/pthread_once.c54
-rw-r--r--nptl/sysdeps/pthread/pthread_rwlock_rdlock.c95
-rw-r--r--nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c137
-rw-r--r--nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c127
-rw-r--r--nptl/sysdeps/pthread/pthread_rwlock_unlock.c57
-rw-r--r--nptl/sysdeps/pthread/pthread_rwlock_wrlock.c87
-rw-r--r--nptl/sysdeps/pthread/pthread_spin_destroy.c29
-rw-r--r--nptl/sysdeps/pthread/pthread_spin_init.c28
-rw-r--r--nptl/sysdeps/pthread/pthread_spin_unlock.c30
-rw-r--r--nptl/sysdeps/s390/tls.h29
-rw-r--r--nptl/sysdeps/sh/tls.h28
-rw-r--r--nptl/sysdeps/sparc/tls.h34
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/bits/local_lim.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.c9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/bits/semaphore.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c22
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/Versions4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h93
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstack.c2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/bits/semaphore.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h21
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h21
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h28
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S10
-rw-r--r--nptl/sysdeps/x86_64/tls.h26
51 files changed, 1623 insertions, 221 deletions
diff --git a/nptl/sysdeps/alpha/tls.h b/nptl/sysdeps/alpha/tls.h
index be2430f676..07db15939d 100644
--- a/nptl/sysdeps/alpha/tls.h
+++ b/nptl/sysdeps/alpha/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  NPTL/Alpha version.
-   Copyright (C) 2003, 2005, 2006 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
@@ -48,6 +48,9 @@ typedef union dtv
 # error "TLS support is required."
 #endif
 
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
 #ifndef __ASSEMBLER__
 
 /* Get system call information.  */
@@ -121,6 +124,29 @@ typedef struct
 #define THREAD_SETMEM_NC(descr, member, idx, value) \
   descr->member[idx] = (value)
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
+			       THREAD_GSCOPE_FLAG_UNUSED);		     \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h
index d5b3797e69..b3d9142fc5 100644
--- a/nptl/sysdeps/i386/tls.h
+++ b/nptl/sysdeps/i386/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  nptl/i386 version.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002,2003,2004,2005,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -51,6 +51,7 @@ typedef struct
   uintptr_t sysinfo;
   uintptr_t stack_guard;
   uintptr_t pointer_guard;
+  int gscope_flag;
 } tcbhead_t;
 
 # define TLS_MULTIPLE_THREADS_IN_TCB 1
@@ -65,6 +66,9 @@ typedef struct
 # error "TLS support is required."
 #endif
 
+/* Signal that TLS support is available.  */
+#define USE_TLS	1
+
 /* Alignment requirement for the stack.  For IA-32 this is governed by
    the SSE memory functions.  */
 #define STACK_ALIGN	16
@@ -431,6 +435,26 @@ union user_desc_init
    = THREAD_GETMEM (THREAD_SELF, header.pointer_guard))
 
 
+/* Get and set the global scope generation counter in the TCB head.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									      \
+    { int __res;							      \
+      asm volatile ("xchgl %0, %%gs:%P1"				      \
+		    : "=r" (__res)					      \
+		    : "i" (offsetof (struct pthread, header.gscope_flag)),    \
+		      "0" (THREAD_GSCOPE_FLAG_UNUSED));			      \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				      \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		      \
+    }									      \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/ia64/pthread_spin_unlock.c b/nptl/sysdeps/ia64/pthread_spin_unlock.c
index 50d9c5f6a8..6232764b13 100644
--- a/nptl/sysdeps/ia64/pthread_spin_unlock.c
+++ b/nptl/sysdeps/ia64/pthread_spin_unlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -23,6 +23,6 @@
 int
 pthread_spin_unlock (pthread_spinlock_t *lock)
 {
-  __sync_lock_release ((int *) lock);
+  __sync_lock_release_si ((int *) lock);
   return 0;
 }
diff --git a/nptl/sysdeps/ia64/tls.h b/nptl/sysdeps/ia64/tls.h
index 22a8b08144..a43f096798 100644
--- a/nptl/sysdeps/ia64/tls.h
+++ b/nptl/sysdeps/ia64/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  nptl/IA-64 version.
-   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -61,6 +61,9 @@ register struct pthread *__thread_self __asm__("r13");
 # error "TLS support is required."
 #endif
 
+/* Signal that TLS support is available.  */
+#define USE_TLS	1
+
 /* Alignment requirement for the stack.  */
 #define STACK_ALIGN	16
 
@@ -163,6 +166,29 @@ register struct pthread *__thread_self __asm__("r13");
   (((uintptr_t *) ((char *) (descr) + TLS_PRE_TCB_SIZE))[-2] \
    = THREAD_GET_POINTER_GUARD ())
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
+			       THREAD_GSCOPE_FLAG_UNUSED);		     \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/powerpc/tls.h b/nptl/sysdeps/powerpc/tls.h
index ddaafe23d0..ad5698c6f8 100644
--- a/nptl/sysdeps/powerpc/tls.h
+++ b/nptl/sysdeps/powerpc/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  NPTL/PowerPC version.
-   Copyright (C) 2003, 2005, 2006 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
@@ -48,6 +48,9 @@ typedef union dtv
 # error "TLS support is required."
 #endif
 
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
 #ifndef __ASSEMBLER__
 
 /* Get system call information.  */
@@ -180,6 +183,29 @@ register void *__thread_register __asm__ ("r13");
    different value to mean unset l_tls_offset.  */
 # define NO_TLS_OFFSET		-1
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
+			       THREAD_GSCOPE_FLAG_UNUSED);		     \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/pthread/pthread_barrier_wait.c b/nptl/sysdeps/pthread/pthread_barrier_wait.c
new file mode 100644
index 0000000000..c6b563f242
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_barrier_wait.c
@@ -0,0 +1,77 @@
+/* Copyright (C) 2003, 2004 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>
+
+
+/* Wait on barrier.  */
+int
+pthread_barrier_wait (barrier)
+     pthread_barrier_t *barrier;
+{
+  struct pthread_barrier *ibarrier = (struct pthread_barrier *) barrier;
+  int result = 0;
+
+  /* Make sure we are alone.  */
+  lll_lock (ibarrier->lock);
+
+  /* One more arrival.  */
+  --ibarrier->left;
+
+  /* Are these all?  */
+  if (ibarrier->left == 0)
+    {
+      /* Yes. Increment the event counter to avoid invalid wake-ups and
+	 tell the current waiters that it is their turn.  */
+      ++ibarrier->curr_event;
+
+      /* Wake up everybody.  */
+      lll_futex_wake (&ibarrier->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->curr_event;
+
+      /* Before suspending, make the barrier available to others.  */
+      lll_unlock (ibarrier->lock);
+
+      /* Wait for the event counter of the barrier to change.  */
+      do
+	lll_futex_wait (&ibarrier->curr_event, event);
+      while (event == ibarrier->curr_event);
+    }
+
+  /* Make sure the init_count is stored locally or in a register.  */
+  unsigned int init_count = ibarrier->init_count;
+
+  /* If this was the last woken thread, unlock.  */
+  if (atomic_increment_val (&ibarrier->left) == init_count)
+    /* We are done.  */
+    lll_unlock (ibarrier->lock);
+
+  return result;
+}
diff --git a/nptl/sysdeps/pthread/pthread_cond_broadcast.c b/nptl/sysdeps/pthread/pthread_cond_broadcast.c
new file mode 100644
index 0000000000..2b8b5460f4
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_cond_broadcast.c
@@ -0,0 +1,86 @@
+/* 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 <endian.h>
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <pthread.h>
+#include <pthreadP.h>
+
+#include <shlib-compat.h>
+#include <kernel-features.h>
+
+
+int
+__pthread_cond_broadcast (cond)
+     pthread_cond_t *cond;
+{
+  /* Make sure we are alone.  */
+  lll_mutex_lock (cond->__data.__lock);
+
+  /* Are there any waiters to be woken?  */
+  if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
+    {
+      /* Yes.  Mark them all as woken.  */
+      cond->__data.__wakeup_seq = cond->__data.__total_seq;
+      cond->__data.__woken_seq = cond->__data.__total_seq;
+      cond->__data.__futex = (unsigned int) cond->__data.__total_seq * 2;
+      int futex_val = cond->__data.__futex;
+      /* Signal that a broadcast happened.  */
+      ++cond->__data.__broadcast_seq;
+
+      /* We are done.  */
+      lll_mutex_unlock (cond->__data.__lock);
+
+      /* Do not use requeue for pshared condvars.  */
+      if (cond->__data.__mutex == (void *) ~0l)
+	goto wake_all;
+
+      /* 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,
+					       INT_MAX, &mut->__data.__lock,
+					       futex_val), 0))
+	{
+	  /* The requeue functionality is not available.  */
+	wake_all:
+	  lll_futex_wake (&cond->__data.__futex, INT_MAX);
+	}
+
+      /* That's all.  */
+      return 0;
+    }
+
+  /* We are done.  */
+  lll_mutex_unlock (cond->__data.__lock);
+
+  return 0;
+}
+
+versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
+		  GLIBC_2_3_2);
diff --git a/nptl/sysdeps/pthread/pthread_cond_signal.c b/nptl/sysdeps/pthread/pthread_cond_signal.c
new file mode 100644
index 0000000000..5a9bbcad91
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_cond_signal.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 2003, 2004 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 <endian.h>
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <pthread.h>
+#include <pthreadP.h>
+
+#include <shlib-compat.h>
+#include <kernel-features.h>
+
+
+int
+__pthread_cond_signal (cond)
+     pthread_cond_t *cond;
+{
+  /* Make sure we are alone.  */
+  lll_mutex_lock (cond->__data.__lock);
+
+  /* Are there any waiters to be woken?  */
+  if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
+    {
+      /* Yes.  Mark one of them as woken.  */
+      ++cond->__data.__wakeup_seq;
+      ++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);
+    }
+
+  /* We are done.  */
+  lll_mutex_unlock (cond->__data.__lock);
+
+  return 0;
+}
+
+versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
+		  GLIBC_2_3_2);
diff --git a/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/nptl/sysdeps/pthread/pthread_cond_timedwait.c
new file mode 100644
index 0000000000..fdbf43eae8
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_cond_timedwait.c
@@ -0,0 +1,214 @@
+/* Copyright (C) 2003, 2004 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 <endian.h>
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <pthread.h>
+#include <pthreadP.h>
+
+#include <shlib-compat.h>
+
+
+/* Cleanup handler, defined in pthread_cond_wait.c.  */
+extern void __condvar_cleanup (void *arg)
+     __attribute__ ((visibility ("hidden")));
+
+struct _condvar_cleanup_buffer
+{
+  int oldtype;
+  pthread_cond_t *cond;
+  pthread_mutex_t *mutex;
+  unsigned int bc_seq;
+};
+
+int
+__pthread_cond_timedwait (cond, mutex, abstime)
+     pthread_cond_t *cond;
+     pthread_mutex_t *mutex;
+     const struct timespec *abstime;
+{
+  struct _pthread_cleanup_buffer buffer;
+  struct _condvar_cleanup_buffer cbuffer;
+  int result = 0;
+
+  /* Catch invalid parameters.  */
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    return EINVAL;
+
+  /* Make sure we are along.  */
+  lll_mutex_lock (cond->__data.__lock);
+
+  /* Now we can release the mutex.  */
+  int err = __pthread_mutex_unlock_usercnt (mutex, 0);
+  if (err)
+    {
+      lll_mutex_unlock (cond->__data.__lock);
+      return err;
+    }
+
+  /* We have one new user of the condvar.  */
+  ++cond->__data.__total_seq;
+  ++cond->__data.__futex;
+  cond->__data.__nwaiters += 1 << COND_CLOCK_BITS;
+
+  /* Remember the mutex we are using here.  If there is already a
+     different address store this is a bad user bug.  Do not store
+     anything for pshared condvars.  */
+  if (cond->__data.__mutex != (void *) ~0l)
+    cond->__data.__mutex = mutex;
+
+  /* Prepare structure passed to cancellation handler.  */
+  cbuffer.cond = cond;
+  cbuffer.mutex = mutex;
+
+  /* Before we block we enable cancellation.  Therefore we have to
+     install a cancellation handler.  */
+  __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer);
+
+  /* The current values of the wakeup counter.  The "woken" counter
+     must exceed this value.  */
+  unsigned long long int val;
+  unsigned long long int seq;
+  val = seq = cond->__data.__wakeup_seq;
+  /* Remember the broadcast counter.  */
+  cbuffer.bc_seq = cond->__data.__broadcast_seq;
+
+  while (1)
+    {
+      struct timespec rt;
+      {
+#ifdef __NR_clock_gettime
+	INTERNAL_SYSCALL_DECL (err);
+	int ret;
+	ret = INTERNAL_SYSCALL (clock_gettime, err, 2,
+				(cond->__data.__nwaiters
+				 & ((1 << COND_CLOCK_BITS) - 1)),
+				&rt);
+# ifndef __ASSUME_POSIX_TIMERS
+	if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (ret, err), 0))
+	  {
+	    struct timeval tv;
+	    (void) gettimeofday (&tv, NULL);
+
+	    /* Convert the absolute timeout value to a relative timeout.  */
+	    rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+	    rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+	  }
+	else
+# endif
+	  {
+	    /* Convert the absolute timeout value to a relative timeout.  */
+	    rt.tv_sec = abstime->tv_sec - rt.tv_sec;
+	    rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
+	  }
+#else
+	/* Get the current time.  So far we support only one clock.  */
+	struct timeval tv;
+	(void) gettimeofday (&tv, NULL);
+
+	/* Convert the absolute timeout value to a relative timeout.  */
+	rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+	rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+#endif
+      }
+      if (rt.tv_nsec < 0)
+	{
+	  rt.tv_nsec += 1000000000;
+	  --rt.tv_sec;
+	}
+      /* Did we already time out?  */
+      if (__builtin_expect (rt.tv_sec < 0, 0))
+	{
+	  if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
+	    goto bc_out;
+
+	  goto timeout;
+	}
+
+      unsigned int futex_val = cond->__data.__futex;
+
+      /* Prepare to wait.  Release the condvar futex.  */
+      lll_mutex_unlock (cond->__data.__lock);
+
+      /* Enable asynchronous cancellation.  Required by the standard.  */
+      cbuffer.oldtype = __pthread_enable_asynccancel ();
+
+      /* Wait until woken by signal or broadcast.  */
+      err = lll_futex_timed_wait (&cond->__data.__futex,
+				  futex_val, &rt);
+
+      /* Disable asynchronous cancellation.  */
+      __pthread_disable_asynccancel (cbuffer.oldtype);
+
+      /* We are going to look at shared data again, so get the lock.  */
+      lll_mutex_lock(cond->__data.__lock);
+
+      /* If a broadcast happened, we are done.  */
+      if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
+	goto bc_out;
+
+      /* Check whether we are eligible for wakeup.  */
+      val = cond->__data.__wakeup_seq;
+      if (val != seq && cond->__data.__woken_seq != val)
+	break;
+
+      /* Not woken yet.  Maybe the time expired?  */
+      if (__builtin_expect (err == -ETIMEDOUT, 0))
+	{
+	timeout:
+	  /* Yep.  Adjust the counters.  */
+	  ++cond->__data.__wakeup_seq;
+	  ++cond->__data.__futex;
+
+	  /* The error value.  */
+	  result = ETIMEDOUT;
+	  break;
+	}
+    }
+
+  /* Another thread woken up.  */
+  ++cond->__data.__woken_seq;
+
+ bc_out:
+
+  cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;
+
+  /* If pthread_cond_destroy was called on this variable already,
+     notify the pthread_cond_destroy caller all waiters have left
+     and it can be successfully destroyed.  */
+  if (cond->__data.__total_seq == -1ULL
+      && cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
+    lll_futex_wake (&cond->__data.__nwaiters, 1);
+
+  /* We are done with the condvar.  */
+  lll_mutex_unlock (cond->__data.__lock);
+
+  /* The cancellation handling is back to normal, remove the handler.  */
+  __pthread_cleanup_pop (&buffer, 0);
+
+  /* Get the mutex before returning.  */
+  err = __pthread_mutex_cond_lock (mutex);
+
+  return err ?: result;
+}
+
+versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
+		  GLIBC_2_3_2);
diff --git a/nptl/sysdeps/pthread/pthread_cond_wait.c b/nptl/sysdeps/pthread/pthread_cond_wait.c
new file mode 100644
index 0000000000..f5f5cec5a8
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_cond_wait.c
@@ -0,0 +1,191 @@
+/* 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 <endian.h>
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <pthread.h>
+#include <pthreadP.h>
+
+#include <shlib-compat.h>
+
+
+struct _condvar_cleanup_buffer
+{
+  int oldtype;
+  pthread_cond_t *cond;
+  pthread_mutex_t *mutex;
+  unsigned int bc_seq;
+};
+
+
+void
+__attribute__ ((visibility ("hidden")))
+__condvar_cleanup (void *arg)
+{
+  struct _condvar_cleanup_buffer *cbuffer =
+    (struct _condvar_cleanup_buffer *) arg;
+  unsigned int destroying;
+
+  /* We are going to modify shared data.  */
+  lll_mutex_lock (cbuffer->cond->__data.__lock);
+
+  if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
+    {
+      /* This thread is not waiting anymore.  Adjust the sequence counters
+	 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.__nwaiters -= 1 << COND_CLOCK_BITS;
+
+  /* If pthread_cond_destroy was called on this variable already,
+     notify the pthread_cond_destroy caller all waiters have left
+     and it can be successfully destroyed.  */
+  destroying = 0;
+  if (cbuffer->cond->__data.__total_seq == -1ULL
+      && cbuffer->cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
+    {
+      lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1);
+      destroying = 1;
+    }
+
+  /* We are done.  */
+  lll_mutex_unlock (cbuffer->cond->__data.__lock);
+
+  /* Wake everybody to make sure no condvar signal gets lost.  */
+  if (! destroying)
+    lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX);
+
+  /* Get the mutex before returning unless asynchronous cancellation
+     is in effect.  */
+  __pthread_mutex_cond_lock (cbuffer->mutex);
+}
+
+
+int
+__pthread_cond_wait (cond, mutex)
+     pthread_cond_t *cond;
+     pthread_mutex_t *mutex;
+{
+  struct _pthread_cleanup_buffer buffer;
+  struct _condvar_cleanup_buffer cbuffer;
+  int err;
+
+  /* Make sure we are along.  */
+  lll_mutex_lock (cond->__data.__lock);
+
+  /* Now we can release the mutex.  */
+  err = __pthread_mutex_unlock_usercnt (mutex, 0);
+  if (__builtin_expect (err, 0))
+    {
+      lll_mutex_unlock (cond->__data.__lock);
+      return err;
+    }
+
+  /* We have one new user of the condvar.  */
+  ++cond->__data.__total_seq;
+  ++cond->__data.__futex;
+  cond->__data.__nwaiters += 1 << COND_CLOCK_BITS;
+
+  /* Remember the mutex we are using here.  If there is already a
+     different address store this is a bad user bug.  Do not store
+     anything for pshared condvars.  */
+  if (cond->__data.__mutex != (void *) ~0l)
+    cond->__data.__mutex = mutex;
+
+  /* Prepare structure passed to cancellation handler.  */
+  cbuffer.cond = cond;
+  cbuffer.mutex = mutex;
+
+  /* Before we block we enable cancellation.  Therefore we have to
+     install a cancellation handler.  */
+  __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer);
+
+  /* The current values of the wakeup counter.  The "woken" counter
+     must exceed this value.  */
+  unsigned long long int val;
+  unsigned long long int seq;
+  val = seq = cond->__data.__wakeup_seq;
+  /* Remember the broadcast counter.  */
+  cbuffer.bc_seq = cond->__data.__broadcast_seq;
+
+  do
+    {
+      unsigned int futex_val = cond->__data.__futex;
+
+      /* Prepare to wait.  Release the condvar futex.  */
+      lll_mutex_unlock (cond->__data.__lock);
+
+      /* Enable asynchronous cancellation.  Required by the standard.  */
+      cbuffer.oldtype = __pthread_enable_asynccancel ();
+
+      /* Wait until woken by signal or broadcast.  */
+      lll_futex_wait (&cond->__data.__futex, futex_val);
+
+      /* Disable asynchronous cancellation.  */
+      __pthread_disable_asynccancel (cbuffer.oldtype);
+
+      /* We are going to look at shared data again, so get the lock.  */
+      lll_mutex_lock (cond->__data.__lock);
+
+      /* If a broadcast happened, we are done.  */
+      if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
+	goto bc_out;
+
+      /* Check whether we are eligible for wakeup.  */
+      val = cond->__data.__wakeup_seq;
+    }
+  while (val == seq || cond->__data.__woken_seq == val);
+
+  /* Another thread woken up.  */
+  ++cond->__data.__woken_seq;
+
+ bc_out:
+
+  cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;
+
+  /* If pthread_cond_destroy was called on this varaible already,
+     notify the pthread_cond_destroy caller all waiters have left
+     and it can be successfully destroyed.  */
+  if (cond->__data.__total_seq == -1ULL
+      && cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
+    lll_futex_wake (&cond->__data.__nwaiters, 1);
+
+  /* We are done with the condvar.  */
+  lll_mutex_unlock (cond->__data.__lock);
+
+  /* The cancellation handling is back to normal, remove the handler.  */
+  __pthread_cleanup_pop (&buffer, 0);
+
+  /* Get the mutex before returning.  */
+  return __pthread_mutex_cond_lock (mutex);
+}
+
+versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
+		  GLIBC_2_3_2);
diff --git a/nptl/sysdeps/pthread/pthread_getcpuclockid.c b/nptl/sysdeps/pthread/pthread_getcpuclockid.c
new file mode 100644
index 0000000000..8506f94eb4
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_getcpuclockid.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2000, 2001, 2002, 2003 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>
+
+
+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 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/pthread/pthread_once.c b/nptl/sysdeps/pthread/pthread_once.c
new file mode 100644
index 0000000000..9b2cef8645
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_once.c
@@ -0,0 +1,54 @@
+/* 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 "pthreadP.h"
+#include <lowlevellock.h>
+
+
+
+static lll_lock_t once_lock = LLL_LOCK_INITIALIZER;
+
+
+int
+__pthread_once (once_control, init_routine)
+     pthread_once_t *once_control;
+     void (*init_routine) (void);
+{
+  /* XXX Depending on whether the LOCK_IN_ONCE_T is defined use a
+     global lock variable or one which is part of the pthread_once_t
+     object.  */
+  if (*once_control == PTHREAD_ONCE_INIT)
+    {
+      lll_lock (once_lock);
+
+      /* XXX This implementation is not complete.  It doesn't take
+	 cancelation and fork into account.  */
+      if (*once_control == PTHREAD_ONCE_INIT)
+	{
+	  init_routine ();
+
+	  *once_control = !PTHREAD_ONCE_INIT;
+	}
+
+      lll_unlock (once_lock);
+    }
+
+  return 0;
+}
+strong_alias (__pthread_once, pthread_once)
diff --git a/nptl/sysdeps/pthread/pthread_rwlock_rdlock.c b/nptl/sysdeps/pthread/pthread_rwlock_rdlock.c
new file mode 100644
index 0000000000..e225d7030d
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_rwlock_rdlock.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 2003, 2004 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 <pthread.h>
+#include <pthreadP.h>
+
+
+/* Acquire read lock for RWLOCK.  */
+int
+__pthread_rwlock_rdlock (rwlock)
+     pthread_rwlock_t *rwlock;
+{
+  int result = 0;
+
+  /* Make sure we are along.  */
+  lll_mutex_lock (rwlock->__data.__lock);
+
+  while (1)
+    {
+      /* Get the rwlock if there is no writer...  */
+      if (rwlock->__data.__writer == 0
+	  /* ...and if either no writer is waiting or we prefer readers.  */
+	  && (!rwlock->__data.__nr_writers_queued
+	      || rwlock->__data.__flags == 0))
+	{
+	  /* Increment the reader counter.  Avoid overflow.  */
+	  if (__builtin_expect (++rwlock->__data.__nr_readers == 0, 0))
+	    {
+	      /* Overflow on number of readers.	 */
+	      --rwlock->__data.__nr_readers;
+	      result = EAGAIN;
+	    }
+
+	  break;
+	}
+
+      /* Make sure we are not holding the rwlock as a writer.  This is
+	 a deadlock situation we recognize and report.  */
+      if (__builtin_expect (rwlock->__data.__writer
+			    == THREAD_GETMEM (THREAD_SELF, tid), 0))
+	{
+	  result = EDEADLK;
+	  break;
+	}
+
+      /* Remember that we are a reader.  */
+      if (__builtin_expect (++rwlock->__data.__nr_readers_queued == 0, 0))
+	{
+	  /* Overflow on number of queued readers.  */
+	  --rwlock->__data.__nr_readers_queued;
+	  result = EAGAIN;
+	  break;
+	}
+
+      int waitval = rwlock->__data.__readers_wakeup;
+
+      /* Free the lock.  */
+      lll_mutex_unlock (rwlock->__data.__lock);
+
+      /* Wait for the writer to finish.  */
+      lll_futex_wait (&rwlock->__data.__readers_wakeup, waitval);
+
+      /* Get the lock.  */
+      lll_mutex_lock (rwlock->__data.__lock);
+
+      --rwlock->__data.__nr_readers_queued;
+    }
+
+  /* We are done, free the lock.  */
+  lll_mutex_unlock (rwlock->__data.__lock);
+
+  return result;
+}
+
+weak_alias (__pthread_rwlock_rdlock, pthread_rwlock_rdlock)
+strong_alias (__pthread_rwlock_rdlock, __pthread_rwlock_rdlock_internal)
diff --git a/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c b/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c
new file mode 100644
index 0000000000..80ea83a3dd
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c
@@ -0,0 +1,137 @@
+/* Copyright (C) 2003, 2004 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 <pthread.h>
+#include <pthreadP.h>
+
+
+/* Try to acquire read lock for RWLOCK or return after specfied time.  */
+int
+pthread_rwlock_timedrdlock (rwlock, abstime)
+     pthread_rwlock_t *rwlock;
+     const struct timespec *abstime;
+{
+  int result = 0;
+
+  /* Make sure we are along.  */
+  lll_mutex_lock(rwlock->__data.__lock);
+
+  while (1)
+    {
+      int err;
+
+      /* Get the rwlock if there is no writer...  */
+      if (rwlock->__data.__writer == 0
+	  /* ...and if either no writer is waiting or we prefer readers.  */
+	  && (!rwlock->__data.__nr_writers_queued
+	      || rwlock->__data.__flags == 0))
+	{
+	  /* Increment the reader counter.  Avoid overflow.  */
+	  if (++rwlock->__data.__nr_readers == 0)
+	    {
+	      /* Overflow on number of readers.	 */
+	      --rwlock->__data.__nr_readers;
+	      result = EAGAIN;
+	    }
+
+	  break;
+	}
+
+      /* Make sure we are not holding the rwlock as a writer.  This is
+	 a deadlock situation we recognize and report.  */
+      if (__builtin_expect (rwlock->__data.__writer
+			    == THREAD_GETMEM (THREAD_SELF, tid), 0))
+	{
+	  result = EDEADLK;
+	  break;
+	}
+
+      /* Make sure the passed in timeout value is valid.  Ideally this
+	 test would be executed once.  But since it must not be
+	 performed if we would not block at all simply moving the test
+	 to the front is no option.  Replicating all the code is
+	 costly while this test is not.  */
+      if (__builtin_expect (abstime->tv_nsec >= 1000000000
+                            || abstime->tv_nsec < 0, 0))
+	{
+	  result = EINVAL;
+	  break;
+	}
+
+      /* Get the current time.  So far we support only one clock.  */
+      struct timeval tv;
+      (void) gettimeofday (&tv, NULL);
+
+      /* Convert the absolute timeout value to a relative timeout.  */
+      struct timespec rt;
+      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;
+	}
+      /* Did we already time out?  */
+      if (rt.tv_sec < 0)
+	{
+	  /* Yep, return with an appropriate error.  */
+	  result = ETIMEDOUT;
+	  break;
+	}
+
+      /* Remember that we are a reader.  */
+      if (++rwlock->__data.__nr_readers_queued == 0)
+	{
+	  /* Overflow on number of queued readers.  */
+	  --rwlock->__data.__nr_readers_queued;
+	  result = EAGAIN;
+	  break;
+	}
+
+      int waitval = rwlock->__data.__readers_wakeup;
+
+      /* Free the lock.  */
+      lll_mutex_unlock (rwlock->__data.__lock);
+
+      /* Wait for the writer to finish.  */
+      err = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup,
+				  waitval, &rt);
+
+      /* Get the lock.  */
+      lll_mutex_lock (rwlock->__data.__lock);
+
+      --rwlock->__data.__nr_readers_queued;
+
+      /* Did the futex call time out?  */
+      if (err == -ETIMEDOUT)
+	{
+	  /* Yep, report it.  */
+	  result = ETIMEDOUT;
+	  break;
+	}
+    }
+
+  /* We are done, free the lock.  */
+  lll_mutex_unlock (rwlock->__data.__lock);
+
+  return result;
+}
diff --git a/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c b/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c
new file mode 100644
index 0000000000..97c0598f96
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c
@@ -0,0 +1,127 @@
+/* Copyright (C) 2003, 2004 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 <pthread.h>
+#include <pthreadP.h>
+
+
+/* Try to acquire write lock for RWLOCK or return after specfied time.	*/
+int
+pthread_rwlock_timedwrlock (rwlock, abstime)
+     pthread_rwlock_t *rwlock;
+     const struct timespec *abstime;
+{
+  int result = 0;
+
+  /* Make sure we are along.  */
+  lll_mutex_lock (rwlock->__data.__lock);
+
+  while (1)
+    {
+      int err;
+
+      /* Get the rwlock if there is no writer and no reader.  */
+      if (rwlock->__data.__writer == 0 && rwlock->__data.__nr_readers == 0)
+	{
+	  /* Mark self as writer.  */
+	  rwlock->__data.__writer = THREAD_GETMEM (THREAD_SELF, tid);
+	  break;
+	}
+
+      /* Make sure we are not holding the rwlock as a writer.  This is
+	 a deadlock situation we recognize and report.  */
+      if (__builtin_expect (rwlock->__data.__writer
+			    == THREAD_GETMEM (THREAD_SELF, tid), 0))
+	{
+	  result = EDEADLK;
+	  break;
+	}
+
+      /* Make sure the passed in timeout value is valid.  Ideally this
+	 test would be executed once.  But since it must not be
+	 performed if we would not block at all simply moving the test
+	 to the front is no option.  Replicating all the code is
+	 costly while this test is not.  */
+      if (__builtin_expect (abstime->tv_nsec >= 1000000000
+                            || abstime->tv_nsec < 0, 0))
+	{
+	  result = EINVAL;
+	  break;
+	}
+
+      /* Get the current time.  So far we support only one clock.  */
+      struct timeval tv;
+      (void) gettimeofday (&tv, NULL);
+
+      /* Convert the absolute timeout value to a relative timeout.  */
+      struct timespec rt;
+      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;
+	}
+      /* Did we already time out?  */
+      if (rt.tv_sec < 0)
+	{
+	  result = ETIMEDOUT;
+	  break;
+	}
+
+      /* Remember that we are a writer.  */
+      if (++rwlock->__data.__nr_writers_queued == 0)
+	{
+	  /* Overflow on number of queued writers.  */
+	  --rwlock->__data.__nr_writers_queued;
+	  result = EAGAIN;
+	  break;
+	}
+
+      int waitval = rwlock->__data.__writer_wakeup;
+
+      /* Free the lock.  */
+      lll_mutex_unlock (rwlock->__data.__lock);
+
+      /* Wait for the writer or reader(s) to finish.  */
+      err = lll_futex_timed_wait (&rwlock->__data.__writer_wakeup,
+				  waitval, &rt);
+
+      /* Get the lock.  */
+      lll_mutex_lock (rwlock->__data.__lock);
+
+      /* To start over again, remove the thread from the writer list.  */
+      --rwlock->__data.__nr_writers_queued;
+
+      /* Did the futex call time out?  */
+      if (err == -ETIMEDOUT)
+	{
+	  result = ETIMEDOUT;
+	  break;
+	}
+    }
+
+  /* We are done, free the lock.  */
+  lll_mutex_unlock (rwlock->__data.__lock);
+
+  return result;
+}
diff --git a/nptl/sysdeps/pthread/pthread_rwlock_unlock.c b/nptl/sysdeps/pthread/pthread_rwlock_unlock.c
new file mode 100644
index 0000000000..9cae8b6c22
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_rwlock_unlock.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2003 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 <pthread.h>
+#include <pthreadP.h>
+
+/* Unlock RWLOCK.  */
+int
+__pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
+{
+  lll_mutex_lock (rwlock->__data.__lock);
+  if (rwlock->__data.__writer)
+    rwlock->__data.__writer = 0;
+  else
+    --rwlock->__data.__nr_readers;
+  if (rwlock->__data.__nr_readers == 0)
+    {
+      if (rwlock->__data.__nr_writers_queued)
+	{
+	  ++rwlock->__data.__writer_wakeup;
+	  lll_mutex_unlock (rwlock->__data.__lock);
+	  lll_futex_wake (&rwlock->__data.__writer_wakeup, 1);
+	  return 0;
+	}
+      else if (rwlock->__data.__nr_readers_queued)
+	{
+	  ++rwlock->__data.__readers_wakeup;
+	  lll_mutex_unlock (rwlock->__data.__lock);
+	  lll_futex_wake (&rwlock->__data.__readers_wakeup, INT_MAX);
+	  return 0;
+	}
+    }
+  lll_mutex_unlock (rwlock->__data.__lock);
+  return 0;
+}
+
+weak_alias (__pthread_rwlock_unlock, pthread_rwlock_unlock)
+strong_alias (__pthread_rwlock_unlock, __pthread_rwlock_unlock_internal)
diff --git a/nptl/sysdeps/pthread/pthread_rwlock_wrlock.c b/nptl/sysdeps/pthread/pthread_rwlock_wrlock.c
new file mode 100644
index 0000000000..822aeed79c
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_rwlock_wrlock.c
@@ -0,0 +1,87 @@
+/* Copyright (C) 2003 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 <pthread.h>
+#include <pthreadP.h>
+
+
+/* Acquire write lock for RWLOCK.  */
+int
+__pthread_rwlock_wrlock (rwlock)
+     pthread_rwlock_t *rwlock;
+{
+  int result = 0;
+
+  /* Make sure we are along.  */
+  lll_mutex_lock (rwlock->__data.__lock);
+
+  while (1)
+    {
+      /* Get the rwlock if there is no writer and no reader.  */
+      if (rwlock->__data.__writer == 0 && rwlock->__data.__nr_readers == 0)
+	{
+	  /* Mark self as writer.  */
+	  rwlock->__data.__writer = THREAD_GETMEM (THREAD_SELF, tid);
+	  break;
+	}
+
+      /* Make sure we are not holding the rwlock as a writer.  This is
+	 a deadlock situation we recognize and report.  */
+      if (__builtin_expect (rwlock->__data.__writer
+			    == THREAD_GETMEM (THREAD_SELF, tid), 0))
+	{
+	  result = EDEADLK;
+	  break;
+	}
+
+      /* Remember that we are a writer.  */
+      if (++rwlock->__data.__nr_writers_queued == 0)
+	{
+	  /* Overflow on number of queued writers.  */
+	  --rwlock->__data.__nr_writers_queued;
+	  result = EAGAIN;
+	  break;
+	}
+
+      int waitval = rwlock->__data.__writer_wakeup;
+
+      /* Free the lock.  */
+      lll_mutex_unlock (rwlock->__data.__lock);
+
+      /* Wait for the writer or reader(s) to finish.  */
+      lll_futex_wait (&rwlock->__data.__writer_wakeup, waitval);
+
+      /* Get the lock.  */
+      lll_mutex_lock (rwlock->__data.__lock);
+
+      /* To start over again, remove the thread from the writer list.  */
+      --rwlock->__data.__nr_writers_queued;
+    }
+
+  /* We are done, free the lock.  */
+  lll_mutex_unlock (rwlock->__data.__lock);
+
+  return result;
+}
+
+weak_alias (__pthread_rwlock_wrlock, pthread_rwlock_wrlock)
+strong_alias (__pthread_rwlock_wrlock, __pthread_rwlock_wrlock_internal)
diff --git a/nptl/sysdeps/pthread/pthread_spin_destroy.c b/nptl/sysdeps/pthread/pthread_spin_destroy.c
new file mode 100644
index 0000000000..4d0109cf02
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_spin_destroy.c
@@ -0,0 +1,29 @@
+/* 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 "pthreadP.h"
+
+
+int
+pthread_spin_destroy (lock)
+     pthread_spinlock_t *lock;
+{
+  /* Nothing to do.  */
+  return 0;
+}
diff --git a/nptl/sysdeps/pthread/pthread_spin_init.c b/nptl/sysdeps/pthread/pthread_spin_init.c
new file mode 100644
index 0000000000..c2275085e8
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_spin_init.c
@@ -0,0 +1,28 @@
+/* pthread_spin_init -- initialize a spin lock.  Generic version.
+   Copyright (C) 2003 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 "pthreadP.h"
+
+int
+pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  *lock = 0;
+  return 0;
+}
diff --git a/nptl/sysdeps/pthread/pthread_spin_unlock.c b/nptl/sysdeps/pthread/pthread_spin_unlock.c
new file mode 100644
index 0000000000..f97cadfbd0
--- /dev/null
+++ b/nptl/sysdeps/pthread/pthread_spin_unlock.c
@@ -0,0 +1,30 @@
+/* pthread_spin_unlock -- unlock a spin lock.  Generic version.
+   Copyright (C) 2003 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 "pthreadP.h"
+#include <atomic.h>
+
+int
+pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  atomic_full_barrier ();
+  *lock = 0;
+  return 0;
+}
diff --git a/nptl/sysdeps/s390/tls.h b/nptl/sysdeps/s390/tls.h
index 6f6f17b975..8e8f86d64e 100644
--- a/nptl/sysdeps/s390/tls.h
+++ b/nptl/sysdeps/s390/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  NPTL/s390 version.
-   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -50,6 +50,7 @@ typedef struct
   int multiple_threads;
   uintptr_t sysinfo;
   uintptr_t stack_guard;
+  int gscope_flag;
 } tcbhead_t;
 
 # ifndef __s390x__
@@ -66,6 +67,9 @@ typedef struct
 # error "TLS support is required."
 #endif
 
+/* Signal that TLS support is available.  */
+#define USE_TLS	1
+
 /* Alignment requirement for the stack.  For IA-32 this is governed by
    the SSE memory functions.  */
 #define STACK_ALIGN	16
@@ -168,6 +172,29 @@ typedef struct
 #define THREAD_SET_POINTER_GUARD(value)
 #define THREAD_COPY_POINTER_GUARD(descr)
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
+			       THREAD_GSCOPE_FLAG_UNUSED);		     \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/sh/tls.h b/nptl/sysdeps/sh/tls.h
index d9aa1073b8..2873fe73a8 100644
--- a/nptl/sysdeps/sh/tls.h
+++ b/nptl/sysdeps/sh/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  NPTL/SH version.
-   Copyright (C) 2003, 2005, 2006 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
@@ -56,6 +56,9 @@ typedef struct
 # error "TLS support is required."
 #endif
 
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
 #ifndef __ASSEMBLER__
 
 /* Get system call information.  */
@@ -150,6 +153,29 @@ typedef struct
      __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));			      \
      ((tcbhead_t *) (descr + 1))->pointer_guard	= __tcbp->pointer_guard;})
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
+			       THREAD_GSCOPE_FLAG_UNUSED);		     \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/sparc/tls.h b/nptl/sysdeps/sparc/tls.h
index 4fbe426595..90a3e0bf3d 100644
--- a/nptl/sysdeps/sparc/tls.h
+++ b/nptl/sysdeps/sparc/tls.h
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  NPTL/sparc version.
-   Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -46,9 +46,15 @@ typedef struct
   dtv_t *dtv;
   void *self;
   int multiple_threads;
+#if __WORDSIZE == 64
+  int gscope_flag;
+#endif
   uintptr_t sysinfo;
   uintptr_t stack_guard;
   uintptr_t pointer_guard;
+#if __WORDSIZE != 64
+  int gscope_flag;
+#endif
 } tcbhead_t;
 
 #else /* __ASSEMBLER__ */
@@ -60,6 +66,9 @@ typedef struct
 # error "TLS support is required."
 #endif
 
+/* Signal that TLS support is available.  */
+#define USE_TLS	1
+
 #ifndef __ASSEMBLER__
 /* Get system call information.  */
 # include <sysdep.h>
@@ -141,6 +150,29 @@ register struct pthread *__thread_self __asm__("%g7");
 # define THREAD_COPY_POINTER_GUARD(descr) \
   ((descr)->header.pointer_guard = THREAD_GET_POINTER_GUARD ())
 
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
+			       THREAD_GSCOPE_FLAG_UNUSED);		     \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* !ASSEMBLER */
 
 #endif	/* tls.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h
index 9b27b1ff48..e0718780cc 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h
@@ -87,6 +87,3 @@
 
 /* Maximum message queue priority level.  */
 #define MQ_PRIO_MAX		32768
-
-/* Maximum value the semaphore can have.  */
-#define SEM_VALUE_MAX   (2147483647)
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h
index be4469c69d..6dadfda206 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h
@@ -26,6 +26,9 @@
 /* Value returned if `sem_open' failed.  */
 #define SEM_FAILED      ((sem_t *) 0)
 
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   (2147483647)
+
 
 typedef union
 {
diff --git a/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h
index 4b7b29787e..b639ba44af 100644
--- a/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h
+++ b/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h
@@ -87,6 +87,3 @@
 
 /* Maximum message queue priority level.  */
 #define MQ_PRIO_MAX		32768
-
-/* Maximum value the semaphore can have.  */
-#define SEM_VALUE_MAX   (2147483647)
diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c
index 840974401b..98bb237c06 100644
--- a/nptl/sysdeps/unix/sysv/linux/fork.c
+++ b/nptl/sysdeps/unix/sysv/linux/fork.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -167,8 +167,11 @@ __libc_fork (void)
 	    allp->handler->child_handler ();
 
 	  /* Note that we do not have to wake any possible waiter.
-	     This is the only thread in the new process.  */
-	  --allp->handler->refcntr;
+ 	     This is the only thread in the new process.  The count
+ 	     may have been bumped up by other threads doing a fork.
+ 	     We reset it to 1, to avoid waiting for non-existing
+ 	     thread(s) to release the count.  */
+	  allp->handler->refcntr = 1;
 
 	  /* XXX We could at this point look through the object pool
 	     and mark all objects not on the __fork_handlers list as
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h
index 934493c308..e6c5d845ce 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h
@@ -28,6 +28,9 @@
 /* Value returned if `sem_open' failed.  */
 #define SEM_FAILED      ((sem_t *) 0)
 
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   (2147483647)
+
 
 typedef union
 {
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
index aa1f9f41ca..bf70e17fca 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -79,10 +79,7 @@ sem_timedwait:
 	jae	6f
 
 	cfi_offset(3, -16)		/* %ebx */
-7:	call	__pthread_enable_asynccancel
-	movl	%eax, 8(%esp)
-
-	xorl	%ecx, %ecx
+7:	xorl	%ecx, %ecx
 	movl	%esp, %ebx
 	movl	%ecx, %edx
 	movl	$SYS_gettimeofday, %eax
@@ -105,6 +102,10 @@ sem_timedwait:
 
 	movl	%ecx, (%esp)	/* Store relative timeout.  */
 	movl	%edx, 4(%esp)
+
+	call	__pthread_enable_asynccancel
+	movl	%eax, 8(%esp)
+
 	movl	28(%esp), %ebx
 	xorl	%ecx, %ecx
 	movl	%esp, %esi
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
index 1cd4b9b8b6..d60dcd33d5 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
@@ -58,7 +58,6 @@
 # define SAVE_OLDTYPE_3	SAVE_OLDTYPE_2
 # define SAVE_OLDTYPE_4	SAVE_OLDTYPE_2
 # define SAVE_OLDTYPE_5	SAVE_OLDTYPE_2
-# define SAVE_OLDTYPE_6	SAVE_OLDTYPE_2
 
 # define PUSHCARGS_0	/* No arguments to push.  */
 # define DOCARGS_0	/* No arguments to frob.  */
@@ -102,14 +101,6 @@
 # define _POPCARGS_5	_POPCARGS_4; popl %edi; \
 			cfi_adjust_cfa_offset (-4); cfi_restore (edi);
 
-# define PUSHCARGS_6	_PUSHCARGS_6
-# define DOCARGS_6	_DOARGS_6 (44)
-# define POPCARGS_6	_POPCARGS_6
-# define _PUSHCARGS_6	pushl %ebp; cfi_adjust_cfa_offset (4); \
-			cfi_rel_offset (ebp, 0); _PUSHCARGS_5
-# define _POPCARGS_6	_POPCARGS_5; popl %ebp; \
-			cfi_adjust_cfa_offset (-4); cfi_restore (ebp);
-
 # ifdef IS_IN_libpthread
 #  define CENABLE	call __pthread_enable_asynccancel;
 #  define CDISABLE	call __pthread_disable_asynccancel
@@ -131,7 +122,6 @@
 # define POPSTATE_3	POPSTATE_2
 # define POPSTATE_4	POPSTATE_3
 # define POPSTATE_5	POPSTATE_4
-# define POPSTATE_6	POPSTATE_5
 
 # ifndef __ASSEMBLER__
 #  define SINGLE_THREAD_P \
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h
index 83db31efcb..f837250b95 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h
@@ -87,6 +87,3 @@
 
 /* Maximum message queue priority level.  */
 #define MQ_PRIO_MAX		32768
-
-/* Maximum value the semaphore can have.  */
-#define SEM_VALUE_MAX   (2147483647)
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/ia64/bits/semaphore.h
index 0684aebe24..2329e98667 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/bits/semaphore.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/bits/semaphore.h
@@ -28,6 +28,9 @@
 /* Value returned if `sem_open' failed.  */
 #define SEM_FAILED      ((sem_t *) 0)
 
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   (2147483647)
+
 
 typedef union
 {
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
index 3e88ee1866..30ef991bd0 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
 
@@ -30,6 +30,10 @@ __lll_robust_lock_wait (int *futex)
   int oldval = *futex;
   int tid = THREAD_GETMEM (THREAD_SELF, tid);
 
+  /* If the futex changed meanwhile try locking again.  */
+  if (oldval == 0)
+    goto try;
+
   do
     {
       if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
@@ -41,6 +45,9 @@ __lll_robust_lock_wait (int *futex)
 	continue;
 
       lll_futex_wait (futex, newval);
+
+    try:
+      ;
     }
   while ((oldval = atomic_compare_and_exchange_val_acq (futex,
 							tid | FUTEX_WAITERS,
@@ -57,6 +64,11 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
     return EINVAL;
 
   int tid = THREAD_GETMEM (THREAD_SELF, tid);
+  int oldval = *futex;
+
+  /* If the futex changed meanwhile try locking again.  */
+  if (oldval == 0)
+    goto try;
 
   do
     {
@@ -80,7 +92,6 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
 	return ETIMEDOUT;
 
       /* Wait.  */
-      int oldval = *futex;
       if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
 	return oldval;
 
@@ -90,8 +101,13 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
 	continue;
 
       lll_futex_timed_wait (futex, newval, &rt);
+
+    try:
+      ;
     }
-  while (atomic_compare_and_exchange_bool_acq (futex, tid | FUTEX_WAITERS, 0));
+  while ((oldval = atomic_compare_and_exchange_val_acq (futex,
+							tid | FUTEX_WAITERS,
+							0)) != 0);
 
   return 0;
 }
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/Versions b/nptl/sysdeps/unix/sysv/linux/powerpc/Versions
index 6b5a0362da..9977847984 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/Versions
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/Versions
@@ -2,8 +2,4 @@ libpthread {
   GLIBC_2.3.4 {
     longjmp; siglongjmp;
   }
-  GLIBC_2.6 {
-    # Changed PTHREAD_STACK_MIN.
-    pthread_attr_setstack; pthread_attr_setstacksize;
-  }
 }
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h
deleted file mode 100644
index 02e2d17343..0000000000
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* 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
-
-/* Maximum value the semaphore can have.  */
-#define SEM_VALUE_MAX   (2147483647)
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h
index c7f121ba5b..8123b418b5 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h
@@ -33,6 +33,9 @@
 /* Value returned if `sem_open' failed.  */
 #define SEM_FAILED      ((sem_t *) 0)
 
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   (2147483647)
+
 
 typedef union
 {
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstack.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstack.c
deleted file mode 100644
index 2cb0a13bcb..0000000000
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstack.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define NEW_VERNUM GLIBC_2_6
-#include <nptl/pthread_attr_setstack.c>
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c
deleted file mode 100644
index 9472dd17ef..0000000000
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#define NEW_VERNUM GLIBC_2_6
-#define STACKSIZE_ADJUST \
-  do {									      \
-    size_t ps = __getpagesize ();					      \
-    if (stacksize < 2 * ps)						      \
-      stacksize = 2 * ps;						      \
-  } while (0)
-#include <nptl/pthread_attr_setstacksize.c>
diff --git a/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h b/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
index 6b3d3682da..39db5a3bd4 100644
--- a/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
+++ b/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
@@ -1,5 +1,5 @@
 /* Defintions for lowlevel handling in ld.so.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/s390/bits/semaphore.h
index 111462f0fb..ead2663047 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/bits/semaphore.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/bits/semaphore.h
@@ -32,6 +32,9 @@
 /* Value returned if `sem_open' failed.  */
 #define SEM_FAILED      ((sem_t *) 0)
 
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   (2147483647)
+
 
 typedef union
 {
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
index 6b0240243a..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
@@ -45,13 +45,7 @@ L(pseudo_cancel):							      \
 	bas	%r14,0(%r1,%r13);					      \
 	lr	%r0,%r2;						      \
 	LM_##args							      \
-	.if SYS_ify (syscall_name) < 256;				      \
-	svc SYS_ify (syscall_name);					      \
-	.else;								      \
-	lhi %r1,SYS_ify (syscall_name);					      \
-	svc 0;								      \
-	.endif;								      \
-	LR7_##args							      \
+	DO_CALL(syscall_name, args);					      \
 	l	%r1,2f-0b(%r13);					      \
 	lr	%r12,%r2;						      \
 	lr	%r2,%r0;						      \
@@ -95,7 +89,6 @@ L(pseudo_end):
 #define STM_3		stm %r2,%r4,8(%r15);
 #define STM_4		stm %r2,%r5,8(%r15);
 #define STM_5		stm %r2,%r5,8(%r15);
-#define STM_6		stm %r2,%r7,8(%r15);
 
 #define LM_0		/* Nothing */
 #define LM_1		l %r2,8+96(%r15);
@@ -103,18 +96,6 @@ L(pseudo_end):
 #define LM_3		lm %r2,%r4,8+96(%r15);
 #define LM_4		lm %r2,%r5,8+96(%r15);
 #define LM_5		lm %r2,%r5,8+96(%r15);
-#define LM_6		lm %r2,%r5,8+96(%r15); \
-			cfi_offset (%r7, -68); \
-			l %r7,96+96(%r15);
-
-#define LR7_0		/* Nothing */
-#define LR7_1		/* Nothing */
-#define LR7_2		/* Nothing */
-#define LR7_3		/* Nothing */
-#define LR7_4		/* Nothing */
-#define LR7_5		/* Nothing */
-#define LR7_6		l %r7,28+96(%r15); \
-			cfi_restore (%r7);
 
 # ifndef __ASSEMBLER__
 #  define SINGLE_THREAD_P \
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 70d5a86429..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
@@ -42,13 +42,7 @@ L(pseudo_cancel):							      \
 	brasl	%r14,CENABLE;						      \
 	lgr	%r0,%r2;						      \
 	LM_##args							      \
-	.if SYS_ify (syscall_name) < 256;				      \
-	svc SYS_ify (syscall_name);					      \
-	.else;								      \
-	lghi %r1,SYS_ify (syscall_name);				      \
-	svc 0;								      \
-	.endif;								      \
-	LR7_##args							      \
+	DO_CALL(syscall_name, args);					      \
 	lgr	%r13,%r2;						      \
 	lgr	%r2,%r0;						      \
 	brasl	%r14,CDISABLE;						      \
@@ -91,7 +85,6 @@ L(pseudo_end):
 #define STM_3		stmg %r2,%r4,16(%r15);
 #define STM_4		stmg %r2,%r5,16(%r15);
 #define STM_5		stmg %r2,%r5,16(%r15);
-#define STM_6		stmg %r2,%r7,16(%r15);
 
 #define LM_0		/* Nothing */
 #define LM_1		lg %r2,16+160(%r15);
@@ -99,18 +92,6 @@ L(pseudo_end):
 #define LM_3		lmg %r2,%r4,16+160(%r15);
 #define LM_4		lmg %r2,%r5,16+160(%r15);
 #define LM_5		lmg %r2,%r5,16+160(%r15);
-#define LM_6		lmg %r2,%r5,16+160(%r15); \
-			cfi_offset (%r7, -104); \
-			lg %r7,160+160(%r15);
-
-#define LR7_0		/* Nothing */
-#define LR7_1		/* Nothing */
-#define LR7_2		/* Nothing */
-#define LR7_3		/* Nothing */
-#define LR7_4		/* Nothing */
-#define LR7_5		/* Nothing */
-#define LR7_6		lg %r7,56+160(%r15); \
-			cfi_restore (%r7);
 
 # if defined IS_IN_libpthread || !defined NOT_IN_libc
 #  ifndef __ASSEMBLER__
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h
index 934493c308..e6c5d845ce 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h
@@ -28,6 +28,9 @@
 /* Value returned if `sem_open' failed.  */
 #define SEM_FAILED      ((sem_t *) 0)
 
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   (2147483647)
+
 
 typedef union
 {
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h
index 2576f121c3..e082ea8f04 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h
@@ -87,6 +87,3 @@
 
 /* Maximum message queue priority level.  */
 #define MQ_PRIO_MAX		32768
-
-/* Maximum value the semaphore can have.  */
-#define SEM_VALUE_MAX   (2147483647)
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h
index 8fd7d344ea..7f3a328326 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h
@@ -33,6 +33,9 @@
 /* Value returned if `sem_open' failed.  */
 #define SEM_FAILED      ((sem_t *) 0)
 
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   (2147483647)
+
 
 typedef union
 {
diff --git a/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
index 55d20eb8f8..7613863bba 100644
--- 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
@@ -1 +1 @@
-#include "../../../../../../../pthread_barrier_wait.c"
+#include "../../../../../../pthread/pthread_barrier_wait.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h
index e973bc5bfb..57edbbbfb3 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h
@@ -33,6 +33,9 @@
 /* Value returned if `sem_open' failed.  */
 #define SEM_FAILED      ((sem_t *) 0)
 
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   (2147483647)
+
 
 typedef union
 {
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
index 90f10e6f4f..394dec8d82 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -164,7 +164,7 @@ __lll_mutex_timedlock_wait:
 8:				/* NB: %edx == 2 */
 	xorl	%eax, %eax
 	LOCK
-	cmpxchgl %edx, (%rdi)
+	cmpxchgl %edx, (%r12)
 	jnz	7f
 
 6:	addq	$16, %rsp
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index 4030bb7fb8..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, 2006, 2007 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,7 +35,6 @@
 #define SYS_futex		202
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
-#define FUTEX_CMP_REQUEUE	4
 #define FUTEX_LOCK_PI		6
 #define FUTEX_UNLOCK_PI		7
 #define FUTEX_TRYLOCK_PI	8
@@ -151,7 +150,7 @@ LLL_STUB_UNWIND_INFO_END
 #define lll_futex_wait(futex, val) \
   ({									      \
     int __status;							      \
-    register __typeof (val) _val __asm ("edx") = (val);			      \
+    register __typeof (val) _val asm ("edx") = (val);			      \
     __asm __volatile ("xorq %%r10, %%r10\n\t"				      \
 		      "syscall"						      \
 		      : "=a" (__status)					      \
@@ -164,22 +163,22 @@ LLL_STUB_UNWIND_INFO_END
 
 #define lll_futex_timed_wait(futex, val, timeout)			      \
   ({									      \
-    register const struct timespec *__to __asm ("r10") = timeout;	      \
+    register const struct timespec *__to __asm__ ("r10") = timeout;	      \
     int __status;							      \
-    register __typeof (val) _val __asm ("edx") = (val);			      \
+    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;								      \
+    __status;								      \
   })
 
 
 #define lll_futex_wake(futex, nr) \
   do {									      \
     int __ignore;							      \
-    register __typeof (nr) _nr __asm ("edx") = (nr);			      \
+    register __typeof (nr) _nr asm ("edx") = (nr);			      \
     __asm __volatile ("syscall"						      \
 		      : "=a" (__ignore)					      \
 		      : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAKE),	      \
@@ -424,21 +423,6 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
 			      : "cx", "r11", "cc", "memory"); })
 
 
-/* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val) \
-  ({ int __res;								      \
-     register int __nr_move __asm ("r10") = nr_move;			      \
-     register void *__mutex __asm ("r8") = mutex;			      \
-     register int __val __asm ("r9") = val;				      \
-     __asm __volatile ("syscall"					      \
-		       : "=a" (__res)					      \
-		       : "0" (__NR_futex), "D" ((void *) ftx),		      \
-		         "S" (FUTEX_CMP_REQUEUE), "d" (nr_wake),	      \
-		         "r" (__nr_move), "r" (__mutex), "r" (__val)	      \
-		       : "cx", "r11", "cc", "memory");			      \
-     __res < 0; })
-
-
 #define lll_mutex_islocked(futex) \
   (futex != LLL_MUTEX_LOCK_INITIALIZER)
 
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
index c44d3f5e77..51136cf2dc 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -79,10 +79,7 @@ sem_timedwait:
 	cfi_offset(14, -24)		/* %r14 */
 	jae	6f
 
-7:	call	__pthread_enable_asynccancel
-	movl	%eax, 16(%rsp)
-
-	xorl	%esi, %esi
+7:	xorl	%esi, %esi
 	movq	%rsp, %rdi
 	movq	$VSYSCALL_ADDR_vgettimeofday, %rax
 	callq	*%rax
@@ -105,6 +102,9 @@ sem_timedwait:
 	movq	%rdi, (%rsp)	/* Store relative timeout.  */
 	movq	%rsi, 8(%rsp)
 
+	call	__pthread_enable_asynccancel
+	movl	%eax, 16(%rsp)
+
 	movq	%rsp, %r10
 	movq	%r12, %rdi
 	xorl	%esi, %esi
diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
index 7618573e0b..b6385b135c 100644
--- a/nptl/sysdeps/x86_64/tls.h
+++ b/nptl/sysdeps/x86_64/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  nptl/x86_64 version.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -47,6 +47,7 @@ typedef struct
   dtv_t *dtv;
   void *self;		/* Pointer to the thread descriptor.  */
   int multiple_threads;
+  int gscope_flag;
   uintptr_t sysinfo;
   uintptr_t stack_guard;
   uintptr_t pointer_guard;
@@ -62,6 +63,9 @@ typedef struct
 # error "TLS support is required."
 #endif
 
+/* Signal that TLS support is available.  */
+#define USE_TLS	1
+
 /* Alignment requirement for the stack.  */
 #define STACK_ALIGN	16
 
@@ -336,6 +340,26 @@ typedef struct
    = THREAD_GETMEM (THREAD_SELF, header.pointer_guard))
 
 
+/* Get and set the global scope generation counter in the TCB head.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									      \
+    { int __res;							      \
+      asm volatile ("xchgl %0, %%fs:%P1"				      \
+		    : "=r" (__res)					      \
+		    : "i" (offsetof (struct pthread, header.gscope_flag)),    \
+		      "0" (THREAD_GSCOPE_FLAG_UNUSED));			      \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				      \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);		      \
+    }									      \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
 #endif /* __ASSEMBLER__ */
 
 #endif	/* tls.h */