Browse Source

mass sync with glibc nptl

Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
Austin Foxley 15 years ago
parent
commit
a032a65870
100 changed files with 8389 additions and 1060 deletions
  1. 1 0
      .gitignore
  2. 336 60
      include/atomic.h
  3. 3 0
      libpthread/nptl/.gitignore
  4. 3830 0
      libpthread/nptl/ChangeLog
  5. 44 0
      libpthread/nptl/DESIGN-barrier.txt
  6. 134 0
      libpthread/nptl/DESIGN-condvar.txt
  7. 113 0
      libpthread/nptl/DESIGN-rwlock.txt
  8. 46 0
      libpthread/nptl/DESIGN-sem.txt
  9. 7 0
      libpthread/nptl/Makefile.in
  10. 31 0
      libpthread/nptl/TODO
  11. 20 0
      libpthread/nptl/TODO-kernel
  12. 20 0
      libpthread/nptl/TODO-testing
  13. 421 130
      libpthread/nptl/allocatestack.c
  14. 15 5
      libpthread/nptl/cancellation.c
  15. 122 17
      libpthread/nptl/descr.h
  16. 7 25
      libpthread/nptl/forward.c
  17. 142 35
      libpthread/nptl/init.c
  18. 4 95
      libpthread/nptl/libc-cancellation.c
  19. 2 2
      libpthread/nptl/pt-cleanup.c
  20. 1 1
      libpthread/nptl/pt-system.c
  21. 1 0
      libpthread/nptl/pthread-errnos.sym
  22. 139 13
      libpthread/nptl/pthreadP.h
  23. 4 3
      libpthread/nptl/pthread_atfork.c
  24. 2 1
      libpthread/nptl/pthread_attr_destroy.c
  25. 3 1
      libpthread/nptl/pthread_attr_getdetachstate.c
  26. 4 3
      libpthread/nptl/pthread_attr_init.c
  27. 7 1
      libpthread/nptl/pthread_attr_setschedparam.c
  28. 1 1
      libpthread/nptl/pthread_attr_setstack.c
  29. 5 4
      libpthread/nptl/pthread_barrier_destroy.c
  30. 25 11
      libpthread/nptl/pthread_barrier_init.c
  31. 8 3
      libpthread/nptl/pthread_cancel.c
  32. 34 9
      libpthread/nptl/pthread_cond_destroy.c
  33. 6 4
      libpthread/nptl/pthread_cond_init.c
  34. 2 2
      libpthread/nptl/pthread_condattr_getclock.c
  35. 4 3
      libpthread/nptl/pthread_condattr_setclock.c
  36. 112 10
      libpthread/nptl/pthread_create.c
  37. 48 40
      libpthread/nptl/pthread_getattr_np.c
  38. 6 6
      libpthread/nptl/pthread_getschedparam.c
  39. 46 38
      libpthread/nptl/pthread_join.c
  40. 23 32
      libpthread/nptl/pthread_key_create.c
  41. 37 0
      libpthread/nptl/pthread_mutex_consistent.c
  42. 9 3
      libpthread/nptl/pthread_mutex_destroy.c
  43. 38 0
      libpthread/nptl/pthread_mutex_getprioceiling.c
  44. 87 3
      libpthread/nptl/pthread_mutex_init.c
  45. 406 30
      libpthread/nptl/pthread_mutex_lock.c
  46. 119 0
      libpthread/nptl/pthread_mutex_setprioceiling.c
  47. 384 18
      libpthread/nptl/pthread_mutex_timedlock.c
  48. 320 14
      libpthread/nptl/pthread_mutex_trylock.c
  49. 236 20
      libpthread/nptl/pthread_mutex_unlock.c
  50. 48 0
      libpthread/nptl/pthread_mutexattr_getprioceiling.c
  51. 37 0
      libpthread/nptl/pthread_mutexattr_getprotocol.c
  52. 2 4
      libpthread/nptl/pthread_mutexattr_getpshared.c
  53. 37 0
      libpthread/nptl/pthread_mutexattr_getrobust.c
  54. 2 4
      libpthread/nptl/pthread_mutexattr_gettype.c
  55. 2 1
      libpthread/nptl/pthread_mutexattr_init.c
  56. 47 0
      libpthread/nptl/pthread_mutexattr_setprioceiling.c
  57. 41 0
      libpthread/nptl/pthread_mutexattr_setprotocol.c
  58. 3 5
      libpthread/nptl/pthread_mutexattr_setpshared.c
  59. 44 0
      libpthread/nptl/pthread_mutexattr_setrobust.c
  60. 2 4
      libpthread/nptl/pthread_mutexattr_settype.c
  61. 30 8
      libpthread/nptl/pthread_rwlock_init.c
  62. 6 5
      libpthread/nptl/pthread_rwlock_tryrdlock.c
  63. 5 4
      libpthread/nptl/pthread_rwlock_trywrlock.c
  64. 21 8
      libpthread/nptl/pthread_setschedparam.c
  65. 12 4
      libpthread/nptl/pthread_setschedprio.c
  66. 3 3
      libpthread/nptl/pthread_setspecific.c
  67. 5 5
      libpthread/nptl/pthread_timedjoin.c
  68. 5 3
      libpthread/nptl/pthread_tryjoin.c
  69. 0 1
      libpthread/nptl/res.c
  70. 4 3
      libpthread/nptl/sem_close.c
  71. 2 1
      libpthread/nptl/sem_destroy.c
  72. 3 3
      libpthread/nptl/sem_getvalue.c
  73. 14 8
      libpthread/nptl/sem_init.c
  74. 26 21
      libpthread/nptl/sem_open.c
  75. 2 1
      libpthread/nptl/sem_unlink.c
  76. 4 2
      libpthread/nptl/semaphoreP.h
  77. 0 1
      libpthread/nptl/sysdeps/arm/tls.h
  78. 8 13
      libpthread/nptl/sysdeps/generic/lowlevellock.h
  79. 2 1
      libpthread/nptl/sysdeps/i386/pthread_spin_lock.c
  80. 4 0
      libpthread/nptl/sysdeps/i386/tcb-offsets.sym
  81. 64 13
      libpthread/nptl/sysdeps/i386/tls.h
  82. 4 0
      libpthread/nptl/sysdeps/powerpc/tcb-offsets.sym
  83. 39 3
      libpthread/nptl/sysdeps/powerpc/tls.h
  84. 8 1
      libpthread/nptl/sysdeps/pthread/Makefile.in
  85. 3 2
      libpthread/nptl/sysdeps/pthread/allocalim.h
  86. 35 19
      libpthread/nptl/sysdeps/pthread/bits/libc-lock.h
  87. 7 1
      libpthread/nptl/sysdeps/pthread/bits/sigthread.h
  88. 10 4
      libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
  89. 10 8
      libpthread/nptl/sysdeps/pthread/createthread.c
  90. 4 87
      libpthread/nptl/sysdeps/pthread/librt-cancellation.c
  91. 2 13
      libpthread/nptl/sysdeps/pthread/list.h
  92. 18 7
      libpthread/nptl/sysdeps/pthread/malloc-machine.h
  93. 2 2
      libpthread/nptl/sysdeps/pthread/pt-initfini.c
  94. 0 2
      libpthread/nptl/sysdeps/pthread/pt-longjmp.c
  95. 15 5
      libpthread/nptl/sysdeps/pthread/pthread-functions.h
  96. 268 106
      libpthread/nptl/sysdeps/pthread/pthread.h
  97. 10 7
      libpthread/nptl/sysdeps/pthread/pthread_barrier_wait.c
  98. 21 7
      libpthread/nptl/sysdeps/pthread/pthread_cond_broadcast.c
  99. 16 5
      libpthread/nptl/sysdeps/pthread/pthread_cond_signal.c
  100. 17 12
      libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c

+ 1 - 0
.gitignore

@@ -17,6 +17,7 @@ install_dir/
 .config*
 .*.dep
 /*.log
+cscope.*
 
 #
 # Debugging files

+ 336 - 60
include/atomic.h

@@ -1,5 +1,5 @@
 /* Internal macros for atomic operations for GNU C Library.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002-2006, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -21,6 +21,31 @@
 #ifndef _ATOMIC_H
 #define _ATOMIC_H	1
 
+/* This header defines three types of macros:
+
+   - atomic arithmetic and logic operation on memory.  They all
+     have the prefix "atomic_".
+
+   - conditionally atomic operations of the same kinds.  These
+     always behave identical but can be faster when atomicity
+     is not really needed since only one thread has access to
+     the memory location.  In that case the code is slower in
+     the multi-thread case.  The interfaces have the prefix
+     "catomic_".
+
+   - support functions like barriers.  They also have the preifx
+     "atomic_".
+
+   Architectures must provide a few lowlevel macros (the compare
+   and exchange definitions).  All others are optional.  They
+   should only be provided if the architecture has specific
+   support for the operation.
+
+   As <atomic.h> macros are usually heavily nested and often use local
+   variables to make sure side-effects are evaluated properly, use for
+   macro local variables a per-macro unique prefix.  This file uses
+   __atgN_ prefix where N is different in each macro.  */
+
 #include <stdlib.h>
 
 #include <bits/atomic.h>
@@ -30,33 +55,33 @@
    and following args.  */
 #define __atomic_val_bysize(pre, post, mem, ...)			      \
   ({									      \
-    __typeof (*mem) __result;						      \
+    __typeof (*mem) __atg1_result;					      \
     if (sizeof (*mem) == 1)						      \
-      __result = pre##_8_##post (mem, __VA_ARGS__);			      \
+      __atg1_result = pre##_8_##post (mem, __VA_ARGS__);		      \
     else if (sizeof (*mem) == 2)					      \
-      __result = pre##_16_##post (mem, __VA_ARGS__);			      \
+      __atg1_result = pre##_16_##post (mem, __VA_ARGS__);		      \
     else if (sizeof (*mem) == 4)					      \
-      __result = pre##_32_##post (mem, __VA_ARGS__);			      \
+      __atg1_result = pre##_32_##post (mem, __VA_ARGS__);		      \
     else if (sizeof (*mem) == 8)					      \
-      __result = pre##_64_##post (mem, __VA_ARGS__);			      \
+      __atg1_result = pre##_64_##post (mem, __VA_ARGS__);		      \
     else								      \
       abort ();								      \
-    __result;								      \
+    __atg1_result;							      \
   })
 #define __atomic_bool_bysize(pre, post, mem, ...)			      \
   ({									      \
-    int __result;							      \
+    int __atg2_result;							      \
     if (sizeof (*mem) == 1)						      \
-      __result = pre##_8_##post (mem, __VA_ARGS__);			      \
+      __atg2_result = pre##_8_##post (mem, __VA_ARGS__);		      \
     else if (sizeof (*mem) == 2)					      \
-      __result = pre##_16_##post (mem, __VA_ARGS__);			      \
+      __atg2_result = pre##_16_##post (mem, __VA_ARGS__);		      \
     else if (sizeof (*mem) == 4)					      \
-      __result = pre##_32_##post (mem, __VA_ARGS__);			      \
+      __atg2_result = pre##_32_##post (mem, __VA_ARGS__);		      \
     else if (sizeof (*mem) == 8)					      \
-      __result = pre##_64_##post (mem, __VA_ARGS__);			      \
+      __atg2_result = pre##_64_##post (mem, __VA_ARGS__);		      \
     else								      \
       abort ();								      \
-    __result;								      \
+    __atg2_result;							      \
   })
 
 
@@ -70,6 +95,29 @@
 #endif
 
 
+#ifndef catomic_compare_and_exchange_val_acq
+# ifdef __arch_c_compare_and_exchange_val_32_acq
+#  define catomic_compare_and_exchange_val_acq(mem, newval, oldval) \
+  __atomic_val_bysize (__arch_c_compare_and_exchange_val,acq,		      \
+		       mem, newval, oldval)
+# else
+#  define catomic_compare_and_exchange_val_acq(mem, newval, oldval) \
+  atomic_compare_and_exchange_val_acq (mem, newval, oldval)
+# endif
+#endif
+
+
+#ifndef catomic_compare_and_exchange_val_rel
+# ifndef atomic_compare_and_exchange_val_rel
+#  define catomic_compare_and_exchange_val_rel(mem, newval, oldval)	      \
+  catomic_compare_and_exchange_val_acq (mem, newval, oldval)
+# else
+#  define catomic_compare_and_exchange_val_rel(mem, newval, oldval)	      \
+  atomic_compare_and_exchange_val_rel (mem, newval, oldval)
+# endif
+#endif
+
+
 #ifndef atomic_compare_and_exchange_val_rel
 # define atomic_compare_and_exchange_val_rel(mem, newval, oldval)	      \
   atomic_compare_and_exchange_val_acq (mem, newval, oldval)
@@ -83,17 +131,46 @@
 #  define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
   __atomic_bool_bysize (__arch_compare_and_exchange_bool,acq,		      \
 		        mem, newval, oldval)
-#  else
-#   define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
+# else
+#  define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
+  ({ /* Cannot use __oldval here, because macros later in this file might     \
+	call this macro with __oldval argument.	 */			      \
+     __typeof (oldval) __atg3_old = (oldval);				      \
+     atomic_compare_and_exchange_val_acq (mem, newval, __atg3_old)	      \
+       != __atg3_old;							      \
+  })
+# endif
+#endif
+
+
+#ifndef catomic_compare_and_exchange_bool_acq
+# ifdef __arch_c_compare_and_exchange_bool_32_acq
+#  define catomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
+  __atomic_bool_bysize (__arch_c_compare_and_exchange_bool,acq,		      \
+		        mem, newval, oldval)
+# else
+#  define catomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
   ({ /* Cannot use __oldval here, because macros later in this file might     \
 	call this macro with __oldval argument.	 */			      \
-     __typeof (oldval) __old = (oldval);				      \
-     atomic_compare_and_exchange_val_acq (mem, newval, __old) != __old;	      \
+     __typeof (oldval) __atg4_old = (oldval);				      \
+     catomic_compare_and_exchange_val_acq (mem, newval, __atg4_old)	      \
+       != __atg4_old;							      \
   })
 # endif
 #endif
 
 
+#ifndef catomic_compare_and_exchange_bool_rel
+# ifndef atomic_compare_and_exchange_bool_rel
+#  define catomic_compare_and_exchange_bool_rel(mem, newval, oldval)	      \
+  catomic_compare_and_exchange_bool_acq (mem, newval, oldval)
+# else
+#  define catomic_compare_and_exchange_bool_rel(mem, newval, oldval)	      \
+  atomic_compare_and_exchange_bool_rel (mem, newval, oldval)
+# endif
+#endif
+
+
 #ifndef atomic_compare_and_exchange_bool_rel
 # define atomic_compare_and_exchange_bool_rel(mem, newval, oldval) \
   atomic_compare_and_exchange_bool_acq (mem, newval, oldval)
@@ -103,18 +180,17 @@
 /* Store NEWVALUE in *MEM and return the old value.  */
 #ifndef atomic_exchange_acq
 # define atomic_exchange_acq(mem, newvalue) \
-  ({ __typeof (*(mem)) __oldval;					      \
-     __typeof (mem) __memp = (mem);					      \
-     __typeof (*(mem)) __value = (newvalue);				      \
+  ({ __typeof (*(mem)) __atg5_oldval;					      \
+     __typeof (mem) __atg5_memp = (mem);				      \
+     __typeof (*(mem)) __atg5_value = (newvalue);			      \
 									      \
      do									      \
-       __oldval = (*__memp);						      \
-     while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
-								    __value,  \
-								    __oldval),\
-			      0));					      \
+       __atg5_oldval = *__atg5_memp;					      \
+     while (__builtin_expect						      \
+	    (atomic_compare_and_exchange_bool_acq (__atg5_memp, __atg5_value, \
+						   __atg5_oldval), 0));	      \
 									      \
-     __oldval; })
+     __atg5_oldval; })
 #endif
 
 #ifndef atomic_exchange_rel
@@ -125,19 +201,90 @@
 /* Add VALUE to *MEM and return the old value of *MEM.  */
 #ifndef atomic_exchange_and_add
 # define atomic_exchange_and_add(mem, value) \
-  ({ __typeof (*(mem)) __oldval;					      \
-     __typeof (mem) __memp = (mem);					      \
-     __typeof (*(mem)) __value = (value);				      \
+  ({ __typeof (*(mem)) __atg6_oldval;					      \
+     __typeof (mem) __atg6_memp = (mem);				      \
+     __typeof (*(mem)) __atg6_value = (value);				      \
 									      \
      do									      \
-       __oldval = (*__memp);						      \
-     while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
-								    __oldval  \
-								    + __value,\
-								    __oldval),\
-			      0));					      \
+       __atg6_oldval = *__atg6_memp;					      \
+     while (__builtin_expect						      \
+	    (atomic_compare_and_exchange_bool_acq (__atg6_memp,		      \
+						   __atg6_oldval	      \
+						   + __atg6_value,	      \
+						   __atg6_oldval), 0));	      \
 									      \
-     __oldval; })
+     __atg6_oldval; })
+#endif
+
+
+#ifndef catomic_exchange_and_add
+# define catomic_exchange_and_add(mem, value) \
+  ({ __typeof (*(mem)) __atg7_oldv;					      \
+     __typeof (mem) __atg7_memp = (mem);				      \
+     __typeof (*(mem)) __atg7_value = (value);				      \
+									      \
+     do									      \
+       __atg7_oldv = *__atg7_memp;					      \
+     while (__builtin_expect						      \
+	    (catomic_compare_and_exchange_bool_acq (__atg7_memp,	      \
+						    __atg7_oldv		      \
+						    + __atg7_value,	      \
+						    __atg7_oldv), 0));	      \
+									      \
+     __atg7_oldv; })
+#endif
+
+
+#ifndef atomic_max
+# define atomic_max(mem, value) \
+  do {									      \
+    __typeof (*(mem)) __atg8_oldval;					      \
+    __typeof (mem) __atg8_memp = (mem);					      \
+    __typeof (*(mem)) __atg8_value = (value);				      \
+    do {								      \
+      __atg8_oldval = *__atg8_memp;					      \
+      if (__atg8_oldval >= __atg8_value)				      \
+	break;								      \
+    } while (__builtin_expect						      \
+	     (atomic_compare_and_exchange_bool_acq (__atg8_memp, __atg8_value,\
+						    __atg8_oldval), 0));      \
+  } while (0)
+#endif
+
+
+#ifndef catomic_max
+# define catomic_max(mem, value) \
+  do {									      \
+    __typeof (*(mem)) __atg9_oldv;					      \
+    __typeof (mem) __atg9_memp = (mem);					      \
+    __typeof (*(mem)) __atg9_value = (value);				      \
+    do {								      \
+      __atg9_oldv = *__atg9_memp;					      \
+      if (__atg9_oldv >= __atg9_value)					      \
+	break;								      \
+    } while (__builtin_expect						      \
+	     (catomic_compare_and_exchange_bool_acq (__atg9_memp,	      \
+						     __atg9_value,	      \
+						     __atg9_oldv), 0));	      \
+  } while (0)
+#endif
+
+
+#ifndef atomic_min
+# define atomic_min(mem, value) \
+  do {									      \
+    __typeof (*(mem)) __atg10_oldval;					      \
+    __typeof (mem) __atg10_memp = (mem);				      \
+    __typeof (*(mem)) __atg10_value = (value);				      \
+    do {								      \
+      __atg10_oldval = *__atg10_memp;					      \
+      if (__atg10_oldval <= __atg10_value)				      \
+	break;								      \
+    } while (__builtin_expect						      \
+	     (atomic_compare_and_exchange_bool_acq (__atg10_memp,	      \
+						    __atg10_value,	      \
+						    __atg10_oldval), 0));     \
+  } while (0)
 #endif
 
 
@@ -146,16 +293,32 @@
 #endif
 
 
+#ifndef catomic_add
+# define catomic_add(mem, value) \
+  (void) catomic_exchange_and_add ((mem), (value))
+#endif
+
+
 #ifndef atomic_increment
 # define atomic_increment(mem) atomic_add ((mem), 1)
 #endif
 
 
+#ifndef catomic_increment
+# define catomic_increment(mem) catomic_add ((mem), 1)
+#endif
+
+
 #ifndef atomic_increment_val
 # define atomic_increment_val(mem) (atomic_exchange_and_add ((mem), 1) + 1)
 #endif
 
 
+#ifndef catomic_increment_val
+# define catomic_increment_val(mem) (catomic_exchange_and_add ((mem), 1) + 1)
+#endif
+
+
 /* Add one to *MEM and return true iff it's now zero.  */
 #ifndef atomic_increment_and_test
 # define atomic_increment_and_test(mem) \
@@ -168,11 +331,21 @@
 #endif
 
 
+#ifndef catomic_decrement
+# define catomic_decrement(mem) catomic_add ((mem), -1)
+#endif
+
+
 #ifndef atomic_decrement_val
 # define atomic_decrement_val(mem) (atomic_exchange_and_add ((mem), -1) - 1)
 #endif
 
 
+#ifndef catomic_decrement_val
+# define catomic_decrement_val(mem) (catomic_exchange_and_add ((mem), -1) - 1)
+#endif
+
+
 /* Subtract 1 from *MEM and return true iff it's now zero.  */
 #ifndef atomic_decrement_and_test
 # define atomic_decrement_and_test(mem) \
@@ -183,35 +356,34 @@
 /* Decrement *MEM if it is > 0, and return the old value.  */
 #ifndef atomic_decrement_if_positive
 # define atomic_decrement_if_positive(mem) \
-  ({ __typeof (*(mem)) __oldval;					      \
-     __typeof (mem) __memp = (mem);					      \
+  ({ __typeof (*(mem)) __atg11_oldval;					      \
+     __typeof (mem) __atg11_memp = (mem);				      \
 									      \
      do									      \
        {								      \
-	 __oldval = *__memp;						      \
-	 if (__builtin_expect (__oldval <= 0, 0))			      \
+	 __atg11_oldval = *__atg11_memp;				      \
+	 if (__builtin_expect (__atg11_oldval <= 0, 0))			      \
 	   break;							      \
        }								      \
-     while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
-								    __oldval  \
-								    - 1,      \
-								    __oldval),\
-			      0));\
-     __oldval; })
+     while (__builtin_expect						      \
+	    (atomic_compare_and_exchange_bool_acq (__atg11_memp,	      \
+						   __atg11_oldval - 1,	      \
+						   __atg11_oldval), 0));      \
+     __atg11_oldval; })
 #endif
 
 
 #ifndef atomic_add_negative
 # define atomic_add_negative(mem, value)				      \
-  ({ __typeof (value) __aan_value = (value);				      \
-     atomic_exchange_and_add (mem, __aan_value) < -__aan_value; })
+  ({ __typeof (value) __atg12_value = (value);				      \
+     atomic_exchange_and_add (mem, __atg12_value) < -__atg12_value; })
 #endif
 
 
 #ifndef atomic_add_zero
 # define atomic_add_zero(mem, value)					      \
-  ({ __typeof (value) __aaz_value = (value);				      \
-     atomic_exchange_and_add (mem, __aaz_value) == -__aaz_value; })
+  ({ __typeof (value) __atg13_value = (value);				      \
+     atomic_exchange_and_add (mem, __atg13_value) == -__atg13_value; })
 #endif
 
 
@@ -223,21 +395,119 @@
 
 #ifndef atomic_bit_test_set
 # define atomic_bit_test_set(mem, bit) \
-  ({ __typeof (*(mem)) __oldval;					      \
-     __typeof (mem) __memp = (mem);					      \
-     __typeof (*(mem)) __mask = ((__typeof (*(mem))) 1 << (bit));	      \
+  ({ __typeof (*(mem)) __atg14_old;					      \
+     __typeof (mem) __atg14_memp = (mem);				      \
+     __typeof (*(mem)) __atg14_mask = ((__typeof (*(mem))) 1 << (bit));	      \
 									      \
      do									      \
-       __oldval = (*__memp);						      \
-     while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
-								    __oldval  \
-								    | __mask, \
-								    __oldval),\
-			      0));					      \
+       __atg14_old = (*__atg14_memp);					      \
+     while (__builtin_expect						      \
+	    (atomic_compare_and_exchange_bool_acq (__atg14_memp,	      \
+						   __atg14_old | __atg14_mask,\
+						   __atg14_old), 0));	      \
 									      \
-     __oldval & __mask; })
+     __atg14_old & __atg14_mask; })
 #endif
 
+/* Atomically *mem &= mask.  */
+#ifndef atomic_and
+# define atomic_and(mem, mask) \
+  do {									      \
+    __typeof (*(mem)) __atg15_old;					      \
+    __typeof (mem) __atg15_memp = (mem);				      \
+    __typeof (*(mem)) __atg15_mask = (mask);				      \
+									      \
+    do									      \
+      __atg15_old = (*__atg15_memp);					      \
+    while (__builtin_expect						      \
+	   (atomic_compare_and_exchange_bool_acq (__atg15_memp,		      \
+						  __atg15_old & __atg15_mask, \
+						  __atg15_old), 0));	      \
+  } while (0)
+#endif
+
+#ifndef catomic_and
+# define catomic_and(mem, mask) \
+  do {									      \
+    __typeof (*(mem)) __atg20_old;					      \
+    __typeof (mem) __atg20_memp = (mem);				      \
+    __typeof (*(mem)) __atg20_mask = (mask);				      \
+									      \
+    do									      \
+      __atg20_old = (*__atg20_memp);					      \
+    while (__builtin_expect						      \
+	   (catomic_compare_and_exchange_bool_acq (__atg20_memp,	      \
+						   __atg20_old & __atg20_mask,\
+						   __atg20_old), 0));	      \
+  } while (0)
+#endif
+
+/* Atomically *mem &= mask and return the old value of *mem.  */
+#ifndef atomic_and_val
+# define atomic_and_val(mem, mask) \
+  ({ __typeof (*(mem)) __atg16_old;					      \
+     __typeof (mem) __atg16_memp = (mem);				      \
+     __typeof (*(mem)) __atg16_mask = (mask);				      \
+									      \
+     do									      \
+       __atg16_old = (*__atg16_memp);					      \
+     while (__builtin_expect						      \
+	    (atomic_compare_and_exchange_bool_acq (__atg16_memp,	      \
+						   __atg16_old & __atg16_mask,\
+						   __atg16_old), 0));	      \
+									      \
+     __atg16_old; })
+#endif
+
+/* Atomically *mem |= mask and return the old value of *mem.  */
+#ifndef atomic_or
+# define atomic_or(mem, mask) \
+  do {									      \
+    __typeof (*(mem)) __atg17_old;					      \
+    __typeof (mem) __atg17_memp = (mem);				      \
+    __typeof (*(mem)) __atg17_mask = (mask);				      \
+									      \
+    do									      \
+      __atg17_old = (*__atg17_memp);					      \
+    while (__builtin_expect						      \
+	   (atomic_compare_and_exchange_bool_acq (__atg17_memp,		      \
+						  __atg17_old | __atg17_mask, \
+						  __atg17_old), 0));	      \
+  } while (0)
+#endif
+
+#ifndef catomic_or
+# define catomic_or(mem, mask) \
+  do {									      \
+    __typeof (*(mem)) __atg18_old;					      \
+    __typeof (mem) __atg18_memp = (mem);				      \
+    __typeof (*(mem)) __atg18_mask = (mask);				      \
+									      \
+    do									      \
+      __atg18_old = (*__atg18_memp);					      \
+    while (__builtin_expect						      \
+	   (catomic_compare_and_exchange_bool_acq (__atg18_memp,	      \
+						   __atg18_old | __atg18_mask,\
+						   __atg18_old), 0));	      \
+  } while (0)
+#endif
+
+/* Atomically *mem |= mask and return the old value of *mem.  */
+#ifndef atomic_or_val
+# define atomic_or_val(mem, mask) \
+  ({ __typeof (*(mem)) __atg19_old;					      \
+     __typeof (mem) __atg19_memp = (mem);				      \
+     __typeof (*(mem)) __atg19_mask = (mask);				      \
+									      \
+     do									      \
+       __atg19_old = (*__atg19_memp);					      \
+     while (__builtin_expect						      \
+	    (atomic_compare_and_exchange_bool_acq (__atg19_memp,	      \
+						   __atg19_old | __atg19_mask,\
+						   __atg19_old), 0));	      \
+									      \
+     __atg19_old; })
+#endif
 
 #ifndef atomic_full_barrier
 # define atomic_full_barrier() __asm__ ("" ::: "memory")
@@ -254,6 +524,12 @@
 #endif
 
 
+#ifndef atomic_forced_read
+# define atomic_forced_read(x) \
+  ({ __typeof (x) __x; __asm__ ("" : "=r" (__x) : "0" (x)); __x; })
+#endif
+
+
 #ifndef atomic_delay
 # define atomic_delay() do { /* nothing */ } while (0)
 #endif

+ 3 - 0
libpthread/nptl/.gitignore

@@ -11,7 +11,10 @@ tcb-offsets.[hcs]
 lowlevelbarrier.[hcs]
 lowlevelcond.[hcs]
 lowlevelrwlock.[hcs]
+lowlevelrobustlock.[hcs]
 unwindbuf.[hcs]
+structsem.[hcs]
+pthread-pi-defines.[hcs]
 sysdeps/pthread/pt-sigaction.c
 sysdeps/pthread/pt-sigfillset.c
 sysdeps/pthread/pt-sigprocmask.c

+ 3830 - 0
libpthread/nptl/ChangeLog

@@ -1,3 +1,3833 @@
+2010-01-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S:
+	Fix unwind info.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+
+2010-01-15  Michal Schmidt  <mschmidt@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S:
+	Fix pthread_cond_timedwait with requeue-PI.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S:
+	Fix pthread_cond_wait with requeue-PI.
+
+2010-01-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* Versions: Add pthread_mutex_consistent, pthread_mutexattr_getrobust,
+	and pthread_mutexattr_setrobust for GLIBC_2.12.
+	* pthread_mutex_consistent.c: Define alias pthread_mutex_consistent.
+	* pthread_mutexattr_getrobust.c: Define alias
+	pthread_mutexattr_getrobust.
+	* pthread_mutexattr_setrobust.c: Define alias
+	pthread_mutexattr_setrobust.
+
+2010-01-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread.h: Cleanup.  Fix up for XPG7.
+
+2010-01-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread.h: Fix pthread_mutex_consistent declaration.
+
+2009-12-18  Thomas Schwinge  <thomas@codesourcery.com>
+
+	* sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c (_init): Don't
+	call __gmon_start__.
+	* sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c (_init): Likewise.
+
+2009-12-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_rwlock_init.c (__pthread_rwlock_init): Simplify code by
+	using memset.
+
+2009-12-01  Dinakar Guniguntala  <dino@in.ibm.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.h: Define
+	FUTEX_WAIT_REQUEUE_PI and FUTEX_CMP_REQUEUE_PI.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: If mutex
+	is a non robust PI mutex, then use FUTEX_CMP_REQUEUE_PI.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: If mutex
+	is a non robust PI mutex, then use FUTEX_WAIT_REQUEUE_PI.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+
+2009-12-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (sem_timedwait):
+	Don't update nwaiters after invalid timeout is recognized.
+
+2009-11-27  Thomas Schwinge  <thomas@codesourcery.com>
+
+	* sysdeps/unix/sysv/linux/sh/pt-initfini.c (_init): Don't call
+	__gmon_start__.
+
+2009-11-27  Andreas Schwab  <schwab@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/cancellation.S: Reload
+	THREAD_SELF->cancelhandling after returning from futex call.
+
+2009-11-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-sem13.c: New file.
+	* Makefile (tests): Add tst-sem13.
+
+2009-11-22  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/dl-sysdep.h: # include "i686/dl-sysdep.h"
+	instead of recapitulating its contents.
+
+2009-11-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: Minor
+	optimizations and cleanups.
+
+2009-11-18  Dinakar Guniguntala  <dino@in.ibm.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S:
+	Remove redundant code. Fix cfi offsets.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S:
+	Fix cfi offsets.
+
+2009-11-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Minimally
+	reduce size of unwind info.
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Convert to use
+	cfi directives.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+	Based on a patch by Dinakar Guniguntala <dino@in.ibm.com>.
+
+2009-11-03  Andreas Schwab  <schwab@linux-m68k.org>
+
+	[BZ #4457]
+	* sysdeps/pthread/unwind-resume.c: Include <libgcc_s.h> and use
+	LIBGCC_S_SO.
+	* sysdeps/pthread/unwind-forcedunwind.c: Likewise.
+
+2009-10-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-sem11.c (main): Rewrite to avoid aliasing problems.
+
+	[BZ #3270]
+	* allocatestack.c (__nptl_setxid): Perform the operation in multiple
+	steps to avoid races with creation and terminations.
+	* nptl-init.c (sighandler_setxid): Adjust.
+	Patch by Daniel Jacobowitz.
+
+2009-09-07  Andreas Schwab  <schwab@redhat.com>
+
+	* sysdeps/pthread/bits/libc-lock.h (BP_SYM): Remove space before paren.
+
+2009-09-02  Suzuki K P  <suzuki@in.ibm.com>
+	    Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #7094]
+	* sysdeps/unix/sysv/linux/timer_create.c (timer_create):
+	Initialize the sigev_notify field for newly created timer to make sure
+	the timer gets deleted from the active timer's list upon timer_delete.
+
+2009-08-27  Andrew Stubbs  <ams@codesourcery.com>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S (__lll_timedlock_wait):
+	Correct a logic error.
+
+2009-08-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/x86_64/tls.h (RTLD_ENABLE_FOREIGN_CALL): Store old value
+	of the field in local variables.
+	(RTLD_FINALIZE_FOREIGN_CALL): Restore rtld_must_xmm_save from local
+	variable and don't unconditionally clear it.
+
+2009-08-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_create.c (start_thread): Hint to the kernel that memory for
+	the stack can be reused.  We do not mark all the memory.  The part
+	still in use and some reserve are kept.
+
+2009-08-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/bits/posix_opt.h: Clean up namespace.
+
+2009-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: Add CFI
+	directives.
+
+2009-08-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Add CFI
+	directives.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+
+2009-08-10  Andreas Schwab  <schwab@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+	(__pthread_cond_signal): Don't clobber register used for syscall
+	number.
+
+2009-08-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait):
+	Optimize code path used when FUTEX_CLOCK_REALTIME is supported.
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+	(__pthread_cond_wait): Optimize by avoiding use of callee-safe
+	register.
+
+2009-08-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Little optimizations
+	enabled by the special *_asynccancel functions.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+
+	* sysdeps/unix/sysv/linux/x86_64/cancellation.S: Include lowlevellock.h.
+
+2009-08-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/cancellation.S: New file.
+	* sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S: New file.
+	* sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S: New file.
+	* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Optimize
+	since we can assume the special __*_{en,dis}able_asynccancel
+	functions.
+	(PUSHARGS_*, POPARGS_*, SAVESTK_*, RESTSTK_*): Removed.
+	* sysdeps/x86_64/tcb-offsets.sym: Add cancellation-related bits
+	and PTHREAD_CANCELED.
+
+2009-07-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* descr.h: Better definition of *_BITMASK macros for cancellation.
+
+2009-07-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/x86_64/tls.h (TLS_TCB_ALIGN): Define explicitly to 32.
+
+	* sysdeps/x86_64/tls.h (tcbhead_t): Add room for SSE registers the
+	dynamic linker might have to save.
+	Define RTLD_CHECK_FOREIGN_CALL, RTLD_ENABLE_FOREIGN_CALL,
+	RTLD_PREPARE_FOREIGN_CALL, and RTLD_FINALIZE_FOREIGN_CALL.  Pretty
+	printing.
+
+	* sysdeps/x86_64/tcb-offsets.sym: Add RTLD_SAVESPACE_SSE.
+
+2009-07-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_mutex_lock.c [NO_INCR] (__pthread_mutex_cond_lock_adjust):
+	New function.
+	* pthreadP.h: Declare __pthread_mutex_cond_lock_adjust.
+	* sysdeps/unix/sysv/linux/pthread-pi-defines.sym: Add ROBUST_BIT.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S: Don't use
+	requeue_pi for robust mutexes.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+	Don't only skip __pthread_mutex_cond_lock.  Call instead
+	__pthread_mutex_cond_lock_adjust.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+
+	* pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Minor
+	optimization of PI mutex handling.
+
+2009-07-27  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #10418]
+	* pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Use _rel
+	instead of of _acq variants of cmpxchg.
+
+2009-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/x86_64/configure.in: New file.
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Fix error
+	path when not using absolute timeout futex.
+
+2009-07-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Minor
+	optimizations of last changes.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+
+2009-07-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Define
+	FUTEX_WAIT_REQUEUE_PI and FUTEX_CMP_REQUEUE_PI.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S: If mutex
+	is a PI mutex, then use FUTEX_CMP_REQUEUE_PI.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: If mutex
+	is a PI mutex, then use FUTEX_WAIT_REQUEUE_PI.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+	(__pthread_cond_timedwait): Make more robust.
+
+2009-07-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
+	(__lll_robust_timedlock_wait): If possible use FUTEX_WAIT_BITSET to
+	directly use absolute timeout.
+
+	* tst-sem5.c (do_test): Add test for premature timeout.
+	* Makefile: Linu tst-sem5 with librt.
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
+	(pthread_rwlock_timedwrlock): If possible use FUTEX_WAIT_BITSET to
+	directly use absolute timeout.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
+	(pthread_rwlock_timedrdlock): Likewise.
+
+	* tst-cond11.c (run_test): Add test to check that the timeout is
+	long enough.
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+	(__pthread_cond_timedwait): If possible use FUTEX_WAIT_BITSET to
+	directly use absolute timeout.
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+	(__pthread_cond_wait): Convert to using exception handler instead of
+	registered unwind buffer.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+	(__pthread_cond_timedwait): Likewise.
+
+2009-07-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait):
+	If possible use FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME to directly
+	use absolute timeout.
+
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S (sem_wait): Optimize
+	handling of uncontested semaphore.
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+	(__condvar_cleanup): Rewrite to use cfi directives instead of
+	hand-coded unwind tables.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_once.S (__pthread_once):
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S (sem_wait): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait):
+	Likewise.
+
+2009-06-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile (libpthread-routines): Add pthread_sigqueue.
+	* Versions: Add pthread_sigqueue for GLIBC_2.11.
+	* sysdeps/pthread/bits/sigthread.h: Declare pthread_sigqueue.
+	* sysdeps/unix/sysv/linux/pthread_sigqueue.c: New file.
+
+2009-06-11  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #10262]
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
+	(LOAD_FUTEX_WAIT_ABS): Fix futex parameter in case private futexes
+	cannot be assumed.
+	Patch by Bryan Kadzban <bz-glibc@kdzbn.homelinux.net>.
+
+2009-05-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* libc-cancellation.c: Move __libc_cleanup_routine to...
+	* libc-cleanup.c: ...here.  New file.
+	* Makefile (routines): Add libc-cleanup.
+
+	* cancellation.c (__pthread_disable_asynccancel): Remove unnecessary
+	test.
+	* libc-cancellation.c: Use <nptl/cancellation.c: to define the code.
+	* sysdeps/pthread/librt-cancellation.c: Likewise.
+
+	[BZ #9924]
+	* nptl-init.c: Renamed from init.c.
+	* Makefile: Change all occurences of init.c to nptl-init.c.
+
+2009-05-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* cancellation.c (__pthread_disable_asynccancel): Correct the bits
+	to test when deciding on the delay.
+	* libc-cancellation.c (__libc_disable_asynccancel): Likewise.
+	* pthread_cancel.c: Close race between deciding on sending a signal
+	and setting the CANCELING_BIT bit.
+
+	* cancellation.c (__pthread_disable_asynccancel): Don't return if
+	thread is canceled.
+	* libc-cancellation.c (__libc_disable_asynccancel): Likewise.
+
+2009-04-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* cancellation.c (__pthread_disable_asynccancel): Use THREAD_ATOMIC_AND
+	is available.
+	* libc-cancellation.c (__libc_disable_asynccancel): Likewise.
+	* sysdeps/x86_64/tls.h: Define THREAD_ATOMIC_AND.
+	* sysdeps/i386/tls.h: Likewise.
+	(tcbhead_t): Add __private_tm member.
+
+2009-04-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* sem_open.c (sem_open): Rewrite initialization of initsem to
+	avoid warnings.
+
+	* sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init):
+	Avoid warning by using may_alias attribute on ptrhack.
+
+2009-04-22  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #10090]
+	* pthread_attr_setschedparam.c (__pthread_attr_setschedparam):
+	Check policy and priority for validity.
+	Patch mostly by Zhang Xiliang <zhangxiliang@cn.fujitsu.com>.
+
+2009-03-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+	(__pthread_cond_timedwait): Change to use cfi directives instead of
+	hand-coded unwind sections.
+
+2009-03-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* init.c (nptl_freeres): Compile only for SHARED.
+
+2009-03-09  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Define
+	FUTEX_WAIT_BITSET, FUTEX_WAKE_BITSET, FUTEX_CLOCK_REALTIME and
+	FUTEX_BITSET_MATCH_ANY.
+
+2009-02-27  Roland McGrath  <roland@redhat.com>
+
+	* init.c (__nptl_initial_report_events): Mark __attribute_used__.
+	* pthread_create.c (__nptl_threads_events, __nptl_last_event): Likewise.
+
+2009-02-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/bits/posix_opt.h: Define
+	_POSIX_THREAD_ROBUST_PRIO_INHERIT and
+	_POSIX_THREAD_ROBUST_PRIO_PROTECT.  Reset value of macros from
+	200112L to 200809L.
+
+2009-02-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread.h: The robust mutex functions are in
+	POSIX 2008.
+
+2009-02-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/bits/posix_opt.h (_BITS_POSIX_OPT_H):
+	Unify name of include protector macro.
+
+2009-02-14  SUGIOKA Toshinobu  <sugioka@itonet.co.jp>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S: Define
+	LOAD_FUTEX_WAIT_ABS even if (FUTEX_WAIT == 0).
+
+2009-01-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/unwind-forcedunwind.c: Encrypt all function
+	pointer variables.
+
+	* allocatestack.c (__free_stacks): Renamed from free_stacks.
+	(__free_stack_cache): Removed.  Change callers to call __free_stacks.
+	* init.c (nptl_freeres): New function.
+	(pthread_functions): Initialize ptr_freeres to nptl_freeres.
+	* pthreadP.h: Don't declare __free_stack_cache.  Declare __free_stacks.
+	* sysdeps/pthread/unwind-forcedunwind.c (libgcc_s_handle): New
+	variable.
+	(pthread_cancel_init): Depend in libgcc_s_handle for decision to
+	load DSO.  Assign last.
+	(__unwind_freeres): New function.
+
+	* allocatestack.c (__reclaim_stacks): Reset in_flight_stack later
+	for better debugging.  No need to use stack_list_add here.
+
+2009-01-14  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S
+	(__lll_timedlock_wait): Use FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME
+	instead of computing relative timeout.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Define
+	FUTEX_CLOCK_REALTIME and FUTEX_BITSET_MATCH_ANY.
+
+2009-01-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_mutex_lock.c (__pthread_mutex_lock): Remove unused label out.
+
+2009-01-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/list.h (list_add): Initialize new element first.
+	(list_add_tail): Removed.
+
+2009-01-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* (in_flight_stack): New variable.
+	(stack_list_del): New function.  Use instead of list_del.
+	(stack_list_add): New function.  Use instead of list_add when adding to
+	stack_cache and stack_used lists.
+	(__reclaim_stacks): Complete operations on stack_cache and stack_used lists
+	when the fork call interrupted another thread.
+
+2009-01-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* init.c (__pthread_initialize_minimal_internal): Optimize test
+	FUTEX_CLOCK_REALTIME a bit.
+
+2009-01-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* init.c (__pthread_initialize_minimal_internal): Cheat a bit by
+	only passing five parameters to FUTEX_WAIT_BITSET call.
+
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
+	(__lll_timedlock_wait): Use FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME
+	instead of computing relative timeout.
+
+2009-01-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* init.c (__pthread_initialize_minimal_internal): Check for
+	FUTEX_CLOCK_REALTIME flag.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S (__lll_timedlock_wait):
+	Use FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME instead of computing
+	relative timeout.
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Define
+	FUTEX_CLOCK_REALTIME and FUTEX_BITSET_MATCH_ANY.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+
+2008-12-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread.h (pthread_cleanup_pop): Use { } as empty
+	loop body instead of ; to avoid gcc warnings.
+	(pthread_cleanup_pop_restore_np): Likewise.
+	Patch by Caolán McNamara <caolanm@redhat.com>.
+
+2008-12-09  Jakub Jelinek  <jakub@redhat.com>
+
+	* pthread_mutex_lock.c (__pthread_mutex_lock): Handle only the
+	fast path here, for robust/PI/PP mutexes call
+	__pthread_mutex_lock_full.  Don't use switch, instead use a series
+	of ifs according to their probability.
+	(__pthread_mutex_lock_full): New function.
+	* pthread_mutex_unlock.c: Include assert.h.
+	(__pthread_mutex_unlock_usercnt): Handle only the
+	fast path here, for robust/PI/PP mutexes call
+	__pthread_mutex_unlock_full.  Don't use switch, instead use a series
+	of ifs according to their probability.
+	(__pthread_mutex_unlock_full): New function.
+	* sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
+	(__pthread_mutex_lock_full): Define.
+
+2008-12-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/x86_64/tls.h (tcbhead_t): Add fields reserved for TM
+	implementation.  Add necessary padding and.
+	* descr.h (struct pthread): Increase padding for tcbhead_t to 24
+	words.
+
+2008-12-04  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Define FUTEX_WAIT_BITSET
+	and FUTEX_WAKE_BITSET.
+
+2008-12-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Define FUTEX_WAIT_BITSET
+	and FUTEX_WAKE_BITSET.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+
+2008-11-25  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/alpha, sysdeps/unix/sysv/linux/alpha:
+	Subdirectories moved to ports repository as
+	sysdeps/.../nptl subdirectories.
+
+2008-11-12  Jakub Jelinek  <jakub@redhat.com>
+
+	[BZ #7008]
+	* pthread_condattr_setclock.c (pthread_condattr_setclock): Fix masking
+	of old value.
+	* pthread_cond_init.c (__pthread_cond_init): Fix
+	cond->__data.__nwaiters initialization.
+	* Makefile (tests): Add tst-cond23.
+	* tst-cond23.c: New test.
+
+2008-11-07  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/pthread/malloc-machine.h (MALLOC): Adjust __libc_tsd_define
+	arguments.
+	(tsd_setspecific, tsd_getspecific): Adjust __libc_tsd_{set,get}
+	arguments.
+
+2008-11-01  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #6955]
+	* pthread_mutex_lock.c: Add support for private PI mutexes.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise.
+	Patch mostly by Ben Jackson <ben@ben.com>.
+
+2008-10-31  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #6843]
+	* sysdeps/pthread/gai_misc.h (__gai_create_helper_thread):
+	Increase stack size for helper thread.
+
+2008-10-06  Martin Schwidefsky  <schwidefsky@de.ibm.com>
+
+	* sysdeps/s390/tls.h (THREAD_SET_STACK_GUARD): Add empty inline
+	assembly with a clobber list for access registers a0 and a1.
+
+2008-09-11  Martin Schwidefsky  <schwidefsky@de.ibm.com>
+
+	* sysdeps/unix/sysv/linux/fork.c (__libc_fork): Add memory barrier
+	to force runp->refcntr to be read from memory.
+
+2008-09-08  Richard Guenther  <rguenther@suse.de>
+
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_lock,
+	lll_robust_lock, lll_cond_lock, lll_robust_cond_lock,
+	lll_timedlock, lll_robust_timedlock, lll_unlock,
+	lll_robust_unlock): Promote private to int.
+
+2008-08-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/x86_64/pthreaddef.h: Remove ARCH_MAP_FLAGS and
+	ARCH_RETRY_MMAP definitions.
+	* allocatestack.c: Remove definition of ARCH_MAP_FLAGS.
+	Define MAP_STACK when not defined.
+	(allocate_stack): Use MAP_STACK instead of ARCH_MAP_FLAGS.  Remove
+	handling of ARCH_RETRY_MMAP.
+
+2008-07-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-align2.c (f): Print message that f is reached.
+
+2008-04-28  Hiroki Kaminaga  <kaminaga@sm.sony.co.jp>
+
+	[BZ #6740]
+	* sysdeps/powerpc/tcb-offsets.sym (PRIVATE_FUTEX_OFFSET): Guard symbol
+	definition with #ifndef __ASSUME_PRIVATE_FUTEX.
+
+2008-07-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/mq_notify.c (init_mq_netlink): Use
+	SOCK_CLOEXEC if possible.
+
+2008-05-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile (tests): Add tst-rwlock2a.
+	* tst-rwlock2.c: Use TYPE macro to decide what rwlock type to use.
+	* tst-rwlock2a.c: New file.
+
+2008-06-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread.h: Remove inadvertant checkin.
+
+2008-05-17  Samuel Thibault  <samuel.thibault@ens-lyon.org>
+
+	* sysdeps/pthread/pthread.h: Fix typo in comment.
+
+2008-05-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/createthread.c (do_clone): Pass accurate length
+	of CPU set to the kernel.
+
+2008-05-23  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S: Add
+	cfi directives.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+
+2008-05-22  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S: Add
+	cfi directives.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+	Likewise.
+
+2008-05-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-typesizes.c: Explicitly check __SIZEOF_PTHREAD_* constants.
+
+2008-05-20  Jakub Jelinek  <jakub@redhat.com>
+
+	David S. Miller  <davem@davemloft.net>
+
+	* sysdeps/unix/sysv/linux/sparc/sparc64/Makefile: New file.
+
+2008-05-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Access
+	__pshared correctly.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S:
+	Likewise.
+	Reported by Clemens Kolbitsch <clemens.kol@gmx.at>.
+
+2008-04-14  David S. Miller  <davem@davemloft.net>
+
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
+	(__old_sem_wait): Fix argument to lll_futex_wait().
+
+2007-11-26  Daniel Jacobowitz  <dan@codesourcery.com>
+
+	* pthread_create.c: Require pthread_mutex_trylock and
+	pthread_key_delete for libgcc.
+
+2008-04-08  Jakub Jelinek  <jakub@redhat.com>
+
+	[BZ #6020]
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h
+	(lll_futex_wake_unlock): Add private argument to the pre-v9 macro.
+	Patch by Sunil Amitkumar Janki <devel.sjanki@gmail.com>.
+
+2008-03-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/bits/local_lim.h: Undefine ARG_MAX if
+	<linux/limits.h> has defined it.
+	* sysdeps/unix/sysv/linux/alpha/bits/local_lim.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/bits/local_lim.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/bits/local_lim.h: Likewise.
+
+2008-03-18  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/ia64/dl-sysdep.h: Use __ASSEMBLER__ instead
+	of ASSEMBLER.
+	* sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/dl-sysdep.h: Likewise.
+
+2008-03-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/dl-sysdep.h: Define
+	HAVE_DL_DISCOVER_OSVERSION.
+	* sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/dl-sysdep.h: Likewise.
+
+2008-03-07  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #5778]
+	* sysdeps/unix/sysv/linux/bits/posix_opt.h: Change
+	_POSIX_CHOWN_RESTRICTED value to zero.
+
+2008-01-31  Roland McGrath  <roland@redhat.com>
+
+	* Makefile (omit-deps): Variable removed.
+
+2008-01-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/sem_post.S (sem_post): Avoid
+	unnecessary addr32 prefix.
+
+2008-01-29  Roland McGrath  <roland@redhat.com>
+
+	* Makeconfig (ptw-CPPFLAGS, sysd-rules-patterns): New variables.
+
+2008-01-22  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/sem_post.S: Don't overflow value field.
+
+2008-01-21  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h (XADD): Use
+	a scratch register.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S
+	(__lll_lock_wait_private): Fix typo.
+	* sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
+	(pthread_barrier_wait): Likewise.  Adjust XADD use.
+	* sysdeps/unix/sysv/linux/sh/sem_post.S (__new_sem_post):
+	Adjust XADD use.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
+	(pthread_rwlock_timedrdlock): Return correct return value.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
+	(pthread_rwlock_timedwrlock): Likewise.
+
+2008-01-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-eintr2.c (do_test): make sure that if mutex_lock in main
+	thread returns the program exits with an error code.
+
+2008-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread-errnos.sym: Add EOVERFLOW.
+	* sysdeps/unix/sysv/linux/structsem.sym: Add SEM_VALUE_MAX.
+	* sysdeps/unix/sysv/linux/sem_post.c: Don't overflow value field.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+
+2007-12-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/x86_64/pthreaddef.h (ARCH_RETRY_MMAP): Take additional
+	parameter.  Passed it as permission to mmap.
+	* allocatestack.c (allocate_stack): Pass prot as second parameter
+	to ARCH_RETRY_MMAP.
+
+2007-12-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-basic7.c: Allocate memory for the stack.
+
+	[BZ #5465]
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S [!SHARED]
+	(__pthread_cond_timedwait): Don't use VDSO.
+	Patch by Michal Januszewski.
+
+2007-12-07  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #5455]
+	* sysdeps/pthread/pthread.h [!__EXCEPTIONS] (pthread_cleanup_pop):
+	Allow label before pthread_cleanup_pop.
+	(pthread_cleanup_pop_restore_np): Likewise.
+
+2007-12-04  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S (__lll_timedlock_wait):
+	Store 2 before returning ETIMEDOUT.
+
+2007-11-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S (__lll_timedlock_wait):
+	Store 2 before returning ETIMEDOUT.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise
+	* sysdeps/unix/sysv/linux/lowlevellock.c: Likewise.
+	(__lll_lock_wait_private): Optimize.
+	(__lll_lock_wait): Likewise.
+
+2007-11-20  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/pthread/pthread.h (pthread_cleanup_push,
+	pthread_cleanup_push_defer_np): Add extra (void *) cast to shut up
+	g++ 4.1 and 4.2 -Wstrict-aliasing warnings.
+
+2007-11-08  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #5240]
+	* sysdeps/unix/sysv/linux/lowlevellock.c (__lll_timedlock_wait):
+	If we time out, try one last time to lock the futex to avoid
+	losing a wakeup signal.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Likewise.
+
+	[BZ #5245]
+	* sysdeps/pthread/createthread.c (do_clone): Translate clone error
+	if necessary.
+
+2007-11-07  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #5245]
+	* allocatestack.c (allocate_stack): Change ENOMEM error in case
+	mmap failed to EAGAIN.
+	* Makefile (tests): Add tst-basic7.
+	* tst-basic7.c: New file.
+
+2007-11-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/register-atfork.c (__register_atfork):
+	Use __linkin_atfork.
+
+2007-11-03  Mike Frysinger  <vapier@gentoo.org>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S (LOAD_FUTEX_WAIT): Add
+	missing line continuations.
+	* sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S (LOAD_FUTEX_WAIT,
+	LOAD_FUTEX_WAKE): Likewise.  Also add missing 3rd parameter.
+
+2007-10-28  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #5220]
+	* sysdeps/unix/sysv/linux/kernel-posix-timers.h: Declare
+	__active_timer_sigev_thread and __active_timer_sigev_thread_lock.
+	(struct timer): Add next element.
+	* sysdeps/unix/sysv/linux/timer_create.c: For SIGEV_THREAD timers,
+	enqueue timer structure into __active_timer_sigev_thread list.
+	* sysdeps/unix/sysv/linux/timer_delete.c: For SIGEV_THREAD timers,
+	remove timer struct from __active_timer_sigev_thread.
+	* sysdeps/unix/sysv/linux/timer_routines.c (timer_helper_thread):
+	Before using timer structure make sure it is still on the
+	__active_timer_sigev_thread list.  Keep lock until done.
+	Define __active_timer_sigev_thread and
+	__active_timer_sigev_thread_lock.
+
+2007-10-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/malloc-machine.h: Define ATFORK_MEM.
+	Redefine thread_atfork for use of ATFORK_MEM.
+	* sysdeps/unix/sysv/linux/fork.h: Define __linkin_atfork.
+	* sysdeps/unix/sysv/linux/register-atfork.c (__linkin_atfork): New
+	function.
+	* sysdeps/unix/sysv/linux/unregister-atfork.c (__unregister_atfork):
+	Use atomic operation when removing first element of list.
+
+2007-10-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S (__old_sem_post): New
+	routine instead of an alias to __new_sem_post.
+
+2007-10-15  Jakub Jelinek  <jakub@redhat.com>
+
+	* init.c (__pthread_initialize_minimal): Initialize word to appease
+	valgrind.
+
+2007-10-10  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/pthread/bits/libc-lock.h (__libc_rwlock_init): Inside of
+	libc.so just clear NAME.
+	(__libc_rwlock_fini): Nop inside of libc.so.
+	* tst-initializers1.c (main): Test if PTHREAD_RWLOCK_INITIALIZER is
+	all zeros.
+
+2007-09-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+	(__pthread_cond_wait): Fix unlocking of internal lock after mutex
+	unlocking failed.
+	Patch by Luca Barbieri <luca.barbieri@gmail.com>.
+
+2007-08-21  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #4938]
+	* allocatestack.c (__reclaim_stacks): Clear the TSD in the
+	reclaimed stack if necessary.
+	* Makefile (tests): Add tst-tsd6.
+	* tst-tsd6.c: New file.
+
+2007-08-21  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h (lll_robust_dead):
+	Add private argument.
+
+2007-08-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+	(__pthread_cond_timedwait): Use clock_gettime from VDSO if possible.
+
+2007-08-16  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h
+	(__lll_robust_timedlock): Pass private as last argument to
+	__lll_robust_timedlock_wait.
+	(__lll_unlock): Fix a pasto.
+
+2007-08-15  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/sparc/internaltypes.h (sparc_new_sem,
+	sparc_old_sem): New structs.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
+	(__sem_wait_cleanup): New function.
+	(__new_sem_wait): Use sparc_new_sem structure.  Bump and afterwards
+	decrease nwaiters.  Register __sem_wait_cleanup as cleanup handler.
+	Pass isem->private ^ FUTEX_PRIVATE_FLAG as last argument to
+	lll_futex_wait.
+	(__old_sem_wait): New function.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c: Include
+	nptl/sysdeps/unix/sysv/linux/sparc version.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c:
+	Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c
+	(__new_sem_trywait): Use sparc_old_sem structure.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
+	(sem_timedwait): Use sparc_new_sem structure.  Bump and afterwards
+	decrease nwaiters.  Register __sem_wait_cleanup as cleanup handler.
+	Pass isem->private ^ FUTEX_PRIVATE_FLAG as last argument to
+	lll_futex_timed_wait.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c (__new_sem_post):
+	Use sparc_new_sem structure.  Only wake if nwaiters > 0.  Pass
+	isem->private ^ FUTEX_PRIVATE_FLAG as last argument to
+	lll_futex_wake.
+	(__old_sem_post): New function.
+	* sysdeps/unix/sysv/linux/sparc/sem_wait.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sem_init.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sem_timedwait.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sem_post.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_init.c: Remove.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_init.c: Remove.
+
+2007-08-14  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
+	(__pthread_cond_broadcast): Pass LLL_PRIVATE to lll_* and or
+	FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+	Don't use FUTEX_CMP_REQUEUE if dep_mutex is not process private.
+	* sysdeps/unix/sysv/linux/shpthread_cond_signal.S
+	(__pthread_cond_signal): Pass LLL_PRIVATE to lll_* and or
+	FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+	Use FUTEX_WAKE_OP.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Include
+	kernel-features.h and tcb-offsets.h.
+	(__pthread_cond_wait, __condvar_w_cleanup): Pass LLL_PRIVATE to
+	lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is
+	process private.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Include
+	tcb-offsets.h.
+	(__pthread_cond_timedwait, __condvar_tw_cleanup): Pass LLL_PRIVATE
+	to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is
+	process private.
+	* sysdeps/unix/sysv/linux/sh/pthread_once.S: Use #ifdef
+	__ASSUME_PRIVATE_FUTEX instead of #if __ASSUME_PRIVATE_FUTEX.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+
+2007-08-14  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/lowlevellock.c: Comment fix.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c
+	(__lll_timedwait_tid): Pass LLL_SHARED as 4th argument to
+	lll_futex_timed_wait.
+
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h (__lll_unlock,
+	__lll_robust_unlock): Rewrite as macros instead of inline functions.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h (__lll_unlock,
+	__lll_robust_unlock, __lll_wait_tid): Likewise.
+
+2007-08-13  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h (__lll_private_flag):
+	Fix a pasto.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+	(__pthread_cond_broadcast): Pass LLL_PRIVATE to lll_* and or
+	FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+	Don't use FUTEX_CMP_REQUEUE if dep_mutex is not process private.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+	(__pthread_cond_signal): Pass LLL_PRIVATE to lll_* and or
+	FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Include
+	kernel-features.h.
+	(__pthread_cond_wait, __condvar_w_cleanup): Pass LLL_PRIVATE to
+	lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is
+	process private.  Switch DW_CFA_advance_loc1 and some
+	DW_CFA_advance_loc .eh_frame opcodes to DW_CFA_advance_loc4.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+	(__pthread_cond_timedwait, __condvar_tw_cleanup): Pass LLL_PRIVATE to
+	lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is
+	process private.  Switch DW_CFA_advance_loc{1,2} and some
+	DW_CFA_advance_loc .eh_frame opcodes to DW_CFA_advance_loc4.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Use
+	#ifdef __ASSUME_PRIVATE_FUTEX instead of #if __ASSUME_PRIVATE_FUTEX.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+	(__pthread_cond_broadcast): Compare %r8 instead of
+	dep_mutex-cond_*(%rdi) with $-1.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+	(__pthread_cond_signal): Xor FUTEX_WAKE_OP with FUTEX_WAKE instead
+	of oring.
+
+2007-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i786/Implies: New file.
+
+2007-08-13  Jakub Jelinek  <jakub@redhat.com>
+
+	* allocatestack.c: Include kernel-features.h.
+	* pthread_create.c: Likewise.
+	* pthread_mutex_init.c: Likewise.
+	* init.c: Likewise.
+	* pthread_cond_timedwait.c: Likewise.
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+
+2007-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
+	[__WORDSIZE=32] (pthread_rwlock_t): Split __flags element into four
+	byte elements.  One of them is the new __shared element.
+	[__WORDSIZE=64] (pthread_rwlock_t): Renamed __pad1 element to __shared,
+	adjust names of other padding elements.
+	* sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
+	[__WORDSIZE=32] (pthread_rwlock_t): Split __flags element into four
+	byte elements.  One of them is the new __shared element.
+	[__WORDSIZE=64] (pthread_rwlock_t): Renamed __pad1 element to __shared,
+	adjust names of other padding elements.
+	* sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h (pthread_rwlock_t):
+	Renamed __pad1 element to __shared, adjust names of other padding
+	elements.
+	* sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
+	(pthread_rwlock_t): Likewise.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h (__lll_lock): Fix a
+	typo.
+
+2007-08-09  Anton Blanchard  <anton@samba.org>
+
+	* sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c: New file.
+
+2007-08-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Include
+	<kernel-features.h>.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+
+2007-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthreadP.h (PTHREAD_ROBUST_MUTEX_PSHARED): Define.
+	* pthread_mutex_lock.c: Use it instead of PTHREAD_MUTEX_PSHARED when
+	dealing with robust mutexes.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise.
+	* sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c: Likewise.
+
+2007-08-06  Jakub Jelinek  <jakub@redhat.com>
+
+	* pthreadP.h (PTHREAD_MUTEX_PSHARED_BIT): Define.
+	(PTHREAD_MUTEX_TYPE): Mask __kind with 127.
+	(PTHREAD_MUTEX_PSHARED): Define.
+	* pthread_mutex_init.c (__pthread_mutex_init): Set
+	PTHREAD_MUTEX_PSHARED_BIT for pshared or robust
+	mutexes.
+	* pthread_mutex_lock.c (LLL_MUTEX_LOCK): Take mutex as argument
+	instead of its __data.__lock field, pass PTHREAD_MUTEX_PSHARED
+	as second argument to lll_lock.
+	(LLL_MUTEX_TRYLOCK): Take mutex as argument
+	instead of its __data.__lock field.
+	(LLL_ROBUST_MUTEX_LOCK): Take mutex as argument instead of its
+	__data.__lock field, pass PTHREAD_MUTEX_PSHARED as second argument
+	to lll_robust_lock.
+	(__pthread_mutex_lock): Update LLL_MUTEX_LOCK, LLL_MUTEX_TRYLOCK,
+	LLL_ROBUST_MUTEX_LOCK users, use PTHREAD_MUTEX_TYPE (mutex)
+	instead of mutex->__data.__kind directly, pass
+	PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock and lll_futex_wait.
+	* pthread_mutex_trylock.c (__pthread_mutex_trylock): Use
+	PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind
+	directly, pass PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock.
+	(pthread_mutex_timedlock): Pass PTHREAD_MUTEX_PSHARED (mutex)
+	to lll_timedlock, lll_robust_timedlock, lll_unlock and
+	lll_futex_timed_wait.  Use PTHREAD_MUTEX_TYPE (mutex) instead
+	of mutex->__data.__kind directly.
+	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Pass
+	PTHREAD_MUTEX_PSHARED (mutex) to lll_timedlock,
+	lll_robust_timedlock, lll_unlock and lll_futex_timed_wait.  Use
+	PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind directly.
+	* pthread_mutex_unlock.c (__pthread_mutex_unlock_usercnt): Pass
+	PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock, lll_robust_unlock
+	and lll_futex_wake.
+	* pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling): Pass
+	PTHREAD_MUTEX_PSHARED (mutex) to lll_futex_wait and lll_futex_wake.
+	Use PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind
+	directly.
+	* sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c (LLL_MUTEX_LOCK):
+	Take mutex as argument instead of its __data.__lock field, pass
+	PTHREAD_MUTEX_PSHARED as second argument to lll_cond_lock.
+	(LLL_MUTEX_TRYLOCK): Take mutex as argument instead of its
+	__data.__lock field.
+	(LLL_ROBUST_MUTEX_LOCK): Take mutex as argument instead of its
+	__data.__lock field, pass PTHREAD_MUTEX_PSHARED as second argument
+	to lll_robust_cond_lock.
+	* pthread_cond_broadcast.c (__pthread_cond_broadcast): Add pshared
+	variable, pass it to lll_lock, lll_unlock, lll_futex_requeue and
+	lll_futex_wake.  Don't use lll_futex_requeue if dependent mutex
+	has PTHREAD_MUTEX_PSHARED_BIT bit set in its __data.__kind.
+	* pthread_cond_destroy.c (__pthread_cond_destroy): Add pshared
+	variable, pass it to lll_lock, lll_unlock, lll_futex_wake and
+	lll_futex_wait.
+	* pthread_cond_signal.c (__pthread_cond_signal): Add pshared
+	variable, pass it to lll_lock, lll_unlock, lll_futex_wake_unlock and
+	lll_futex_wake.
+	* pthread_cond_timedwait.c (__pthread_cond_wait): Add
+	pshared variable, pass it to lll_lock, lll_unlock,
+	lll_futex_timedwait and lll_futex_wake.
+	* pthread_cond_wait.c (__condvar_cleanup, __pthread_cond_wait): Add
+	pshared variable, pass it to lll_lock, lll_unlock, lll_futex_wait
+	and lll_futex_wake.
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h (lll_futex_requeue,
+	lll_futex_wake_unlock): Add private argument, use __lll_private_flag
+	macro.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h (lll_futex_requeue,
+	lll_futex_wake_unlock): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (lll_futex_requeue):
+	Likewise.
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h (lll_futex_requeue,
+	lll_futex_wake_unlock): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_futex_requeue):
+	Likewise.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h (lll_futex_requeue,
+	lll_futex_wake_unlock): Likewise.
+	(lll_futex_wake): Fix a typo.
+	* sysdeps/unix/sysv/linux/pthread-pi-defines.sym (PS_BIT): Add.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+	(__pthread_cond_broadcast): Pass LLL_PRIVATE to lll_* and or
+	FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+	Don't use FUTEX_CMP_REQUEUE if dep_mutex is not process private.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+	(__pthread_cond_signal): Pass LLL_PRIVATE to lll_* and or
+	FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+	(__pthread_cond_timedwait): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:
+	(__condvar_cleanup, __pthread_cond_wait): Likewise.
+
+2007-08-05  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h (PSEUDO):
+	Don't use CGOTSETUP and CGOTRESTORE macros.
+	(CGOTSETUP, CGOTRESTORE): Remove.
+	<IS_IN_rtld> (CENABLE, CDISABLE): Don't use JUMPTARGET, branch to
+	@local symbol.
+
+2007-08-01  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: Remove
+	definitions for private futexes.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S: Include
+	kernel-features.h and lowlevellock.h.  Use private futexes if
+	they are available.
+	(__lll_lock_wait_private, __lll_unlock_wake_private): New.
+	(__lll_mutex_lock_wait): Rename to
+	(__lll_lock_wait): ... this.  Don't compile in for libc.so.
+	(__lll_mutex_timedlock_wait): Rename to ...
+	(__lll_timedlock_wait): ... this.  Use __NR_gettimeofday.
+	Don't compile in for libc.so.
+	(__lll_mutex_unlock_wake): Rename to ...
+	(__lll_unlock_wake): ... this.  Don't compile in for libc.so.
+	(__lll_timedwait_tid): Use __NR_gettimeofday.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Allow including
+	the header from assembler.  Renamed all lll_mutex_* resp.
+	lll_robust_mutex_* macros to lll_* resp. lll_robust_*.
+	Renamed all LLL_MUTEX_LOCK_* macros to LLL_LOCK_*.
+	(FUTEX_CMP_REQUEUE, FUTEX_WAKE_OP, FUTEX_OP_CLEAR_WAKE_IF_GT_ONE):
+	Define.
+	(__lll_lock_wait_private): Add prototype.
+	(__lll_lock_wait, __lll_timedlock_wait, __lll_robust_lock_wait,
+	__lll_robust_timedlock_wait, __lll_unlock_wake_private,
+	__lll_unlock_wake): Likewise.
+	(lll_lock): Add private argument.  Call __lll_lock_wait_private
+	if private is constant LLL_PRIVATE.
+	(lll_robust_lock, lll_cond_lock, lll_robust_cond_lock,
+	lll_timedlock, lll_robust_timedlock): Add private argument.
+	(lll_unlock): Add private argument.  Call __lll_unlock_wake_private
+	if private is constant LLL_PRIVATE.
+	(lll_robust_unlock, lll_robust_dead): Add private argument.
+	(lll_lock_t): Remove.
+	(__lll_cond_wait, __lll_cond_timedwait, __lll_cond_wake,
+	__lll_cond_broadcast, lll_cond_wait, lll_cond_timedwait,
+	lll_cond_wake, lll_cond_broadcast): Remove.
+	* sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S: Include
+	kernel-features.h and lowlevellock.h.
+	(SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Remove.
+	(LOAD_FUTEX_WAIT): Define.
+	(__lll_robust_mutex_lock_wait): Rename to ...
+	(__lll_robust_lock_wait): ... this.  Add private argument.
+	Use LOAD_FUTEX_WAIT macro.
+	(__lll_robust_mutex_timedlock_wait): Rename to ...
+	(__lll_robust_timedlock_wait): ... this.    Add private argument.
+	Use __NR_gettimeofday.  Use LOAD_FUTEX_WAIT macro.
+	* sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: Include
+	lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Remove.
+	(pthread_barrier_wait): Use __lll_{lock,unlock}_* instead of
+	__lll_mutex_{lock,unlock}_*.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: Include
+	lowlevellock.h and pthread-errnos.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE,
+	FUTEX_CMP_REQUEUE, EINVAL): Remove.
+	(__pthread_cond_broadcast): Use __lll_{lock,unlock}_* instead of
+	__lll_mutex_{lock,unlock}_*.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: Include
+	lowlevellock.h and pthread-errnos.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE, EINVAL): Remove.
+	(__pthread_cond_signal): Use __lll_{lock,unlock}_* instead of
+	__lll_mutex_{lock,unlock}_*.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Include
+	lowlevellock.h.
+	(SYS_futex, SYS_gettimeofday, FUTEX_WAIT, FUTEX_WAKE): Remove.
+	(__pthread_cond_timedwait): Use __lll_{lock,unlock}_* instead of
+	__lll_mutex_{lock,unlock}_*.  Use __NR_gettimeofday.
+	(__condvar_tw_cleanup): Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Include
+	lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Remove.
+	(__pthread_cond_wait): Use __lll_{lock,unlock}_* instead of
+	__lll_mutex_{lock,unlock}_*.
+	( __condvar_w_cleanup): Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_once.S: Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Include
+	lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove.
+	(__pthread_rwlock_rdlock): Use __lll_{lock,unlock}_* instead of
+	__lll_mutex_{lock,unlock}_*.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Include
+	lowlevellock.h.
+	(SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE,
+	FUTEX_PRIVATE_FLAG): Remove.
+	(pthread_rwlock_timedrdlock): Use __lll_{lock,unlock}_* instead of
+	__lll_mutex_{lock,unlock}_*.  Use __NR_gettimeofday.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Include
+	lowlevellock.h.
+	(SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE,
+	FUTEX_PRIVATE_FLAG): Remove.
+	(pthread_rwlock_timedwrlock): Use __lll_{lock,unlock}_* instead of
+	__lll_mutex_{lock,unlock}_*.  Use __NR_gettimeofday.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Include
+	lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove.
+	(__pthread_rwlock_unlock): Use __lll_{lock,unlock}_* instead of
+	__lll_mutex_{lock,unlock}_*.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Include
+	lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove.
+	(__pthread_rwlock_wrlock): Use __lll_{lock,unlock}_* instead of
+	__lll_mutex_{lock,unlock}_*.
+	* sysdeps/unix/sysv/linux/sh/sem_post.S: Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove.
+	(__new_sem_post): Use standard initial exec code sequences.
+	* sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Include
+	lowlevellock.h.
+	(SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE,
+	FUTEX_PRIVATE_FLAG): Remove.
+	(sem_timedwait): Use __NR_gettimeofday.  Use standard initial
+	exec code sequences.
+	* sysdeps/unix/sysv/linux/sh/sem_trywait.S: Include lowlevellock.h.
+	(__new_sem_trywait): Use standard initial exec code sequences.
+	* sysdeps/unix/sysv/linux/sh/sem_wait.S: Include lowlevellock.h.
+	(__new_sem_wait): Use standard initial exec code sequences.
+
+2007-07-31  Anton Blanchard  <anton@samba.org>
+
+	* sysdeps/unix/sysv/linux/powerpc/sem_post.c (__new_sem_post):
+	Use __asm __volatile (__lll_acq_instr ::: "memory") instead of
+	atomic_full_barrier.
+
+2007-07-31  Jakub Jelinek  <jakub@redhat.com>
+
+	* allocatestack.c (stack_cache_lock): Change type to int.
+	(get_cached_stack, allocate_stack, __deallocate_stack,
+	__make_stacks_executable, __find_thread_by_id, __nptl_setxid,
+	__pthread_init_static_tls, __wait_lookup_done): Add LLL_PRIVATE
+	as second argument to lll_lock and lll_unlock macros on
+	stack_cache_lock.
+	* pthread_create.c (__find_in_stack_list): Likewise.
+	(start_thread): Similarly with pd->lock.  Use lll_robust_dead
+	macro instead of lll_robust_mutex_dead, pass LLL_SHARED to it
+	as second argument.
+	* descr.h (struct pthread): Change lock and setxid_futex field
+	type to int.
+	* old_pthread_cond_broadcast.c (__pthread_cond_broadcast_2_0): Use
+	LLL_LOCK_INITIALIZER instead of LLL_MUTEX_LOCK_INITIALIZER.
+	* old_pthread_cond_signal.c (__pthread_cond_signal_2_0): Likewise.
+	* old_pthread_cond_timedwait.c (__pthread_cond_timedwait_2_0):
+	Likewise.
+	* old_pthread_cond_wait.c (__pthread_cond_wait_2_0): Likewise.
+	* pthread_cond_init.c (__pthread_cond_init): Likewise.
+	* pthreadP.h (__attr_list_lock): Change type to int.
+	* pthread_attr_init.c (__attr_list_lock): Likewise.
+	* pthread_barrier_destroy.c (pthread_barrier_destroy): Pass
+	ibarrier->private ^ FUTEX_PRIVATE_FLAG as second argument to
+	lll_{,un}lock.
+	* pthread_barrier_wait.c (pthread_barrier_wait): Likewise and
+	also for lll_futex_{wake,wait}.
+	* pthread_barrier_init.c (pthread_barrier_init): Make iattr
+	a pointer to const.
+	* pthread_cond_broadcast.c (__pthread_cond_broadcast): Pass
+	LLL_SHARED as second argument to lll_{,un}lock.
+	* pthread_cond_destroy.c (__pthread_cond_destroy): Likewise.
+	* pthread_cond_signal.c (__pthread_cond_singal): Likewise.
+	* pthread_cond_timedwait.c (__pthread_cond_timedwait): Likewise.
+	* pthread_cond_wait.c (__condvar_cleanup, __pthread_cond_wait):
+	Likewise.
+	* pthread_getattr_np.c (pthread_getattr_np): Add LLL_PRIVATE
+	as second argument to lll_{,un}lock macros on pd->lock.
+	* pthread_getschedparam.c (__pthread_getschedparam): Likewise.
+	* pthread_setschedparam.c (__pthread_setschedparam): Likewise.
+	* pthread_setschedprio.c (pthread_setschedprio): Likewise.
+	* tpp.c (__pthread_tpp_change_priority, __pthread_current_priority):
+	Likewise.
+	* sysdeps/pthread/createthread.c (do_clone, create_thread):
+	Likewise.
+	* pthread_once.c (once_lock): Change type to int.
+	(__pthread_once): Pass LLL_PRIVATE as second argument to
+	lll_{,un}lock macros on once_lock.
+	* pthread_rwlock_rdlock.c (__pthread_rwlock_rdlock): Use
+	lll_{,un}lock macros instead of lll_mutex_{,un}lock, pass
+	rwlock->__data.__shared as second argument to them and similarly
+	for lll_futex_w*.
+	* pthread_rwlock_timedrdlock.c (pthread_rwlock_timedrdlock):
+	Likewise.
+	* pthread_rwlock_timedwrlock.c (pthread_rwlock_timedwrlock):
+	Likewise.
+	* pthread_rwlock_tryrdlock.c (__pthread_rwlock_tryrdlock): Likewise.
+	* pthread_rwlock_trywrlock.c (__pthread_rwlock_trywrlock): Likewise.
+	* pthread_rwlock_unlock.c (__pthread_rwlock_unlock): Likewise.
+	* pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock): Likewise.
+	* sem_close.c (sem_close): Pass LLL_PRIVATE as second argument
+	to lll_{,un}lock macros on __sem_mappings_lock.
+	* sem_open.c (check_add_mapping): Likewise.
+	(__sem_mappings_lock): Change type to int.
+	* semaphoreP.h (__sem_mappings_lock): Likewise.
+	* pthread_mutex_lock.c (LLL_MUTEX_LOCK, LLL_MUTEX_TRYLOCK,
+	LLL_ROBUST_MUTEX_LOCK): Use lll_{,try,robust_}lock macros
+	instead of lll_*mutex_*, pass LLL_SHARED as last
+	argument.
+	(__pthread_mutex_lock): Use lll_unlock instead of lll_mutex_unlock,
+	pass LLL_SHARED as last argument.
+	* sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c (LLL_MUTEX_LOCK,
+	LLL_MUTEX_TRYLOCK, LLL_ROBUST_MUTEX_LOCK): Use
+	lll_{cond_,cond_try,robust_cond}lock macros instead of lll_*mutex_*,
+	pass LLL_SHARED as last argument.
+	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Use
+	lll_{timed,try,robust_timed,un}lock instead of lll_*mutex*, pass
+	LLL_SHARED as last argument.
+	* pthread_mutex_trylock.c (__pthread_mutex_trylock): Similarly.
+	* pthread_mutex_unlock.c (__pthread_mutex_unlock_usercnt):
+	Similarly.
+	* sysdeps/pthread/bits/libc-lock.h (__libc_lock_lock,
+	__libc_lock_lock_recursive, __libc_lock_unlock,
+	__libc_lock_unlock_recursive): Pass LLL_PRIVATE as second
+	argument to lll_{,un}lock.
+	* sysdeps/pthread/bits/stdio-lock.h (_IO_lock_lock,
+	_IO_lock_unlock): Likewise.
+	* sysdeps/unix/sysv/linux/fork.c (__libc_fork): Don't use
+	compound literal.
+	* sysdeps/unix/sysv/linux/unregister-atfork.c (__unregister_atfork):
+	Pass LLL_PRIVATE as second argument to lll_{,un}lock macros on
+	__fork_lock.
+	* sysdeps/unix/sysv/linux/register-atfork.c (__register_atfork,
+	free_mem): Likewise.
+	(__fork_lock): Change type to int.
+	* sysdeps/unix/sysv/linux/fork.h (__fork_lock): Likewise.
+	* sysdeps/unix/sysv/linux/sem_post.c (__new_sem_post): Pass
+	isem->private ^ FUTEX_PRIVATE_FLAG as second argument to
+	lll_futex_wake.
+	* sysdeps/unix/sysv/linux/sem_timedwait.c (sem_timedwait): Likewise.
+	* sysdeps/unix/sysv/linux/sem_wait.c (__new_sem_wait): Likewise.
+	* sysdeps/unix/sysv/linux/lowlevellock.c (__lll_lock_wait_private):
+	New function.
+	(__lll_lock_wait, __lll_timedlock_wait): Add private argument and
+	pass it through to lll_futex_*wait, only compile in when
+	IS_IN_libpthread.
+	* sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+	(__lll_robust_lock_wait, __lll_robust_timedlock_wait): Add private
+	argument and pass it through to lll_futex_*wait.
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h: Renamed all
+	lll_mutex_* resp. lll_robust_mutex_* macros to lll_* resp.
+	lll_robust_*.  Renamed all __lll_mutex_* resp. __lll_robust_mutex_*
+	inline functions to __lll_* resp. __lll_robust_*.
+	(LLL_MUTEX_LOCK_INITIALIZER): Remove.
+	(lll_mutex_dead): Add private argument.
+	(__lll_lock_wait_private): New prototype.
+	(__lll_lock_wait, __lll_robust_lock_wait, __lll_lock_timedwait,
+	__lll_robust_lock_timedwait): Add private argument to prototypes.
+	(__lll_lock): Add private argument, if it is constant LLL_PRIVATE,
+	call __lll_lock_wait_private, otherwise pass private to
+	__lll_lock_wait.
+	(__lll_robust_lock, __lll_cond_lock, __lll_timedlock,
+	__lll_robust_timedlock): Add private argument, pass it to
+	__lll_*wait functions.
+	(__lll_unlock): Add private argument, if it is constant LLL_PRIVATE,
+	call __lll_unlock_wake_private, otherwise pass private to
+	__lll_unlock_wake.
+	(__lll_robust_unlock): Add private argument, pass it to
+	__lll_robust_unlock_wake.
+	(lll_lock, lll_robust_lock, lll_cond_lock, lll_timedlock,
+	lll_robust_timedlock, lll_unlock, lll_robust_unlock): Add private
+	argument, pass it through to __lll_* inline function.
+	(__lll_mutex_unlock_force, lll_mutex_unlock_force): Remove.
+	(lll_lock_t): Remove.
+	(__lll_cond_wait, __lll_cond_timedwait, __lll_cond_wake,
+	__lll_cond_broadcast, lll_cond_wait, lll_cond_timedwait,
+	lll_cond_wake, lll_cond_broadcast): Remove.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Allow including
+	the header from assembler.  Renamed all lll_mutex_* resp.
+	lll_robust_mutex_* macros to lll_* resp. lll_robust_*.
+	(LOCK, FUTEX_CMP_REQUEUE, FUTEX_WAKE_OP,
+	FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+	(LLL_MUTEX_LOCK_INITIALIZER, LLL_MUTEX_LOCK_INITIALIZER_LOCKED,
+	LLL_MUTEX_LOCK_INITIALIZER_WAITERS): Remove.
+	(__lll_mutex_lock_wait, __lll_mutex_timedlock_wait,
+	__lll_mutex_unlock_wake, __lll_lock_wait, __lll_unlock_wake):
+	Remove prototype.
+	(__lll_trylock_asm, __lll_lock_asm_start, __lll_unlock_asm): Define.
+	(lll_robust_trylock, lll_cond_trylock): Use LLL_LOCK_INITIALIZER*
+	rather than LLL_MUTEX_LOCK_INITIALIZER* macros.
+	(lll_trylock): Likewise, use __lll_trylock_asm, pass
+	MULTIPLE_THREADS_OFFSET as another asm operand.
+	(lll_lock): Add private argument, use __lll_lock_asm_start, pass
+	MULTIPLE_THREADS_OFFSET as last asm operand, call
+	__lll_lock_wait_private if private is constant LLL_PRIVATE,
+	otherwise pass private as another argument to __lll_lock_wait.
+	(lll_robust_lock, lll_cond_lock, lll_robust_cond_lock,
+	lll_timedlock, lll_robust_timedlock): Add private argument, pass
+	private as another argument to __lll_*lock_wait call.
+	(lll_unlock): Add private argument, use __lll_unlock_asm, pass
+	MULTIPLE_THREADS_OFFSET as another asm operand, call
+	__lll_unlock_wake_private if private is constant LLL_PRIVATE,
+	otherwise pass private as another argument to __lll_unlock_wake.
+	(lll_robust_unlock): Add private argument, pass private as another
+	argument to __lll_unlock_wake.
+	(lll_robust_dead): Add private argument, use __lll_private_flag
+	macro.
+	(lll_islocked): Use LLL_LOCK_INITIALIZER instead of
+	LLL_MUTEX_LOCK_INITIALIZER.
+	(lll_lock_t): Remove.
+	(LLL_LOCK_INITIALIZER_WAITERS): Define.
+	(__lll_cond_wait, __lll_cond_timedwait, __lll_cond_wake,
+	__lll_cond_broadcast, lll_cond_wait, lll_cond_timedwait,
+	lll_cond_wake, lll_cond_broadcast): Remove.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Revert
+	2007-05-2{3,9} changes.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Include
+	kernel-features.h and lowlevellock.h.
+	(LOAD_PRIVATE_FUTEX_WAIT): Define.
+	(LOAD_FUTEX_WAIT): Rewritten.
+	(LOCK, SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Don't
+	define.
+	(__lll_lock_wait_private, __lll_unlock_wake_private): New functions.
+	(__lll_mutex_lock_wait): Rename to ...
+	(__lll_lock_wait): ... this.  Take futex addr from %edx instead of
+	%ecx, %ecx is now private argument.  Don't compile in for libc.so.
+	(__lll_mutex_timedlock_wait): Rename to ...
+	(__lll_timedlock_wait): ... this.  Use __NR_gettimeofday.  %esi
+	contains private argument.  Don't compile in for libc.so.
+	(__lll_mutex_unlock_wake): Rename to ...
+	(__lll_unlock_wake): ... this.  %ecx contains private argument.
+	Don't compile in for libc.so.
+	(__lll_timedwait_tid): Use __NR_gettimeofday.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S: Include
+	kernel-features.h and lowlevellock.h.
+	(LOAD_FUTEX_WAIT): Define.
+	(LOCK, SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Don't
+	define.
+	(__lll_robust_mutex_lock_wait): Rename to ...
+	(__lll_robust_lock_wait): ... this.  Futex addr is now in %edx
+	argument, %ecx argument contains private.  Use LOAD_FUTEX_WAIT
+	macro.
+	(__lll_robust_mutex_timedlock_wait): Rename to ...
+	(__lll_robust_timedlock_wait): ... this.  Use __NR_gettimeofday.
+	%esi argument contains private, use LOAD_FUTEX_WAIT macro.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S: Include
+	lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, LOCK): Don't define.
+	(pthread_barrier_wait): Rename __lll_mutex_* to __lll_*, pass
+	PRIVATE(%ebx) ^ LLL_SHARED as private argument in %ecx to
+	__lll_lock_wait and __lll_unlock_wake, pass MUTEX(%ebx) address
+	to __lll_lock_wait in %edx.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S:
+	Include lowlevellock.h and pthread-errnos.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE,
+	FUTEX_CMP_REQUEUE, EINVAL, LOCK): Don't define.
+	(__pthread_cond_broadcast): Rename __lll_mutex_* to __lll_*, pass
+	cond_lock address in %edx rather than %ecx to __lll_lock_wait,
+	pass LLL_SHARED in %ecx to both __lll_lock_wait and
+	__lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S:
+	Include lowlevellock.h and pthread-errnos.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_WAKE_OP,
+	FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, EINVAL, LOCK): Don't define.
+	(__pthread_cond_signal): Rename __lll_mutex_* to __lll_*, pass
+	cond_lock address in %edx rather than %ecx to __lll_lock_wait,
+	pass LLL_SHARED in %ecx to both __lll_lock_wait and
+	__lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S:
+	Include lowlevellock.h.
+	(SYS_futex, SYS_gettimeofday, FUTEX_WAIT, FUTEX_WAKE, LOCK):
+	Don't define.
+	(__pthread_cond_timedwait): Rename __lll_mutex_* to __lll_*, pass
+	cond_lock address in %edx rather than %ecx to __lll_lock_wait,
+	pass LLL_SHARED in %ecx to both __lll_lock_wait and
+	__lll_unlock_wake.  Use __NR_gettimeofday.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, LOCK): Don't define.
+	(__pthread_cond_wait, __condvar_w_cleanup): Rename __lll_mutex_*
+	to __lll_*, pass cond_lock address in %edx rather than %ecx to
+	__lll_lock_wait, pass LLL_SHARED in %ecx to both __lll_lock_wait
+	and __lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, LOCK): Don't define.
+	(__pthread_rwlock_rdlock): Rename __lll_mutex_* to __lll_*, pass
+	MUTEX(%ebx) address in %edx rather than %ecx to
+	__lll_lock_wait, pass PSHARED(%ebx) in %ecx to both __lll_lock_wait
+	and __lll_unlock_wake.  Move return value from %ecx to %edx
+	register.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+	Include lowlevellock.h.
+	(SYS_futex, SYS_gettimeofday, FUTEX_WAIT, FUTEX_WAKE, LOCK):
+	Don't define.
+	(__pthread_rwlock_wrlock): Rename __lll_mutex_* to __lll_*, pass
+	MUTEX(%ebp) address in %edx rather than %ecx to
+	__lll_lock_wait, pass PSHARED(%ebp) in %ecx to both __lll_lock_wait
+	and __lll_unlock_wake.  Move return value from %ecx to %edx
+	register.  Use __NR_gettimeofday.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+	Include lowlevellock.h.
+	(SYS_futex, SYS_gettimeofday, FUTEX_WAIT, FUTEX_WAKE, LOCK):
+	Don't define.
+	(__pthread_rwlock_wrlock): Rename __lll_mutex_* to __lll_*, pass
+	MUTEX(%ebp) address in %edx rather than %ecx to
+	__lll_lock_wait, pass PSHARED(%ebp) in %ecx to both __lll_lock_wait
+	and __lll_unlock_wake.  Move return value from %ecx to %edx
+	register.  Use __NR_gettimeofday.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, LOCK): Don't define.
+	(__pthread_rwlock_unlock): Rename __lll_mutex_* to __lll_*, pass
+	MUTEX(%edi) address in %edx rather than %ecx to
+	__lll_lock_wait, pass PSHARED(%edi) in %ecx to both __lll_lock_wait
+	and __lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, LOCK): Don't define.
+	(__pthread_rwlock_wrlock): Rename __lll_mutex_* to __lll_*, pass
+	MUTEX(%ebx) address in %edx rather than %ecx to
+	__lll_lock_wait, pass PSHARED(%ebx) in %ecx to both __lll_lock_wait
+	and __lll_unlock_wake.  Move return value from %ecx to %edx
+	register.
+	* sysdeps/unix/sysv/linux/i386/pthread_once.S: Include
+	lowlevellock.h.
+	(LOCK, SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Don't
+	define.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Include lowlevellock.h.
+	(LOCK, SYS_futex, FUTEX_WAKE): Don't define.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Include
+	lowlevellock.h.
+	(LOCK, SYS_futex, SYS_gettimeofday, FUTEX_WAIT): Don't define.
+	(sem_timedwait): Use __NR_gettimeofday.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S: Include
+	lowlevellock.h.
+	(LOCK): Don't define.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Include
+	lowlevellock.h.
+	(LOCK, SYS_futex, FUTEX_WAIT): Don't define.
+	* sysdeps/unix/sysv/linux/powerpc/sem_post.c: Wake only when there
+	are waiters.
+	* sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S: Revert
+	2007-05-2{3,9} changes.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Include
+	kernel-features.h and lowlevellock.h.
+	(LOAD_PRIVATE_FUTEX_WAIT): Define.
+	(LOAD_FUTEX_WAIT): Rewritten.
+	(LOCK, SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Don't define.
+	(__lll_lock_wait_private, __lll_unlock_wake_private): New functions.
+	(__lll_mutex_lock_wait): Rename to ...
+	(__lll_lock_wait): ... this.  %esi is now private argument.
+	Don't compile in for libc.so.
+	(__lll_mutex_timedlock_wait): Rename to ...
+	(__lll_timedlock_wait): ... this.  %esi contains private argument.
+	Don't compile in for libc.so.
+	(__lll_mutex_unlock_wake): Rename to ...
+	(__lll_unlock_wake): ... this.  %esi contains private argument.
+	Don't compile in for libc.so.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S: Include
+	kernel-features.h and lowlevellock.h.
+	(LOAD_FUTEX_WAIT): Define.
+	(LOCK, SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Don't define.
+	(__lll_robust_mutex_lock_wait): Rename to ...
+	(__lll_robust_lock_wait): ... this.  %esi argument contains private.
+	Use LOAD_FUTEX_WAIT macro.
+	(__lll_robust_mutex_timedlock_wait): Rename to ...
+	(__lll_robust_timedlock_wait): ... this. %esi argument contains
+	private, use LOAD_FUTEX_WAIT macro.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S: Include
+	lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, LOCK): Don't define.
+	(pthread_barrier_wait): Rename __lll_mutex_* to __lll_*, pass
+	PRIVATE(%rdi) ^ LLL_SHARED as private argument in %esi to
+	__lll_lock_wait and __lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S:
+	Include lowlevellock.h and pthread-errnos.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE,
+	FUTEX_CMP_REQUEUE, EINVAL, LOCK): Don't define.
+	(__pthread_cond_broadcast): Rename __lll_mutex_* to __lll_*,
+	pass LLL_SHARED in %esi to both __lll_lock_wait and
+	__lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S:
+	Include lowlevellock.h and pthread-errnos.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_WAKE_OP,
+	FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, EINVAL, LOCK): Don't define.
+	(__pthread_cond_signal): Rename __lll_mutex_* to __lll_*,
+	pass LLL_SHARED in %esi to both __lll_lock_wait and
+	__lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, LOCK): Don't define.
+	(__pthread_cond_timedwait): Rename __lll_mutex_* to __lll_*,
+	pass LLL_SHARED in %esi to both __lll_lock_wait and
+	__lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, LOCK): Don't define.
+	(__pthread_cond_wait, __condvar_cleanup): Rename __lll_mutex_*
+	to __lll_*, pass LLL_SHARED in %esi to both __lll_lock_wait
+	and __lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG, LOCK):
+	Don't define.
+	(__pthread_rwlock_rdlock): Rename __lll_mutex_* to __lll_*,
+	pass PSHARED(%rdi) in %esi to both __lll_lock_wait
+	and __lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG, LOCK):
+	Don't define.
+	(__pthread_rwlock_wrlock): Rename __lll_mutex_* to __lll_*,
+	pass PSHARED(%rdi) in %esi to both __lll_lock_wait
+	and __lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG, LOCK):
+	Don't define.
+	(__pthread_rwlock_wrlock): Rename __lll_mutex_* to __lll_*,
+	pass PSHARED(%rdi) in %esi to both __lll_lock_wait
+	and __lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG, LOCK):
+	Don't define.
+	(__pthread_rwlock_unlock): Rename __lll_mutex_* to __lll_*,
+	pass PSHARED(%rdi) in %esi to both __lll_lock_wait
+	and __lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S:
+	Include lowlevellock.h.
+	(SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG, LOCK):
+	Don't define.
+	(__pthread_rwlock_wrlock): Rename __lll_mutex_* to __lll_*,
+	pass PSHARED(%rdi) in %ecx to both __lll_lock_wait
+	and __lll_unlock_wake.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Include
+	lowlevellock.h.
+	(LOCK, SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Don't
+	define.
+	* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Include lowlevellock.h.
+	(LOCK, SYS_futex, FUTEX_WAKE): Don't define.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Include
+	lowlevellock.h.
+	(LOCK, SYS_futex, FUTEX_WAIT): Don't define.
+	* sysdeps/unix/sysv/linux/x86_64/sem_trywait.S: Include
+	lowlevellock.h.
+	(LOCK): Don't define.
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Include
+	lowlevellock.h.
+	(LOCK, SYS_futex, FUTEX_WAIT): Don't define.
+	* sysdeps/unix/sysv/linux/sparc/internaltypes.h: New file.
+	* sysdeps/unix/sysv/linux/sparc/pthread_barrier_destroy.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/pthread_barrier_init.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/pthread_barrier_wait.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c
+	(__lll_lock_wait_private): New function.
+	(__lll_lock_wait, __lll_timedlock_wait): Add private argument, pass
+	it to lll_futex_*wait.  Don't compile in for libc.so.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_init.c:
+	Remove.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c
+	(struct sparc_pthread_barrier): Remove.
+	(pthread_barrier_wait): Use union sparc_pthread_barrier instead of
+	struct sparc_pthread_barrier.  Pass
+	ibarrier->s.pshared ? LLL_SHARED : LLL_PRIVATE to lll_{,un}lock
+	and lll_futex_wait macros.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_init.c:
+	Remove.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c:
+	Include sparc pthread_barrier_wait.c instead of generic one.
+
+2007-07-30  Jakub Jelinek  <jakub@redhat.com>
+
+	* tst-rwlock14.c (do_test): Avoid warnings on 32-bit arches.
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
+	(pthread_rwlock_timedrdlock): Copy futex retval to %esi rather than
+	%ecx.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
+	(pthread_rwlock_timedwrlock): Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
+	(__pthread_rwlock_unlock): Fix MUTEX != 0 args to __lll_*.
+
+2007-07-31  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/sparc/tls.h (tcbhead_t): Add private_futex field.
+
+2007-07-26  Jakub Jelinek  <jakub@redhat.com>
+
+	* tst-locale2.c (useless): Add return statement.
+
+2007-07-24  Jakub Jelinek  <jakub@redhat.com>
+
+	* allocatestack.c (__nptl_setxid, __wait_lookup_done): Replace
+	lll_private_futex_* (*) with lll_futex_* (*, LLL_PRIVATE).
+	* pthread_create.c (start_thread): Likewise.
+	* init.c (sighandler_setxid): Likewise.
+	* sysdeps/alpha/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/ia64/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/i386/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/s390/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/powerpc/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/x86_64/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/sparc/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/sh/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+	* sysdeps/pthread/aio_misc.h (AIO_MISC_NOTIFY, AIO_MISC_WAIT):
+	Likewise.
+	* sysdeps/pthread/gai_misc.h (GAI_MISC_NOTIFY, GAI_MISC_WAIT):
+	Likewise.
+	* sysdeps/unix/sysv/linux/unregister-atfork.c (__unregister_atfork):
+	Likewise.
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h (__rtld_waitzero,
+	__rtld_notify): Likewise.
+	* sysdeps/unix/sysv/linux/fork.c (__libc_fork): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/pthread_once.c (clear_once_control,
+	__pthread_once): Likewise.
+	* sysdeps/unix/sysv/linux/alpha/pthread_once.c (clear_once_control,
+	__pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+	LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+	(lll_futex_wait): Add private argument, define as wrapper around
+	lll_futex_timed_wait.
+	(lll_futex_timed_wait, lll_futex_wake): Add private argument,
+	use __lll_private_flag macro.
+	(lll_robust_mutex_dead, __lll_mutex_unlock, __lll_robust_mutex_unlock,
+	__lll_mutex_unlock_force): Pass LLL_SHARED as last arg to lll_futex_*.
+	* sysdeps/unix/sysv/linux/ia64/pthread_once.c (clear_once_control,
+	__pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+	LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+	(lll_futex_wait): Add private argument, define as wrapper around
+	lll_futex_timed_wait.
+	(lll_futex_timed_wait, lll_futex_wake): Add private argument,
+	use __lll_private_flag macro.
+	(__lll_mutex_unlock, __lll_robust_mutex_unlock, lll_wait_tid,
+	__lll_mutex_unlock_force): Pass LLL_SHARED as last arg to lll_futex_*.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h (__lll_private_flag):
+	Define.
+	(lll_futex_timed_wait, lll_futex_wake): Use it.
+	(lll_private_futex_wait, lll_private_futex_timed_wait,
+	lll_private_futex_wake): Removed.
+	* sysdeps/unix/sysv/linux/s390/pthread_once.c (clear_once_control,
+	__pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+	LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+	(lll_futex_wait): Add private argument, define as wrapper around
+	lll_futex_timed_wait.
+	(lll_futex_timed_wait, lll_futex_wake): Add private argument,
+	use __lll_private_flag macro.
+	(lll_robust_mutex_dead, __lll_mutex_unlock, __lll_robust_mutex_unlock,
+	lll_wait_tid, __lll_mutex_unlock_force): Pass LLL_SHARED as last arg
+	to lll_futex_*.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+	(lll_private_futex_wait, lll_private_futex_timed_wait,
+	lll_private_futex_wake): Removed.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (__lll_private_flag):
+	Fix !__ASSUME_PRIVATE_FUTEX non-constant private case.
+	(lll_private_futex_wait, lll_private_futex_timed_wait,
+	lll_private_futex_wake): Removed.
+	* sysdeps/unix/sysv/linux/sparc/pthread_once.c (clear_once_control,
+	__pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+	LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+	(lll_futex_wait): Add private argument, define as wrapper around
+	lll_futex_timed_wait.
+	(lll_futex_timed_wait, lll_futex_wake): Add private argument,
+	use __lll_private_flag macro.
+	(lll_robust_mutex_dead, __lll_mutex_unlock, __lll_robust_mutex_unlock,
+	lll_wait_tid, __lll_mutex_unlock_force): Pass LLL_SHARED as last arg
+	to lll_futex_*.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h (__lll_private_flag):
+	Define.
+	(lll_futex_timed_wait, lll_futex_wake): Use it.
+	(lll_private_futex_wait, lll_private_futex_timed_wait,
+	lll_private_futex_wake): Removed.
+
+2007-07-27  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/sparc/tls.h (tcbhead_t): Move gscope_flag to the end
+	of the structure for sparc32.
+
+2007-07-26  Aurelien Jarno  <aurelien@aurel32.net>
+
+	* sysdeps/sparc/tls.h (tcbhead_t): Add gscope_flag.
+
+2007-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S: Fix
+	code used when private futexes are assumed.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+	Likewise.
+
+2007-07-23  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+	(__lll_private_flag): Define.
+	(lll_futex_wait): Define as a wrapper around lll_futex_timed_wait.
+	(lll_futex_timed_wait, lll_futex_wake, lll_futex_wake_unlock): Use
+	__lll_private_flag.
+	(lll_private_futex_wait, lll_private_futex_timedwait,
+	lll_private_futex_wake): Define as wrapper around non-_private
+	macros.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+	(__lll_private_flag): Define.
+	(lll_futex_timed_wait, lll_futex_wake): Use __lll_private_flag.
+	(lll_private_futex_wait, lll_private_futex_timedwait,
+	lll_private_futex_wake): Define as wrapper around non-_private
+	macros.
+
+2007-07-10  Steven Munroe  <sjmunroe@us.ibm.com>
+
+	* pthread_rwlock_rdlock.c (__pthread_rwlock_rdlock): Add LLL_SHARED
+	parameter to lll_futex_wait call.
+	* pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock): Likewise.
+
+	* sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once):
+	Replace lll_futex_wait with lll_private_futex_wait.
+	* sysdeps/unix/sysv/linux/powerpc/sem_post.c (__new_sem_post):
+	Add LLL_SHARED parameter to lll_futex_wake().
+
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Define LLL_PRIVATE
+	LLL_SHARED, lll_private_futex_wait, lll_private_futex_timed_wait and
+	lll_private_futex_wake.
+	(lll_futex_wait): Add private parameter. Adjust FUTEX_PRIVATE_FLAG
+	bit from private parm before syscall.
+	(lll_futex_timed_wait): Likewise.
+	(lll_futex_wake): Likewise.
+	(lll_futex_wake_unlock): Likewise.
+	(lll_mutex_unlock): Add LLL_SHARED parm to lll_futex_wake call.
+	(lll_robust_mutex_unlock): Likewise.
+	(lll_mutex_unlock_force): Likewise.
+	(lll_wait_tid): Add LLL_SHARED parm to lll_futex_wait call.
+
+2007-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S: Fix
+	compilation when unconditionally using private futexes.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+
+2007-07-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/pthread/bits/stdio-lock.h (_IO_acquire_lock_clear_flags2):
+	Define.
+
+2007-07-06  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/sh/tls.h: Include stdlib.h, list.h, sysdep.h and
+	kernel-features.h.
+
+2007-05-16  Roland McGrath  <roland@redhat.com>
+
+	* init.c (__nptl_initial_report_events): New variable.
+	(__pthread_initialize_minimal_internal): Initialize pd->report_events
+	to that.
+
+2007-06-22  Jakub Jelinek  <jakub@redhat.com>
+
+	* pthread_getattr_np.c (pthread_getattr_np): Clear cpuset and
+	cpusetsize if pthread_getaffinity_np failed with ENOSYS.
+
+2007-06-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h: Remove mrlock
+	implementation.
+
+2007-06-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthreadP.h: Define PTHREAD_MUTEX_TYPE.
+	* phtread_mutex_lock.c: Use PTHREAD_MUTEX_TYPE.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise.
+
+2007-06-17  Andreas Schwab  <schwab@suse.de>
+
+	* sysdeps/pthread/pt-initfini.c: Tell gcc about the nonstandard
+	sections.
+
+2007-06-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* allocatestack.c (allocate_stack): Make code compile if
+	__ASSUME_PRIVATE_FUTEX is set.
+
+2007-06-17  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S:
+	(__pthread_rwlock_rdlock): Don't use non SH-3/4 instruction.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S:
+	(__pthread_rwlock_wrlock): Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S:
+	(pthread_rwlock_timedrdlock): Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S:
+	(pthread_rwlock_timedwrlock): Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S:
+	(__pthread_rwlock_unlock): Likewise.
+
+2007-06-10  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/sh/tcb-offsets.sym: Add PRIVATE_FUTEX.
+	* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Include endian.h.
+	Split __flags into __flags, __shared, __pad1 and __pad2.
+	* sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: Use private
+	futexes if they are available.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S: Adjust so that change
+	in libc-lowlevellock.S allow using private futexes.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Define
+	FUTEX_PRIVATE_FLAG.  Add additional parameter to lll_futex_wait,
+	lll_futex_timed_wait and lll_futex_wake.  Change lll_futex_wait
+	to call lll_futex_timed_wait.  Add lll_private_futex_wait,
+	lll_private_futex_timed_wait and lll_private_futex_wake.
+	(lll_robust_mutex_unlock): Fix typo.
+	* sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: Use private
+	field in futex command setup.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Use
+	COND_NWAITERS_SHIFT instead of COND_CLOCK_BITS.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_once.S: Use private futexes
+	if they are available.  Remove clear_once_control.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Use private
+	futexes if they are available.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/sem_post.S: Add private futex support.
+	Wake only when there are waiters.
+	* sysdeps/unix/sysv/linux/sh/sem_wait.S: Add private futex
+	support.  Indicate that there are waiters.  Remove unnecessary
+	extra cancellation test.
+	* sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Likewise.  Removed
+	left-over duplication of __sem_wait_cleanup.
+
+2007-06-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Add additional
+	parameter to lll_futex_wait, lll_futex_timed_wait, and
+	lll_futex_wake.  Change lll_futex_wait to call lll_futex_timed_wait.
+	Add lll_private_futex_wait, lll_private_futex_timed_wait, and
+	lll_private_futex_wake.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise.
+	* allocatestack.c: Adjust use of lll_futex_* macros.
+	* init.c: Likewise.
+	* lowlevellock.h: Likewise.
+	* pthread_barrier_wait.c: Likewise.
+	* pthread_cond_broadcast.c: Likewise.
+	* pthread_cond_destroy.c: Likewise.
+	* pthread_cond_signal.c: Likewise.
+	* pthread_cond_timedwait.c: Likewise.
+	* pthread_cond_wait.c: Likewise.
+	* pthread_create.c: Likewise.
+	* pthread_mutex_lock.c: Likewise.
+	* pthread_mutex_setprioceiling.c: Likewise.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise.
+	* pthread_rwlock_timedrdlock.c: Likewise.
+	* pthread_rwlock_timedwrlock.c: Likewise.
+	* pthread_rwlock_unlock.c: Likewise.
+	* sysdeps/alpha/tls.h: Likewise.
+	* sysdeps/i386/tls.h: Likewise.
+	* sysdeps/ia64/tls.h: Likewise.
+	* sysdeps/powerpc/tls.h: Likewise.
+	* sysdeps/pthread/aio_misc.h: Likewise.
+	* sysdeps/pthread/gai_misc.h: Likewise.
+	* sysdeps/s390/tls.h: Likewise.
+	* sysdeps/sh/tls.h: Likewise.
+	* sysdeps/sparc/tls.h: Likewise.
+	* sysdeps/unix/sysv/linux/fork.c: Likewise.
+	* sysdeps/unix/sysv/linux/lowlevellock.c: Likewise.
+	* sysdeps/unix/sysv/linux/lowlevelrobustlock.c: Likewise.
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h: Likewise.
+	* sysdeps/unix/sysv/linux/sem_post.c: Likewise.
+	* sysdeps/unix/sysv/linux/sem_timedwait.c: Likewise.
+	* sysdeps/unix/sysv/linux/sem_wait.c: Likewise.
+	* sysdeps/unix/sysv/linux/unregister-atfork.c: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/pthread_once.c: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c:
+	Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c: Likewise.
+	* sysdeps/x86_64/tls.h: Likewise.
+
+2007-05-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_getattr_np.c: No need to install a cancellation handler,
+	this is no cancellation point.
+	* pthread_getschedparam.c: Likewise.
+	* pthread_setschedparam.c: Likewise.
+	* pthread_setschedprio.c: Likewise.
+	* sysdeps/unix/sysv/linux/lowlevellock.c: Remove all traces of
+	lll_unlock_wake_cb.
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+
+	* sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Checking
+	whether there are more than one thread makes no sense here since
+	we only call the slow path if the locks are taken.
+	* sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S: Likewise.
+
+	* sysdeps/unix/sysv/linux/internaltypes.h: Introduce
+	COND_NWAITERS_SHIFT.
+	* pthread_cond_destroy.c: Use COND_NWAITERS_SHIFT instead of
+	COND_CLOCK_BITS.
+	* pthread_cond_init.c: Likewise.
+	* pthread_cond_timedwait.c: Likewise.
+	* pthread_cond_wait.c: Likewise.
+	* pthread_condattr_getclock.c: Likewise.
+	* pthread_condattr_setclock.c: Likewise.
+	* sysdeps/unix/sysv/linux/lowlevelcond.sym: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+
+2007-05-28  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c: Include
+	unistd.h.
+
+	* sysdeps/i386/tls.h (THREAD_GSCOPE_RESET_FLAG): Use explicit
+	insn suffix.
+	(THREAD_GSCOPE_GET_FLAG): Remove.
+	* sysdeps/x86_64/tls.h (THREAD_GSCOPE_GET_FLAG): Remove.
+	* allocatestack.c (__wait_lookup_done): Revert 2007-05-24
+	changes.
+	* sysdeps/powerpc/tls.h (tcbhead_t): Remove gscope_flag.
+	(THREAD_GSCOPE_GET_FLAG): Remove.
+	(THREAD_GSCOPE_RESET_FLAG): Use THREAD_SELF->header.gscope_flag
+	instead of THREAD_GSCOPE_GET_FLAG.
+	(THREAD_GSCOPE_SET_FLAG): Likewise.  Add atomic_write_barrier after
+	it.
+	* sysdeps/s390/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
+	THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_WAIT): Define.
+	* sysdeps/sparc/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
+	THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_WAIT): Define.
+	* sysdeps/sh/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
+	THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_WAIT): Define.
+	* sysdeps/ia64/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
+	THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_WAIT): Define.
+
+2007-05-24  Richard Henderson  <rth@redhat.com>
+
+	* descr.h (struct pthread): Add header.gscope_flag.
+	* sysdeps/alpha/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
+	THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_WAIT): Define.
+
+2007-05-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* init.c: Make it compile with older kernel headers.
+
+	* tst-initializers1.c: Show through exit code which test failed.
+
+	* pthread_rwlock_init.c: Also initialize __shared field.
+	* sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Split __flags
+	element in rwlock structure into four byte elements.  One of them is
+	the new __shared element.
+	* sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h [__WORDSIZE=32]:
+	Likewise.
+	[__WORDSIZE=64]: Renamed __pad1 element int rwlock structure to
+	__shared, adjust names of other padding elements.
+	* sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+	* sysdeps/pthread/pthread.h: Adjust rwlock initializers.
+	* sysdeps/unix/sysv/linux/lowlevelrwlock.sym: Add PSHARED.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Define
+	FUTEX_PRIVATE_FLAG.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Change main
+	futex to use private operations if possible.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+
+2007-05-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthreadP.h (PTHREAD_RWLOCK_PREFER_READER_P): Define.
+	* pthread_rwlock_rdlock.c: Use PTHREAD_RWLOCK_PREFER_READER_P.
+	* pthread_rwlock_timedrdlock.c: Likewise.
+	* pthread_rwlock_tryrdlock.c: Likewise.
+
+	* sysdeps/unix/sysv/linux/x86_64/sem_trywait.S (sem_trywait): Tiny
+	optimization.
+
+	* sysdeps/unix/sysv/linux/sem_wait.c: Add missing break.
+	* sysdeps/unix/sysv/linux/sem_timedwait.c: Removed left-over
+	duplication of __sem_wait_cleanup.
+
+	* allocatestack.c: Revert last change.
+	* init.c: Likewise.
+	* sysdeps/i386/tls.h: Likewise.
+	* sysdeps/x86_64/tls.h: Likewise.
+	* descr.h [TLS_DTV_AT_TP] (struct pthread): Add private_futex field to
+	header structure.
+	* sysdeps/powerpc/tcb-offsets.sym: Add PRIVATE_FUTEX_OFFSET.
+
+	* sysdeps/unix/sysv/linux/internaltypes.h (struct pthread_barrier):
+	Add private field.
+	* sysdeps/unix/sysv/linux/lowlevelbarrier.sym: Add PRIVATE definition.
+	* pthread_barrier_init.c: Set private flag if pshared and private
+	futexes are supported.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S: Use
+	private field in futex command setup.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S: Likewise.
+
+2007-05-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Add private futex
+	support.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+
+	* semaphoreP.h: Declare __old_sem_init and __old_sem_wait.
+	* sem_init.c (__new_sem_init): Rewrite to initialize all three
+	fields in the structure.
+	(__old_sem_init): New function.
+	* sem_open.c: Initialize all fields of the structure.
+	* sem_getvalue.c: Adjust for renamed element.
+	* sysdeps/unix/sysv/linux/Makefile [subdir=nptl]
+	(gen-as-const-headers): Add structsem.sym.
+	* sysdeps/unix/sysv/linux/structsem.sym: New file.
+	* sysdeps/unix/sysv/linux/internaltypes.h: Rename struct sem to
+	struct new_sem.  Add struct old_sem.
+	* sysdeps/unix/sysv/linux/sem_post.c: Wake only when there are waiters.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+	* sysdeps/unix/sysv/linux/sem_wait.c: Indicate that there are waiters.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/sem_timedwait.c: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+	* Makefile (tests): Add tst-sem10, tst-sem11, tst-sem12.
+	* tst-sem10.c: New file.
+	* tst-sem11.c: New file.
+	* tst-sem12.c: New file.
+	* tst-typesizes.c: Test struct new_sem and struct old_sem instead
+	of struct sem.
+
+2007-05-25  Ulrich Drepper  <drepper@redhat.com>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (sem_timedwait):
+	Move __pthread_enable_asynccancel right before futex syscall.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait):
+	Likewise.
+
+2007-05-24  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/i386/tls.h (THREAD_SET_PRIVATE_FUTEX,
+	THREAD_COPY_PRIVATE_FUTEX): Define.
+	* sysdeps/x86_64/tls.h (THREAD_SET_PRIVATE_FUTEX,
+	THREAD_COPY_PRIVATE_FUTEX): Define.
+	* allocatestack.c (allocate_stack): Use THREAD_COPY_PRIVATE_FUTEX.
+	* init.c (__pthread_initialize_minimal_internal): Use
+	THREAD_SET_PRIVATE_FUTEX.
+
+	* sysdeps/powerpc/tls.h (tcbhead_t): Add gscope_flag.
+	(THREAD_GSCOPE_FLAG_UNUSED, THREAD_GSCOPE_FLAG_USED,
+	THREAD_GSCOPE_FLAG_WAIT): Define.
+	(THREAD_GSCOPE_GET_FLAG, THREAD_GSCOPE_SET_FLAG,
+	THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_WAIT): Define.
+	* sysdeps/i386/tls.h (THREAD_GSCOPE_WAIT): Don't use
+	PTR_DEMANGLE.
+	(THREAD_GSCOPE_GET_FLAG): Define.
+	* sysdeps/x86_64/tls.h (THREAD_GSCOPE_GET_FLAG): Define.
+	* allocatestack.c (__wait_lookup_done): Use THREAD_GSCOPE_GET_FLAG
+	instead of ->header.gscope_flag directly.
+
+2007-05-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* init.c (__pthread_initialize_minimal_internal): Check whether
+	private futexes are available.
+	* allocatestack.c (allocate_stack): Copy private_futex field from
+	current thread into the new stack.
+	* sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S: Use private
+	futexes if they are available.
+	* sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Likewise
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Adjust so that change
+	in libc-lowlevellock.S allow using private futexes.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Define
+	FUTEX_PRIVATE_FLAG.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Use private futexes
+	if they are available.
+	* sysdeps/unix/sysv/linux/i386/pthread_once.S: Likewise.
+	* sysdeps/x86_64/tcb-offsets.sym: Add PRIVATE_FUTEX.
+	* sysdeps/i386/tcb-offsets.sym: Likewise.
+	* sysdeps/x86_64/tls.h (tcbhead_t): Add private_futex field.
+	* sysdeps/i386/tls.h (tcbhead_t): Likewise.
+
+2007-05-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread-functions.h (struct pthread_functions):
+	Remove ptr_wait_lookup_done again.
+	* init.c (pthread_functions): Don't add .ptr_wait_lookup_done here.
+	(__pthread_initialize_minimal_internal): Initialize
+	_dl_wait_lookup_done pointer in _rtld_global directly.
+	* sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init):
+	Remove code to code _dl_wait_lookup_done.
+	* sysdeps/x86_64/tls.h (THREAD_GSCOPE_WAIT): The pointer is not
+	encrypted for now.
+
+2007-05-21  Jakub Jelinek  <jakub@redhat.com>
+
+	* tst-robust9.c (do_test): Don't fail if ENABLE_PI and
+	pthread_mutex_init failed with ENOTSUP.
+
+2007-05-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* allocatestack.c (__wait_lookup_done): New function.
+	* sysdeps/pthread/pthread-functions.h (struct pthread_functions):
+	Add ptr_wait_lookup_done.
+	* init.c (pthread_functions): Initialize .ptr_wait_lookup_done.
+	* pthreadP.h: Declare __wait_lookup_done.
+	* sysdeps/i386/tls.h (tcbhead_t): Add gscope_flag.
+	Define macros to implement reference handling of global scope.
+	* sysdeps/x86_64/tls.h: Likewise.
+	* sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init):
+	Initialize GL(dl_wait_lookup_done).
+
+2007-05-17  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #4512]
+	* pthread_mutex_lock.c: Preserve FUTEX_WAITERS bit when dead owner
+	is detected.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	Patch in part by Atsushi Nemoto <anemo@mba.ocn.ne.jp>.
+
+	* Makefile (tests): Add tst-robust9 and tst-robustpi9.
+	* tst-robust9.c: New file.
+	* tst-robustpi9.c: New file.
+
+	* sysdeps/unix/sysv/linux/sem_wait.c (__new_sem_wait): Remove
+	unnecessary extra cancellation test.
+
+2007-05-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Remove unnecessary
+	extra cancellation test.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+
+2007-05-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* descr.h (struct pthread): Rearrange members to fill hole in
+	64-bit layout.
+
+	* sysdeps/unix/sysv/linux/pthread_setaffinity.c
+	(__pthread_setaffinity_new): If syscall was successful and
+	RESET_VGETCPU_CACHE is defined, use it before returning.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c: New file.
+
+2007-05-10  Jakub Jelinek  <jakub@redhat.com>
+
+	[BZ #4455]
+	* tst-align2.c: Include stackinfo.h.
+	* tst-getpid1.c: Likewise.
+
+2007-05-02  Carlos O'Donell  <carlos@systemhalted.org>
+
+	[BZ #4455]
+	* tst-align2.c (do_test): Add _STACK_GROWS_UP case.
+	* tst-getpid1.c (do_test): Likewise.
+
+	[BZ #4456]
+	* allocatestack.c (change_stack_perm): Add _STACK_GROWS_UP case.
+	(allocate_stack): Likewise.
+
+2007-05-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+	(__lll_robust_lock_wait): Fix race caused by reloading of futex value.
+	(__lll_robust_timedlock_wait): Likewise.
+	Reported by Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>.
+
+2007-05-06  Mike Frysinger  <vapier@gentoo.org>
+
+	[BZ #4465]
+	* tst-cancel-wrappers.sh: Set C["fdatasync"] to 1.
+	* tst-cancel4.c (tf_fdatasync): New test.
+
+2007-04-27  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #4392]
+	* pthread_mutex_trylock.c (__pthread_mutex_trylock): Treat error
+	check mutexes like normal mutexes.
+
+	[BZ #4306]
+	* sysdeps/unix/sysv/linux/timer_create.c (timer_create):
+	Initialize the whole sigevent structure to appease valgrind.
+
+2007-04-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/x86_64/tls.h (tcbhead_t): Add vgetcpu_cache.
+	* sysdeps/x86_64/tcb-offsets.sym: Add VGETCPU_CACHE_OFFSET.
+
+2007-04-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-locale1.c: Avoid warnings.
+	* tst-locale2.c: Likewise.
+
+2007-03-19  Steven Munroe  <sjmunroe@us.ibm.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+	(__lll_robust_trylock):	Add MUTEX_HINT_ACQ to lwarx instruction.
+
+2007-03-16  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/pthread/bits/libc-lock.h: Use __extern_inline and
+	__extern_always_inline where appropriate.
+	* sysdeps/pthread/pthread.h: Likewise.
+
+2007-03-13  Richard Henderson  <rth@redhat.com>
+
+	* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (PSEUDO): Use two
+	separate cfi regions for the two subsections.
+
+2007-02-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/fork.c (__libc_fork): Reset refcntr in
+	new thread, don't just decrement it.
+	Patch by Suzuki K P <suzuki@in.ibm.com>.
+
+2007-02-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread-functions.h: Correct last patch, correct
+	PTHFCT_CALL definition.
+
+2007-02-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread-functions.h: If PTR_DEMANGLE is not
+	available, don't use it.
+
+2007-02-09  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+	(__lll_mutex_timedlock_wait): Use correct pointer when we don't
+	call into the kernel to delay.
+
+2007-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-initializers1.c: We want to test the initializers as seen
+	outside of libc, so undefined _LIBC.
+
+	* pthread_join.c (cleanup): Avoid warning.
+
+2007-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+	(__lll_timedwait_tid): Add unwind info.
+
+	* sysdeps/unix/sysv/linux/libc_pthread_init.c: Don't just copy the
+	function table, mangle the pointers.
+	* sysdeps/pthread/pthread-functions.h: Define PTHFCT_CALL.
+	* forward.c: Use PTHFCT_CALL and __libc_pthread_functions_init.
+	* sysdeps/pthread/bits/libc-lock.h: When using __libc_pthread_functions
+	demangle pointers before use.
+	* sysdeps/unix/sysv/linux/s390/jmp-unwind.c: Use PTHFCT_CALL to
+	demangle pointer.
+	* sysdeps/unix/sysv/linux/jmp-unwind.c: Likewise.
+	* sysdeps/pthread/setxid.h: Likewise.
+
+2007-01-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-rwlock7.c: Show some more information in case of correct
+	behavior.
+
+2007-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+	(lll_futex_timed_wait): Undo part of last change, don't negate
+	return value.
+
+2007-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Cleanups.  Define
+	FUTEX_CMP_REQUEUE and lll_futex_requeue.
+
+2006-12-28  David S. Miller  <davem@davemloft.net>
+
+	* shlib-versions: Fix sparc64 linux target specification.
+
+2007-01-10  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c:
+	Adjust include path for pthread_barrier_wait.c move.
+
+2006-12-21  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/pthread_kill.c (pthread_kill): Make sure
+	tid isn't reread from pd->tid in between ESRCH test and the syscall.
+
+2006-12-06  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h (PSEUDO): Handle
+	6 argument cancellable syscalls.
+	(STM_6, LM_6, LR7_0, LR7_1, LR7_2, LR7_3, LR7_4, LR7_5, LR7_6): Define.
+	* sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (PSEUDO): Handle
+	6 argument cancellable syscalls.
+	(STM_6, LM_6, LR7_0, LR7_1, LR7_2, LR7_3, LR7_4, LR7_5, LR7_6): Define.
+
+2006-12-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h
+	(__rtld_mrlock_initialize): Add missing closing parenthesis.
+
+2006-10-30  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/ia64/pthread_spin_unlock.c (pthread_spin_unlock): Use
+	__sync_lock_release instead of __sync_lock_release_si.
+
+2006-10-29  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (RTLD_SINGLE_THREAD_P):
+	Define.
+	(SINGLE_THREAD_P): Define to 1 if IS_IN_rtld.
+	* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Likewise.
+
+2006-10-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread_barrier_wait.c: Move to...
+	* pthread_barrier_wait.c: ...here.
+	* sysdeps/pthread/pthread_cond_broadcast.c: Move to...
+	* pthread_cond_broadcast.c: ...here.
+	* sysdeps/pthread/pthread_cond_signal.c: Move to...
+	* pthread_cond_signal.c: ...here.
+	* sysdeps/pthread/pthread_cond_timedwait.c: Move to...
+	* pthread_cond_timedwait.c: ...here.
+	* sysdeps/pthread/pthread_cond_wait.c: Move to...
+	* pthread_cond_wait.c: ...here.
+	* sysdeps/pthread/pthread_once.c: Move to...
+	* pthread_once.c: ...here.
+	* sysdeps/pthread/pthread_rwlock_rdlock.c: Move to...
+	* pthread_rwlock_rdlock.c: ...here.
+	* sysdeps/pthread/pthread_rwlock_timedrdlock.c: Move to...
+	* pthread_rwlock_timedrdlock.c: ...here.
+	* sysdeps/pthread/pthread_rwlock_timedwrlock.c: Move to...
+	* pthread_rwlock_timedwrlock.c: ...here.
+	* sysdeps/pthread/pthread_rwlock_unlock.c: Move to...
+	* pthread_rwlock_unlock.c: ...here.
+	* sysdeps/pthread/pthread_rwlock_wrlock.c: Move to...
+	* pthread_rwlock_wrlock.c: ...here.
+	* sysdeps/pthread/pthread_spin_destroy.c: Move to...
+	* pthread_spin_destroy.c: ...here.
+	* sysdeps/pthread/pthread_spin_init.c: Move to...
+	* pthread_spin_init.c: ...here.
+	* sysdeps/pthread/pthread_spin_unlock.c: Move to...
+	* pthread_spin_unlock.c: ...here.
+	* sysdeps/pthread/pthread_getcpuclockid.c: Move to...
+	* pthread_getcpuclockid.c: ...here.
+
+	* init.c: USE_TLS support is now always enabled.
+	* tst-tls5.h: Likewise.
+	* sysdeps/alpha/tls.h: Likewise.
+	* sysdeps/i386/tls.h: Likewise.
+	* sysdeps/ia64/tls.h: Likewise.
+	* sysdeps/powerpc/tls.h: Likewise.
+	* sysdeps/s390/tls.h: Likewise.
+	* sysdeps/sh/tls.h: Likewise.
+	* sysdeps/sparc/tls.h: Likewise.
+	* sysdeps/x86_64/tls.h: Likewise.
+
+2006-10-27  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h (__rtld_mrlock_lock,
+	__rtld_mrlock_change): Update oldval if atomic compare and exchange
+	failed.
+
+	* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (SINGLE_THREAD_P):
+	Define to THREAD_SELF->header.multiple_threads.
+	* sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (SINGLE_THREAD_P):
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (SINGLE_THREAD_P):
+	Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (SINGLE_THREAD_P):
+	Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
+	(SINGLE_THREAD_P): Likewise.
+	* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (SINGLE_THREAD_P):
+	Likewise.
+
+2006-10-26  Jakub Jelinek  <jakub@redhat.com>
+
+	* pthread_attr_setstacksize.c (NEW_VERNUM): Define to GLIBC_2_3_3
+	by default rather than 2_3_3.
+
+2006-10-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h (__rtld_mrlock_lock,
+	__rtld_mrlock_unlock, __rtld_mrlock_change, __rtld_mrlock_done): Use
+	atomic_* instead of catomic_* macros.
+
+2006-10-12  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #3285]
+	* sysdeps/unix/sysv/linux/bits/local_lim.h: Add SEM_VALUE_MAX.
+	* sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/bits/local_lim.h: Likewise.
+	* sysdeps/unix/sysv/linux/alpha/bits/local_lim.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/bits/local_lim.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/bits/semaphore.h: Remove SEM_VALUE_MAX.
+	* sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/bits/semaphore.h: Likewise.
+	* sysdeps/unix/sysv/linux/alpha/bits/semaphore.h: Likewise.
+	* sysdeps/unix/sysv/linux/sh/bits/semaphore.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/bits/semaphore.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/bits/semaphore.h: Likewise.
+
+2006-10-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Add support for
+	cancelable syscalls with six parameters.
+
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h: Use catomic_*
+	operations instead of atomic_*.
+
+2006-10-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/rtld-lowlevel.h: New file..
+
+2006-10-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h: New file.
+	* sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstack.c: New file.
+	* sysdeps/unix/sysv/linux/powerpc/pthread_attr_setstacksize.c:
+	New file.
+	* pthread_attr_setstack.c: Allow overwriting the version number of the
+	new symbol.
+	* pthread_attr_setstacksize.c: Likewise.
+	(__old_pthread_attr_setstacksize): If STACKSIZE_ADJUST is defined use
+	it.
+	* sysdeps/unix/sysv/linux/powerpc/Versions (libpthread): Add
+	pthread_attr_setstack and pthread_attr_setstacksize to GLIBC_2.6.
+
+2006-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #3251]
+	* descr.h (ENQUEUE_MUTEX_BOTH): Add cast to avoid warning.
+	Patch by Petr Baudis.
+
+2006-09-18  Jakub Jelinek  <jakub@redhat.com>
+
+	* tst-kill4.c (do_test): Explicitly set tf thread's stack size.
+
+	* tst-cancel2.c (tf): Loop as long as something was written.
+
+2006-09-12  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: For PI
+	mutexes wake all mutexes.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Don't increment
+	WAKEUP_SEQ if this would increase the value beyond TOTAL_SEQ.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+
+2006-09-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-cond22.c (tf): Slight changes to the pthread_cond_wait use
+	to guarantee the thread is always canceled.
+
+2006-09-08  Jakub Jelinek  <jakub@redhat.com>
+
+	* tst-cond22.c: Include pthread.h instead of pthreadP.h.
+	Include stdlib.h.
+	* sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Only
+	increase FUTEX if increasing WAKEUP_SEQ.  Fix comment typo.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+
+2006-09-08  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #3123]
+	* sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Don't
+	increment WAKEUP_SEQ if this would increase the value beyond TOTAL_SEQ.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+	* Makefile (tests): Add tst-cond22.
+	* tst-cond22.c: New file.
+
+2006-09-05  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #3124]
+	* descr.h (struct pthread): Add parent_cancelhandling.
+	* sysdeps/pthread/createthread.c (create_thread): Pass parent
+	cancelhandling value to child.
+	* pthread_create.c (start_thread): If parent thread was canceled
+	reset the SIGCANCEL mask.
+	* Makefile (tests): Add tst-cancel25.
+	* tst-cancel25.c: New file.
+
+2006-09-05  Jakub Jelinek  <jakub@redhat.com>
+	    Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/gai_misc.h (GAI_MISC_NOTIFY): Don't decrement
+	counterp if it is already zero.
+	* sysdeps/pthread/aio_misc.h (AIO_MISC_NOTIFY): Likewise..
+
+2006-03-04  Jakub Jelinek  <jakub@redhat.com>
+	    Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h
+	(LLL_STUB_UNWIND_INFO_START, LLL_STUB_UNWIND_INFO_END,
+	LLL_STUB_UNWIND_INFO_3, LLL_STUB_UNWIND_INFO_4): Define.
+	(lll_mutex_lock, lll_robust_mutex_lock, lll_mutex_cond_lock,
+	lll_robust_mutex_cond_lock, lll_mutex_timedlock,
+	lll_robust_mutex_timedlock, lll_mutex_unlock,
+	lll_robust_mutex_unlock, lll_lock, lll_unlock): Use them.
+	Add _L_*_ symbols around the subsection.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Add unwind info.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S: Likewise.
+
+2006-03-03  Jakub Jelinek  <jakub@redhat.com>
+	    Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+	(LLL_STUB_UNWIND_INFO_START, LLL_STUB_UNWIND_INFO_END,
+	LLL_STUB_UNWIND_INFO_5, LLL_STUB_UNWIND_INFO_6): Define.
+	(lll_mutex_lock, lll_robust_mutex_lock, lll_mutex_cond_lock,
+	lll_robust_mutex_cond_lock, lll_mutex_timedlock,
+	lll_robust_mutex_timedlock, lll_mutex_unlock,
+	lll_robust_mutex_unlock, lll_lock, lll_unlock): Use them.
+	Add _L_*_ symbols around the subsection.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Add unwind info.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S: Likewise.
+
+2006-08-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_rwlock_trywrlock.c (__pthread_rwlock_trywrlock): Undo last
+	change because it can disturb too much existing code.  If real hard
+	reader preference is needed we'll introduce another type.
+	* sysdeps/pthread/pthread_rwlock_timedwrlock.c
+	(pthread_rwlock_timedwrlock): Likewise.
+	* sysdeps/pthread/pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock):
+	Likewise.
+
+2006-08-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_rwlock_trywrlock.c (__pthread_rwlock_trywrlock): Respect
+	reader preference.
+	* sysdeps/pthread/pthread_rwlock_timedwrlock.c
+	(pthread_rwlock_timedwrlock): Likewise.
+	* sysdeps/pthread/pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock):
+	Likewise.
+
+2006-08-25  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/libc_pthread_init.c (freeres_libpthread):
+	Only define ifdef SHARED.
+
+2006-08-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* allocatestack.c (queue_stack): Move freeing of surplus stacks to...
+	(free_stacks): ...here.
+	(__free_stack_cache): New function.
+	* pthreadP.h: Declare __free_stack_cache.
+	* sysdeps/pthread/pthread-functions.h (pthread_functions): Add
+	ptr_freeres.
+	* init.c (pthread_functions): Initialize ptr_freeres.
+	* sysdeps/unix/sysv/linux/libc_pthread_init.c (freeres_libptread):
+	New freeres function.
+
+2006-07-30  Joseph S. Myers  <joseph@codesourcery.com>
+
+	[BZ #3018]
+	* Makefile (extra-objs): Add modules to extra-test-objs instead.
+
+2006-08-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/bits/posix_opt.h: Define
+	_XOPEN_REALTIME_THREADS.
+
+2006-08-15  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/clock_settime.c (INTERNAL_VSYSCALL): Use
+	HAVE_CLOCK_GETRES_VSYSCALL as guard macro rather than
+	HAVE_CLOCK_GETTIME_VSYSCALL.
+	(maybe_syscall_settime_cpu): Use plain INTERNAL_VSYSCALL here.
+
+2006-08-14  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/bits/posix_opt.h
+	(_POSIX_THREAD_PRIO_PROTECT): Define to 200112L.
+	* descr.h (struct priority_protection_data): New type.
+	(struct pthread): Add tpp field.
+	* pthreadP.h (PTHREAD_MUTEX_PP_NORMAL_NP,
+	PTHREAD_MUTEX_PP_RECURSIVE_NP, PTHREAD_MUTEX_PP_ERRORCHECK_NP,
+	PTHREAD_MUTEX_PP_ADAPTIVE_NP): New enum values.
+	* pthread_mutex_init.c (__pthread_mutex_init): Handle non-robust
+	TPP mutexes.
+	* pthread_mutex_lock.c (__pthread_mutex_lock): Handle TPP mutexes.
+	* pthread_mutex_trylock.c (__pthread_mutex_trylock): Likewise.
+	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise.
+	* pthread_mutex_unlock.c (__pthread_mutex_unlock_usercnt): Likewise.
+	* tpp.c: New file.
+	* pthread_setschedparam.c (__pthread_setschedparam): Handle priority
+	boosted by TPP.
+	* pthread_setschedprio.c (pthread_setschedprio): Likewise.
+	* pthread_mutexattr_getprioceiling.c
+	(pthread_mutexattr_getprioceiling): If ceiling is 0, ensure it is
+	in the SCHED_FIFO priority range.
+	* pthread_mutexattr_setprioceiling.c
+	(pthread_mutexattr_setprioceiling): Fix prioceiling validation.
+	* pthread_mutex_getprioceiling.c (pthread_mutex_getprioceiling): Fail
+	if mutex is not TPP.  Ceiling is now in __data.__lock.
+	* pthread_mutex_setprioceiling.c: Include stdbool.h.
+	(pthread_mutex_setprioceiling): Fix prioceiling validation.  Ceiling
+	is now in __data.__lock.  Add locking.
+	* pthread_create.c (__free_tcb): Free pd->tpp structure.
+	* Makefile (libpthread-routines): Add tpp.
+	(xtests): Add tst-mutexpp1, tst-mutexpp6 and tst-mutexpp10.
+	* tst-tpp.h: New file.
+	* tst-mutexpp1.c: New file.
+	* tst-mutexpp6.c: New file.
+	* tst-mutexpp10.c: New file.
+	* tst-mutex1.c (TEST_FUNCTION): Don't redefine if already defined.
+	* tst-mutex6.c (TEST_FUNCTION): Likewise.
+
+2006-08-12  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #2843]
+	* pthread_join.c (pthread_join): Account for self being canceled
+	when checking for deadlocks.
+	* tst-join5.c: Cleanups.  Allow to be used in tst-join6.
+	(tf1): Don't print anything after pthread_join returns, this would be
+	another cancellation point.
+	(tf2): Likewise.
+	* tst-join6.c: New file.
+	* Makefile (tests): Add tst-join6.
+
+2006-08-03  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #2892]
+	* pthread_setspecific.c (__pthread_setspecific): Check
+	out-of-range index before checking for unused key.
+
+	* sysdeps/pthread/gai_misc.h: New file.
+
+2006-08-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/smp.h: New file.  Old Linux-specific
+	file.  Don't use sysctl.
+	* sysdeps/unix/sysv/linux/smp.h: Always assume SMP.  Archs can
+	overwrite the file if this is likely not true.
+
+2006-07-31  Daniel Jacobowitz  <dan@codesourcery.com>
+
+	* allocatestack.c (__reclaim_stacks): Reset the PID on cached stacks.
+	* Makefile (tests): Add tst-getpid3.
+	* tst-getpid3.c: New file.
+
+2006-07-30  Roland McGrath  <roland@redhat.com>
+
+	* Makefile (libpthread-routines): Add ptw-sigsuspend.
+
+	* sysdeps/unix/sysv/linux/i386/not-cancel.h
+	(pause_not_cancel): New macro.
+	(nanosleep_not_cancel): New macro.
+	(sigsuspend_not_cancel): New macro.
+	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Use
+	nanosleep_not_cancel macro from <not-cancel.h>.
+	* pthread_mutex_lock.c (__pthread_mutex_lock): Use pause_not_cancel
+	macro from <not-cancel.h>.
+
+2006-07-28  Ulrich Drepper  <drepper@redhat.com>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	* descr.h: Change ENQUEUE_MUTEX and DEQUEUE_MUTEX for bit 0
+	notification of PI mutex.  Add ENQUEUE_MUTEX_PI.
+	* pthreadP.h: Define PTHREAD_MUTEX_PI_* macros for PI mutex types.
+	* pthread_mutex_setprioceilining.c: Adjust for mutex type name change.
+	* pthread_mutex_init.c: Add support for priority inheritance mutex.
+	* pthread_mutex_lock.c: Likewise.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise.
+	* sysdeps/pthread/pthread_cond_broadcast.c: For PI mutexes wake
+	all mutexes.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.c: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.c: Likewise.
+	* sysdeps/unix/sysv/linux/pthread-pi-defines.sym: New file.
+	* sysdeps/unix/sysv/linux/Makefile (gen-as-const-header): Add
+	pthread-pi-defines.sym.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Define FUTEX_LOCK_PI,
+	FUTEX_UNLOCK_PI, and FUTEX_TRYLOCK_PI.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/bits/posix_opt.h: Define
+	_POSIX_THREAD_PRIO_INHERIT to 200112L.
+	* tst-mutex1.c: Adjust to allow use in PI mutex test.
+	* tst-mutex2.c: Likewise.
+	* tst-mutex3.c: Likewise.
+	* tst-mutex4.c: Likewise.
+	* tst-mutex5.c: Likewise.
+	* tst-mutex6.c: Likewise.
+	* tst-mutex7.c: Likewise.
+	* tst-mutex7a.c: Likewise.
+	* tst-mutex8.c: Likewise.
+	* tst-mutex9.c: Likewise.
+	* tst-robust1.c: Likewise.
+	* tst-robust7.c: Likewise.
+	* tst-robust8.c: Likewise.
+	* tst-mutexpi1.c: New file.
+	* tst-mutexpi2.c: New file.
+	* tst-mutexpi3.c: New file.
+	* tst-mutexpi4.c: New file.
+	* tst-mutexpi5.c: New file.
+	* tst-mutexpi6.c: New file.
+	* tst-mutexpi7.c: New file.
+	* tst-mutexpi7a.c: New file.
+	* tst-mutexpi8.c: New file.
+	* tst-mutexpi9.c: New file.
+	* tst-robust1.c: New file.
+	* tst-robust2.c: New file.
+	* tst-robust3.c: New file.
+	* tst-robust4.c: New file.
+	* tst-robust5.c: New file.
+	* tst-robust6.c: New file.
+	* tst-robust7.c: New file.
+	* tst-robust8.c: New file.
+	* Makefile (tests): Add the new tests.
+
+	* pthread_create.c (start_thread): Add some casts to avoid warnings.
+	* pthread_mutex_destroy.c: Remove unneeded label.
+
+2006-07-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_mutex_init.c (__pthread_mutex_init): Move some
+	computations to compile time.
+
+2006-06-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread.h: Add pthread_equal inline version.
+
+2006-05-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/fork.h: Mark __fork_handlers as hidden.
+
+2006-05-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_key_create.c (__pthread_key_create): Do away with
+	__pthread_keys_lock.
+
+	* sysdeps/unix/sysv/linux/pthread_setaffinity.c
+	(__kernel_cpumask_size): Mark as hidden.
+	* sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c: Likewise.
+
+	* sem_open.c (__sem_mappings_lock): Mark as hidden.
+	* semaphoreP.h (__sem_mappings_lock): Likewise.
+
+2006-05-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_atfork.c: Mark __dso_handle as hidden.
+
+2006-05-09  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #2644]
+	* sysdeps/pthread/unwind-forcedunwind.c: Different solution for
+	the reload problem.  Change the one path in pthread_cancel_init
+	which causes the problem.  Force gcc to reload.  Simplify callers.
+	* sysdeps/unix/sysv/linux/ia64/unwind-forcedunwind.c
+	(_Unwind_GetBSP): Undo last patch.
+
+2006-05-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/ia64/unwind-forcedunwind.c: Make sure the
+	function pointer is reloaded after pthread_cancel_init calls.
+
+	[BZ #2644]
+	* sysdeps/pthread/unwind-forcedunwind.c: Make sure functions
+	pointers are reloaded after pthread_cancel_init calls.
+
+2006-05-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/allocalim.h (__libc_use_alloca): Mark with
+	__always_inline.
+
+2006-04-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/timer_routines.c (timer_helper_thread):
+	Allocate new object which is passed to timer_sigev_thread so that
+	the timer can be deleted before the new thread is scheduled.
+
+2006-04-26  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/x86_64/tls.h: Include <asm/prctl.h> inside [! __ASSEMBLER__].
+
+2006-04-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Remove branch predicion
+	suffix for conditional jumps.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+
+	* init.c (sigcancel_handler): Compare with correct PID even if the
+	thread is in the middle of a fork call.
+	(sighandler_setxid): Likewise.
+	Reported by Suzuki K P <suzuki@in.ibm.com> .
+
+2006-04-07  Jakub Jelinek  <jakub@redhat.com>
+
+	* pthreadP.h (FUTEX_TID_MASK): Sync with kernel.
+
+2006-04-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_getattr_np.c (pthread_getattr_np): Close fp if getrlimit
+	fails [Coverity CID 105].
+
+2006-04-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread.h: Add nonnull attributes.
+
+2006-04-03  Steven Munroe  <sjmunroe@us.ibm.com>
+
+	[BZ #2505]
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h [_ARCH_PWR4]:
+	Define __lll_rel_instr using lwsync.
+
+2006-03-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* allocatestack.c (allocate_stack): Always initialize robust_head.
+	* descr.h: Define struct robust_list_head.
+	(struct pthread): Use robust_list_head in robust mutex list definition.
+	Adjust ENQUEUE_MUTEX and DEQUEUE_MUTEX.
+	* init.c [!__ASSUME_SET_ROBUST_LIST] (__set_robust_list_avail): Define.
+	(__pthread_initialize_minimal_internal): Register robust_list with
+	the kernel.
+	* pthreadP.h: Remove PRIVATE_ from PTHREAD_MUTEX_ROBUST_* names.
+	Declare __set_robust_list_avail.
+	* pthread_create.c (start_thread): Register robust_list of new thread.
+	[!__ASSUME_SET_ROBUST_LIST]: If robust_list is not empty wake up
+	waiters.
+	* pthread_mutex_destroy.c: For robust mutexes don't look at the
+	number of users, it's unreliable.
+	* pthread_mutex_init.c: Allow use of pshared robust mutexes if
+	set_robust_list syscall is available.
+	* pthread_mutex_consistent.c: Adjust for PTHREAD_MUTEX_ROBUST_* rename.
+	* pthread_mutex_lock.c: Simplify robust mutex code a bit.
+	Set robust_head.list_op_pending before trying to lock a robust mutex.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise for unlocking.
+	* Makefile (tests): Add tst-robust8.
+	* tst-robust8.c: New file.
+
+2006-03-08  Andreas Schwab  <schwab@suse.de>
+
+	* sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
+	(DL_SYSINFO_IMPLEMENTATION): Add missing newline.
+
+2006-03-05  Roland McGrath  <roland@redhat.com>
+
+	* configure (libc_add_on): Disable add-on when $add_ons_automatic = yes
+	and $config_os doesn't match *linux*.
+
+2006-03-05  David S. Miller  <davem@sunset.davemloft.net>
+
+	* sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S:
+	Use __syscall_error.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/Makefile: New file.
+
+2006-03-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/aio_misc.h: Various cleanups.
+
+2006-03-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
+	(__lll_robust_lock_wait): Also set FUTEX_WAITERS bit if we got the
+	mutex.
+	(__lll_robust_timedlock_wait): Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S
+	(__lll_robust_lock_wait): Likewise.
+	(__lll_robust_timedlock_wait): Likewise.
+	* sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+	(__lll_robust_lock_wait): Likewise.
+	(__lll_robust_timedlock_wait): Likewise.
+
+2006-03-01  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h (lll_robust_mutex_dead,
+	lll_robust_mutex_trylock, lll_robust_mutex_lock,
+	lll_robust_mutex_cond_lock, lll_robust_mutex_timedlock,
+	lll_robust_mutex_unlock): Define.
+	(__lll_robust_lock_wait, __lll_robust_timedlock_wait): New prototypes.
+
+2006-02-28  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* sysdeps/unix/sysv/linux/ia64/clone2.S: Include <clone2.S>
+	instead of <clone.S>.
+
+2006-02-27  Jakub Jelinek  <jakub@redhat.com>
+
+	* Makefile (libpthread-routines): Add
+	pthread_mutexattr_[sg]etprotocol, pthread_mutexattr_[sg]etprioceiling
+	and pthread_mutex_[sg]etprioceiling.
+	* Versions (GLIBC_2.4): Export pthread_mutexattr_getprotocol,
+	pthread_mutexattr_setprotocol, pthread_mutexattr_getprioceiling,
+	pthread_mutexattr_setprioceiling, pthread_mutex_getprioceiling and
+	pthread_mutex_setprioceiling.
+	* sysdeps/pthread/pthread.h (PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT,
+	PTHREAD_PRIO_PROTECT): New enum values.
+	(pthread_mutexattr_getprotocol, pthread_mutexattr_setprotocol,
+	pthread_mutexattr_getprioceiling, pthread_mutexattr_setprioceiling,
+	pthread_mutex_getprioceiling, pthread_mutex_setprioceiling): New
+	prototypes.
+	* pthreadP.h (PTHREAD_MUTEX_PRIO_INHERIT_PRIVATE_NP,
+	PTHREAD_MUTEX_PRIO_PROTECT_PRIVATE_NP): New enum values.
+	(PTHREAD_MUTEX_PRIO_CEILING_SHIFT, PTHREAD_MUTEX_PRIO_CEILING_MASK):
+	Define.
+	(PTHREAD_MUTEXATTR_PROTOCOL_SHIFT, PTHREAD_MUTEXATTR_PROTOCOL_MASK,
+	PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT,
+	PTHREAD_MUTEXATTR_PRIO_CEILING_MASK): Define.
+	(PTHREAD_MUTEXATTR_FLAG_BITS): Or in PTHREAD_MUTEXATTR_PROTOCOL_MASK
+	and PTHREAD_MUTEXATTR_PRIO_CEILING_MASK.
+	* pthread_mutex_init.c (__pthread_mutex_init): For the time being
+	return ENOTSUP for PTHREAD_PRIO_INHERIT or PTHREAD_PRIO_PROTECT
+	protocol mutexes.
+	* pthread_mutex_getprioceiling.c: New file.
+	* pthread_mutex_setprioceiling.c: New file.
+	* pthread_mutexattr_getprioceiling.c: New file.
+	* pthread_mutexattr_setprioceiling.c: New file.
+	* pthread_mutexattr_getprotocol.c: New file.
+	* pthread_mutexattr_setprotocol.c: New file.
+
+2006-02-27  Daniel Jacobowitz  <dan@codesourcery.com>
+
+	* sysdeps/unix/sysv/linux/aio_misc.h: Include <limits.h>.
+
+2006-02-27  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/pthread/Subdirs: List nptl here too.
+	* configure (libc_add_on_canonical): New variable.
+
+	* sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h: Use #include_next.
+
+	* sysdeps/unix/sysv/linux/sleep.c: Use #include_next after #include of
+	self to get main source tree's file.
+	* sysdeps/unix/sysv/linux/alpha/clone.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/clone.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/vfork.S: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/clone2.S: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/clone.S: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/clone.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/clone.S: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/clone.S: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/clone.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/clone.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/vfork.S: Likewise.
+
+	* Makefile: Use $(sysdirs) in vpath directive.
+
+	* sysdeps/pthread/Makefile (CFLAGS-libc-start.c): Variable removed.
+	(CPPFLAGS-timer_routines.c): Likewise.
+
+	* Makeconfig (includes): Variable removed.
+
+2006-02-26  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/generic/pt-raise.c: Moved to ...
+	* pt-raise.c: ... here.
+	* sysdeps/generic/lowlevellock.h: Moved to ...
+	* lowlevellock.h: ... here.
+
+2006-02-23  Roland McGrath  <roland@redhat.com>
+
+	* descr.h (struct pthread): Add final member `end_padding'.
+	(PTHREAD_STRUCT_END_PADDING): Use it.
+
+2006-02-20  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/mips: Directory removed, saved in ports repository.
+	* sysdeps/unix/sysv/linux/mips: Likewise.
+
+2006-02-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-robust1.c: Add second mutex to check that the mutex list is
+	handled correctly.
+
+2006-02-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h (lll_robust_mutex_dead,
+	lll_robust_mutex_trylock, lll_robust_mutex_lock,
+	lll_robust_mutex_cond_lock, lll_robust_mutex_timedlock,
+	lll_robust_mutex_unlock): New macros.
+	(__lll_robust_lock_wait, __lll_robust_timedlock_wait): New prototypes.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/lowlevelrobustlock.c: New file.
+
+2006-02-17  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Add lll_robust_mutex_*
+	definitions.
+	* sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S: New file.
+
+2006-02-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+	(lll_robust_mutex_unlock): Avoid unnecessary wakeups.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h
+	(lll_robust_mutex_unlock): Likewise.
+
+2006-02-13  Jakub Jelinek  <jakub@redhat.com>
+
+	* descr.h [!__PTHREAD_MUTEX_HAVE_PREV] (DEQUEUE_MUTEX):
+	Set robust_list.__next rather than robust_list.
+	* sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
+	(__pthread_list_t): New typedef.
+	(pthread_mutex_t): Replace __next and __prev fields with __list.
+	* sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
+	(__pthread_list_t): New typedef.
+	(pthread_mutex_t): Replace __next and __prev fields with __list.
+	* sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
+	(__pthread_list_t, __pthread_slist_t): New typedefs.
+	(pthread_mutex_t): Replace __next and __prev fields with __list.
+	* sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
+	(__pthread_list_t, __pthread_slist_t): New typedefs.
+	(pthread_mutex_t): Replace __next and __prev fields with __list.
+	* sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
+	(__pthread_list_t, __pthread_slist_t): New typedefs.
+	(pthread_mutex_t): Replace __next and __prev fields with __list.
+	* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
+	(__pthread_slist_t): New typedef.
+	(pthread_mutex_t): Replace __next field with __list.
+
+2006-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthreadP.h: Define PTHREAD_MUTEX_INCONSISTENT instead of
+	PTHREAD_MUTEX_OWNERDEAD.
+	(PTHREAD_MUTEX_ROBUST_PRIVATE_NP): Define as 16, not 256.
+	Define FUTEX_WAITERS, FUTEX_OWNER_DIED, FUTEX_TID_MASK.
+	* Makefile (libpthread-routines): Add lowlevelrobustlock.
+	* pthread_create.c (start_thread): Very much simplify robust_list loop.
+	* pthread_mutex_consistent.c: Inconsistent mutex have __owner now set
+	to PTHREAD_MUTEX_INCONSISTENT.
+	* pthread_mutex_destroy.c: Allow destroying of inconsistent mutexes.
+	* pthread_mutex_lock.c: Reimplement robust mutex handling.
+	* pthread_mutex_trylock.c: Likewise.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise.
+	* sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c: Likewise.
+	* sysdeps/unix/sysv/linux/Makefile (gen-as-const-headers): Add
+	lowlevelrobustlock.sym.
+	* sysdeps/unix/sysv/linux/lowlevelrobustlock.sym: New file.
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Add lll_robust_mutex_*
+	definitions.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S: New file.
+	* sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S: New file.
+	* sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S: New file.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S: New file.
+
+2006-02-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* allocatestack.c (allocate_stack): Initialize robust_list.
+	* init.c (__pthread_initialize_minimal_internal): Likewise.
+	* descr.h (struct xid_command): Pretty printing.
+	(struct pthread): Use __pthread_list_t or __pthread_slist_t for
+	robust_list.  Adjust macros.
+	* pthread_create.c (start_thread): Adjust robust_list handling.
+	* phtread_mutex_unlock.c: Don't allow unlocking from any thread
+	but the owner for all robust mutex types.
+	* sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Define
+	__pthread_list_t and __pthread_slist_t.  Use them in pthread_mutex_t.
+	* sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+	* sysdeps/pthread/pthread.h: Adjust mutex initializers.
+
+	* sysdeps/unix/sysv/linux/i386/not-cancel.h: Define openat_not_cancel,
+	openat_not_cancel_3, openat64_not_cancel, and openat64_not_cancel_3.
+
+2006-02-08  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_futex_wait,
+	lll_futex_timedwait, lll_wait_tid): Add "memory" clobber.
+
+2006-01-20  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h (lll_futex_wait):
+	Return status.
+	(lll_futex_timed_wait): Define.
+
+2006-01-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-cancel4.c: Test ppoll.
+
+2006-01-18  Andreas Jaeger  <aj@suse.de>
+
+	[BZ #2167]
+	* sysdeps/unix/sysv/linux/mips/bits/pthreadtypes.h
+	(pthread_mutex_t): Follow changes for other archs.  Based on patch
+	by Jim Gifford <patches@jg555.com>.
+
+2006-01-13  Richard Henderson  <rth@redhat.com>
+
+	* sysdeps/alpha/tls.h (tcbhead_t): Rename member to __private.
+
+2006-01-10  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/alpha/jmpbuf-unwind.h: File moved to main source tree.
+	* sysdeps/i386/jmpbuf-unwind.h: Likewise.
+	* sysdeps/mips/jmpbuf-unwind.h: Likewise.
+	* sysdeps/powerpc/jmpbuf-unwind.h: Likewise.
+	* sysdeps/s390/jmpbuf-unwind.h: Likewise.
+	* sysdeps/sh/jmpbuf-unwind.h: Likewise.
+	* sysdeps/sparc/sparc32/jmpbuf-unwind.h: Likewise.
+	* sysdeps/sparc/sparc64/jmpbuf-unwind.h: Likewise.
+	* sysdeps/x86_64/jmpbuf-unwind.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h: Likewise.
+
+2006-01-09  Roland McGrath  <roland@redhat.com>
+
+	* tst-initializers1-c89.c: New file.
+	* tst-initializers1-c99.c: New file.
+	* tst-initializers1-gnu89.c: New file.
+	* tst-initializers1-gnu99.c: New file.
+	* Makefile (tests): Add them.
+	(CFLAGS-tst-initializers1-c89.c): New variable.
+	(CFLAGS-tst-initializers1-c99.c): New variable.
+	(CFLAGS-tst-initializers1-gnu89.c): New variable.
+	(CFLAGS-tst-initializers1-gnu99.c): New variable.
+
+	* sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_mutex_t):
+	Use __extension__ on anonymous union definition.
+	* sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise.
+
+2006-01-08  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h (pthread_mutex_t):
+	Don't give the union a name because it changes the mangled name.
+	Instead name the struct for __data.
+	* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h (pthread_mutex_t):
+	Likewise.
+	* sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h (pthread_mutex_t):
+	Likewise.
+
+2006-01-09  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/sparc/sparc64/jmpbuf-unwind.h (_JMPBUF_UNWINDS_ADJ): Add
+	stack bias to mc_ftp field.
+
+2006-01-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/aio_misc.h (AIO_MISC_WAIT): Work around gcc
+	being too clever and reloading the futex value where it shouldn't.
+
+2006-01-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* descr.h [!__PTHREAD_MUTEX_HAVE_PREV] (DEQUEUE_MUTEX): Use
+	correct type.
+
+2006-01-06  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h (PSEUDO):
+	Add cfi directives.
+
+2006-01-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/ia64/tls.h (tcbhead_t): Rename private member to __private.
+	* sysdeps/ia64/tcb-offsets.sym: Adjust for private->__private
+	rename in tcbhead_t.
+
+	* sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_mutex_t):
+	Don't give the union a name because it changes the mangled name.
+	Instead name the struct for __data.
+	* sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise.
+	* pthread_create.c (start_thread): Adjust robust mutex free loop.
+	* descr.h (ENQUEUE_MUTEX, DEQUEUE_MUTEX): Adjust.
+
+2006-01-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_futex_wait):
+	Return status.
+	(lll_futex_timed_wait): Define.
+	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+	* sysdeps/pthread/aio_misc.h: New file.
+
+2006-01-03  Joseph S. Myers  <joseph@codesourcery.com>
+
+	* Makefile ($(objpfx)$(multidir)): Use mkdir -p.
+
+2006-01-03  Steven Munroe  <sjmunroe@us.ibm.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
+	(PSEUDO): Remove redundant cfi_startproc and cfi_endproc directives.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise.
+
+2006-01-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* tst-cancel24.cc: Use C headers instead of C++ headers.
+
+2006-01-03  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Remove #error for
+	sparc-linux configured glibc.
+	(lll_futex_wake_unlock): Define to 1 for sparc-linux configured glibc.
+	(__lll_mutex_trylock, __lll_mutex_cond_trylock, __lll_mutex_lock,
+	__lll_mutex_cond_lock, __lll_mutex_timedlock): Use
+	atomic_compare_and_exchange_val_24_acq instead of
+	atomic_compare_and_exchange_val_acq.
+	(lll_mutex_unlock, lll_mutex_unlock_force): Use atomic_exchange_24_rel
+	instead of atomic_exchange_rel.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_init.c: New
+	file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c: New
+	file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_init.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_init.c:
+	New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c:
+	New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_init.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c: New file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c: New
+	file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_trywait.c: New
+	file.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c: New file.
+
+2006-01-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/pthread.h [__WORDSIZE==64]: Don't use cast in
+	mutex initializers.
+
+2006-01-02  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/sparc/tls.h (tcbhead_t): Add pointer_guard field.
+	(THREAD_GET_POINTER_GUARD, THREAD_SET_POINTER_GUARD,
+	THREAD_COPY_POINTER_GUARD): Define.
+	* sysdeps/sparc/tcb-offsets.sym (POINTER_GUARD): Define.
+	* sysdeps/sparc/sparc64/jmpbuf-unwind.h: Revert 2005-12-27 changes.
+
+2006-01-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* version.c: Update copyright year.
+
+2005-12-29  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Remove explicit
+	.eh_frame section, use cfi_* directives.
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S: Add cfi instrumentation.
+
+2005-12-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h: Undo last change for
+	now.
+
+2005-12-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/sigaction.c: Removed.
+	* sigaction.c: New file.
+	* sysdeps/unix/sysv/linux/Makefile: Define CFLAGS-sigaction.c.
+
+2005-12-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile (tests): Add tst-signal7.
+	* tst-signal7.c: New file.
+
+2005-12-27  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/x86_64/jmpbuf-unwind.h (_jmpbuf_sp): New inline function.
+	(_JMPBUF_UNWINDS_ADJ): Use it, to PTR_DEMANGLE before comparison.
+	* sysdeps/alpha/jmpbuf-unwind.h: Likewise.
+	* sysdeps/i386/jmpbuf-unwind.h: Likewise.
+	* sysdeps/mips/jmpbuf-unwind.h: Likewise.
+	* sysdeps/powerpc/jmpbuf-unwind.h: Likewise.
+	* sysdeps/s390/jmpbuf-unwind.h: Likewise.
+	* sysdeps/sh/jmpbuf-unwind.h: Likewise.
+	* sysdeps/sparc/sparc32/jmpbuf-unwind.h: Likewise.
+	* sysdeps/sparc/sparc64/jmpbuf-unwind.h: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/jmpbuf-unwind.h: Likewise.
+
+2005-12-27  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h: Add __next
+	and __prev field to pthread_mutex_t.
+	* sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise.
+	* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Add __next field
+	to pthread_mutex_t.
+
+2005-12-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthreadP.h: Define PTHREAD_MUTEX_ROBUST_PRIVATE_NP,
+	PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP,
+	PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP,
+	PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP,
+	PTHREAD_MUTEXATTR_FLAG_ROBUST, PTHREAD_MUTEXATTR_FLAG_PSHARED,
+	and PTHREAD_MUTEXATTR_FLAG_BITS.
+	* descr.h (struct pthread): Add robust_list field and define
+	ENQUEUE_MUTEX and DEQUEUE_MUTEX macros.
+	* pthread_mutexattr_getrobust.c: New file.
+	* pthread_mutexattr_setrobust.c: New file.
+	* pthread_mutex_consistent.c: New file.
+	* sysdeps/pthread/pthread.h: Declare pthread_mutexattr_getrobust,
+	pthread_mutexattr_setrobust, and pthread_mutex_consistent.
+	Define PTHREAD_MUTEX_STALLED_NP and PTHREAD_MUTEX_ROBUST_NP.
+	Adjust pthread_mutex_t initializers.
+	* nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Add __next
+	field to pthread_mutex_t.
+	* nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Add __next
+	and __prev field to pthread_mutex_t.
+	* Versions [GLIBC_2.4]: Export pthread_mutexattr_getrobust_np,
+	pthread_mutexattr_setrobust_np, and pthread_mutex_consistent_np.
+	* pthread_mutexattr_getpshared.c: Use PTHREAD_MUTEXATTR_FLAG_PSHARED
+	and PTHREAD_MUTEXATTR_FLAG_BITS macros instead of magic numbers.
+	* pthread_mutexattr_gettype.c: Likewise.
+	* pthread_mutexattr_setpshared.c: Likewise.
+	* pthread_mutexattr_settype.c: Likewise.
+	* pthread_mutex_init.c: Reject robust+pshared attribute for now.
+	Initialize mutex kind according to robust flag.
+	* pthread_mutex_lock.c: Implement local robust mutex.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise.
+	* pthread_create.c (start_thread): Mark robust mutexes which remained
+	locked as dead.
+	* tst-robust1.c: New file.
+	* tst-robust2.c: New file.
+	* tst-robust3.c: New file.
+	* tst-robust4.c: New file.
+	* tst-robust5.c: New file.
+	* tst-robust6.c: New file.
+	* tst-robust7.c: New file.
+	* Makefile (libpthread-routines): Add pthread_mutexattr_getrobust,
+	pthread_mutexattr_setrobust, and pthread_mutex_consistent.
+	(tests): Add tst-robust1, tst-robust2, tst-robust3, tst-robust4,
+	tst-robust5, tst-robust6, and tst-robust7.
+
+	* tst-typesizes.c: New file.
+	* Makefile (tests): Add tst-typesizes.
+
+	* tst-once3.c: More debug output.
+
+2005-12-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_mutex_trylock.c (__pthread_mutex_trylock): Add break
+	missing after last change.
+
+	* version.c: Update copyright year.
+
+2005-12-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_mutex_destroy.c: Set mutex type to an invalid value.
+	* pthread_mutex_lock.c: Return EINVAL for invalid mutex type.
+	* pthread_mutex_trylock.c: Likewise.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise.
+
+2005-12-22  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/pthread/sigaction.c: Use "" instead of <> to include self,
+	so that #include_next's search location is not reset to the -I..
+	directory where <nptl/...> can be found.
+
+2005-12-22  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #1913]
+	* sysdeps/unix/sysv/linux/i386/i486/sem_wait.S (__new_sem_wait):
+	Fix unwind info.  Remove useless branch prediction prefix.
+	* tst-cancel24.cc: New file.
+	* Makefile: Add rules to build and run tst-cancel24.
+
+2005-12-21  Roland McGrath  <roland@redhat.com>
+
+	* libc-cancellation.c: Use <> rather than "" #includes.
+	* pt-cleanup.c: Likewise.
+	* pthread_create.c: Likewise.
+	* pthread_join.c: Likewise.
+	* pthread_timedjoin.c: Likewise.
+	* pthread_tryjoin.c: Likewise.
+	* sysdeps/unix/sysv/linux/libc_pthread_init.c: Likewise.
+	* sysdeps/unix/sysv/linux/register-atfork.c: Likewise.
+	* sysdeps/unix/sysv/linux/unregister-atfork.c: Likewise.
+	* unwind.c: Likewise.
+
+2005-12-19  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/sh/tcb-offsets.sym: Add POINTER_GUARD.
+	* sysdeps/sh/tls.h (tcbhead_t): Remove private and add pointer_guard.
+	(THREAD_GET_POINTER_GUARD, THREAD_SET_POINTER_GUARD,
+	THREAD_COPY_POINTER_GUARD): Define.
+
+2005-12-19  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/ia64/tls.h (TLS_PRE_TCB_SIZE): Make room for 2 uintptr_t's
+	rather than one.
+	(THREAD_GET_POINTER_GUARD, THREAD_SET_POINTER_GUARD,
+	THREAD_COPY_POINTER_GUARD): Define.
+	* sysdeps/powerpc/tcb-offsets.sym (POINTER_GUARD): Add.
+	* sysdeps/powerpc/tls.h (tcbhead_t): Add pointer_guard field.
+	(THREAD_GET_POINTER_GUARD, THREAD_SET_POINTER_GUARD,
+	THREAD_COPY_POINTER_GUARD): Define.
+	* sysdeps/s390/tcb-offsets.sym (STACK_GUARD): Add.
+	* sysdeps/s390/tls.h (THREAD_GET_POINTER_GUARD,
+	THREAD_SET_POINTER_GUARD, THREAD_COPY_POINTER_GUARD): Define.
+	* sysdeps/unix/sysv/linux/ia64/__ia64_longjmp.S (__ia64_longjmp):
+	Use PTR_DEMANGLE for B0 if defined.
+
+2005-12-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* pthread_create.c (__pthread_create_2_1): Use
+	THREAD_COPY_POINTER_GUARD if available.
+	* sysdeps/i386/tcb-offsets.sym: Add POINTER_GUARD.
+	* sysdeps/x86_64/tcb-offsets.sym: Likewise.
+	* sysdeps/i386/tls.h (tcbhead_t): Add pointer_guard.
+	Define THREAD_SET_POINTER_GUARD and THREAD_COPY_POINTER_GUARD.
+	* sysdeps/x86_64/tls.h: Likewise.
+
+2005-12-15  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/unix/sysv/linux/mq_notify.c: Don't use sysdeps/generic.
+
+2005-12-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/pthread/sigfillset.c: Adjust for files moved out of
+	sysdeps/generic.
+	* errno-loc.c: New file.
+
+2005-12-12  Roland McGrath  <roland@redhat.com>
+
+	* init.c (__pthread_initialize_minimal_internal): Do __static_tls_size
+	adjustments before choosing stack size.  Update minimum stack size
+	calculation to match allocate_stack change.
+
+2005-12-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* allocatestack.c (allocate_stack): Don't demand that there is an
+	additional full page available on the stack beside guard, TLS, the
+	minimum stack.
+
+2005-11-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
+	(__cleanup_fct_attribute): Use __regparm__ not regparm.
+
+	* sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: When
+	compiling 32-bit code we must define __cleanup_fct_attribute.
+
+005-11-24  Jakub Jelinek  <jakub@redhat.com>
+
+	[BZ #1920]
+	* sysdeps/pthread/pthread.h (__pthread_unwind_next): Use
+	__attribute__ instead of __attribute.
+	* sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
+	(__cleanup_fct_attribute): Likewise.
+
+2005-11-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/pthread/unwind-forcedunwind.c (pthread_cancel_init): Put
+	a write barrier before writing libgcc_s_getcfa.
+
+2005-11-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/configure: Removed.
+
+2005-11-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/ia64/pt-initfini.c: Remove trace of
+	optional init_array/fini_array support.
+
+2005-10-24  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/sem_trywait.S: Remove unnecessary
+	versioned_symbol use.
+
+2005-10-16  Roland McGrath  <roland@redhat.com>
+
+	* init.c (__pthread_initialize_minimal_internal): Even when using a
+	compile-time default stack size, apply the minimum that allocate_stack
+	will require, and round up to page size.
+
+2005-10-10  Daniel Jacobowitz  <dan@codesourcery.com>
+
+	* Makefile ($(test-modules)): Remove static pattern rule.
+
+2005-10-14  Jakub Jelinek  <jakub@redhat.com>
+	    Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_once.S: Fix stack
+	alignment in callback function.
+	* Makefile: Add rules to build and run tst-align3.
+	* tst-align3.c: New file.
+
+2005-10-03  Jakub Jelinek  <jakub@redhat.com>
+
+	* allocatestack.c (setxid_signal_thread): Add
+	INTERNAL_SYSCALL_DECL (err).
+
+2005-10-02  Jakub Jelinek  <jakub@redhat.com>
+
+	* allocatestack.c (setxid_signal_thread): Need to use
+	atomic_compare_and_exchange_bool_acq.
+
+2005-10-01  Ulrich Drepper  <drepper@redhat.com>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	* descr.h: Define SETXID_BIT and SETXID_BITMASK.  Adjust
+	CANCEL_RESTMASK.
+	(struct pthread): Move specific_used field to avoid padding.
+	Add setxid_futex field.
+	* init.c (sighandler_setxid): Reset setxid flag and release the
+	setxid futex.
+	* allocatestack.c (setxid_signal_thread): New function.  Broken
+	out of the bodies of the two loops in __nptl_setxid.  For undetached
+	threads check whether they are exiting and if yes, don't send a signal.
+	(__nptl_setxid): Simplify loops by using setxid_signal_thread.
+	* pthread_create.c (start_thread): For undetached threads, check
+	whether setxid bit is set.  If yes, wait until signal has been
+	processed.
+
+	* allocatestack.c (STACK_VARIABLES): Initialize them.
+	* pthread_create.c (__pthread_create_2_1): Initialize pd.
+
+2004-09-02  Jakub Jelinek  <jakub@redhat.com>
+
+	* pthread_cond_destroy.c (__pthread_cond_destroy): If there are
+	waiters, awake all waiters on the associated mutex.
+
+2005-09-22  Roland McGrath  <roland@redhat.com>
+
+	* perf.c [__x86_64__] (HP_TIMING_NOW): New macro (copied from
+	../sysdeps/x86_64/hp-timing.h).
+
+2005-08-29  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (FUTEX_WAKE_OP,
+	FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+	(lll_futex_wake_unlock): Define.
+	* sysdeps/unix/sysv/linux/alpha/lowlevellock.h (FUTEX_WAKE_OP,
+	FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+	(lll_futex_wake_unlock): Define.
+	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h (FUTEX_WAKE_OP,
+	FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+	(lll_futex_wake_unlock): Define.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h (FUTEX_WAKE_OP,
+	FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+	(lll_futex_wake_unlock): Define.
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h (FUTEX_WAKE_OP,
+	FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+	(lll_futex_wake_unlock): Define.
+	* sysdeps/pthread/pthread_cond_signal.c (__pthread_cond_signal): Use
+	lll_futex_wake_unlock.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+	(FUTEX_WAKE_OP, FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+	(__pthread_cond_signal): Use FUTEX_WAKE_OP.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+	(FUTEX_WAKE_OP, FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define.
+	(__pthread_cond_signal): Use FUTEX_WAKE_OP.
+
+2005-09-05  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.S (__lll_mutex_lock_wait):
+	Fix typo in register name.
+
 2005-08-23  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/unix/sysv/linux/timer_routines.c (timer_helper_thread):

+ 44 - 0
libpthread/nptl/DESIGN-barrier.txt

@@ -0,0 +1,44 @@
+Barriers pseudocode
+===================
+
+    int pthread_barrier_wait(barrier_t *barrier);
+
+struct barrier_t {
+
+   unsigned int lock:
+         - internal mutex
+
+   unsigned int left;
+         - current barrier count, # of threads still needed.
+
+   unsigned int init_count;
+         - number of threads needed for the barrier to continue.
+
+   unsigned int curr_event;
+         - generation count
+}
+
+pthread_barrier_wait(barrier_t *barrier)
+{
+  unsigned int event;
+  result = 0;
+
+  lll_lock(barrier->lock);
+  if (!--barrier->left) {
+    barrier->curr_event++;
+    futex_wake(&barrier->curr_event, INT_MAX)
+
+    result = BARRIER_SERIAL_THREAD;
+  } else {
+    event = barrier->curr_event;
+    lll_unlock(barrier->lock);
+    do {
+      futex_wait(&barrier->curr_event, event)
+    } while (event == barrier->curr_event);
+  }
+
+  if (atomic_increment_val (barrier->left) == barrier->init_count)
+    lll_unlock(barrier->lock);
+
+  return result;
+}

+ 134 - 0
libpthread/nptl/DESIGN-condvar.txt

@@ -0,0 +1,134 @@
+Conditional Variable pseudocode.
+================================
+
+       int pthread_cond_timedwait (pthread_cond_t *cv, pthread_mutex_t *mutex);
+       int pthread_cond_signal    (pthread_cond_t *cv);
+       int pthread_cond_broadcast (pthread_cond_t *cv);
+
+struct pthread_cond_t {
+
+   unsigned int cond_lock;
+
+         internal mutex
+
+   uint64_t total_seq;
+
+     Total number of threads using the conditional variable.
+
+   uint64_t wakeup_seq;
+
+     sequence number for next wakeup.
+
+   uint64_t woken_seq;
+
+     sequence number of last woken thread.
+
+   uint32_t broadcast_seq;
+
+}
+
+
+struct cv_data {
+
+   pthread_cond_t *cv;
+
+   uint32_t bc_seq
+
+}
+
+
+
+cleanup_handler(cv_data)
+{
+  cv = cv_data->cv;
+  lll_lock(cv->lock);
+
+  if (cv_data->bc_seq == cv->broadcast_seq) {
+    ++cv->wakeup_seq;
+    ++cv->woken_seq;
+  }
+
+  /* make sure no signal gets lost.  */
+  FUTEX_WAKE(cv->wakeup_seq, ALL);
+
+  lll_unlock(cv->lock);
+}
+
+
+cond_timedwait(cv, mutex, timeout):
+{
+   lll_lock(cv->lock);
+   mutex_unlock(mutex);
+
+   cleanup_push
+
+   ++cv->total_seq;
+   val = seq =  cv->wakeup_seq;
+   cv_data.bc = cv->broadcast_seq;
+   cv_data.cv = cv;
+
+   while (1) {
+
+     lll_unlock(cv->lock);
+
+     enable_async(&cv_data);
+
+     ret = FUTEX_WAIT(cv->wakeup_seq, val, timeout);
+
+     restore_async
+
+     lll_lock(cv->lock);
+
+     if (bc != cv->broadcast_seq)
+       goto bc_out;
+
+     val = cv->wakeup_seq;
+
+     if (val != seq && cv->woken_seq != val) {
+       ret = 0;
+       break;
+     }
+
+     if (ret == TIMEDOUT) {
+       ++cv->wakeup_seq;
+       break;
+     }
+   }
+
+   ++cv->woken_seq;
+
+ bc_out:
+   lll_unlock(cv->lock);
+
+   cleanup_pop
+
+   mutex_lock(mutex);
+
+   return ret;
+}
+
+cond_signal(cv)
+{
+   lll_lock(cv->lock);
+
+   if (cv->total_seq > cv->wakeup_seq) {
+     ++cv->wakeup_seq;
+     FUTEX_WAKE(cv->wakeup_seq, 1);
+   }
+
+   lll_unlock(cv->lock);
+}
+
+cond_broadcast(cv)
+{
+   lll_lock(cv->lock);
+
+   if (cv->total_seq > cv->wakeup_seq) {
+     cv->wakeup_seq = cv->total_seq;
+     cv->woken_seq = cv->total_seq;
+     ++cv->broadcast_seq;
+     FUTEX_WAKE(cv->wakeup_seq, ALL);
+   }
+
+   lll_unlock(cv->lock);
+}

+ 113 - 0
libpthread/nptl/DESIGN-rwlock.txt

@@ -0,0 +1,113 @@
+Reader Writer Locks pseudocode
+==============================
+
+	pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
+	pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
+	pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
+
+struct pthread_rwlock_t {
+
+   unsigned int lock:
+         - internal mutex
+
+   unsigned int writers_preferred;
+         - locking mode: 0 recursive, readers preferred
+                         1 nonrecursive, writers preferred
+
+   unsigned int readers;
+         - number of read-only references various threads have
+
+   pthread_t writer;
+         - descriptor of the writer or 0
+
+   unsigned int readers_wakeup;
+         - 'all readers should wake up' futex.
+
+   unsigned int writer_wakeup;
+         - 'one writer should wake up' futex.
+
+   unsigned int nr_readers_queued;
+         - number of readers queued up.
+
+   unsigned int nr_writers_queued;
+         - number of writers queued up.
+}
+
+pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
+{
+  lll_lock(rwlock->lock);
+  for (;;) {
+    if (!rwlock->writer && (!rwlock->nr_writers_queued ||
+					!rwlock->writers_preferred))
+        break;
+
+    rwlock->nr_readers_queued++;
+    val = rwlock->readers_wakeup;
+    lll_unlock(rwlock->lock);
+
+    futex_wait(&rwlock->readers_wakeup, val)
+
+    lll_lock(rwlock->lock);
+    rwlock->nr_readers_queued--;
+  }
+  rwlock->readers++;
+  lll_unlock(rwlock->lock);
+}
+
+pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
+{
+  int result = EBUSY;
+  lll_lock(rwlock->lock);
+  if (!rwlock->writer && (!rwlock->nr_writers_queued ||
+					!rwlock->writers_preferred))
+    rwlock->readers++;
+  lll_unlock(rwlock->lock);
+  return result;
+}
+
+pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
+{
+  lll_lock(rwlock->lock);
+  for (;;) {
+    if (!rwlock->writer && !rwlock->readers)
+       break;
+
+    rwlock->nr_writers_queued++;
+    val = rwlock->writer_wakeup;
+    lll_unlock(rwlock->lock);
+
+    futex_wait(&rwlock->writer_wakeup, val);
+
+    lll_lock(rwlock->lock);
+    rwlock->nr_writers_queued--;
+  }
+  rwlock->writer = pthread_self();
+  lll_unlock(rwlock->lock);
+}
+
+pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
+{
+  lll_lock(rwlock->lock);
+
+  if (rwlock->writer)
+    rwlock->writer = 0;
+  else
+    rwlock->readers--;
+
+  if (!rwlock->readers) {
+    if (rwlock->nr_writers_queued) {
+      ++rwlock->writer_wakeup;
+      lll_unlock(rwlock->lock);
+      futex_wake(&rwlock->writer_wakeup, 1);
+      return;
+    } else
+      if (rwlock->nr_readers_queued) {
+        ++rwlock->readers_wakeup;
+        lll_unlock(rwlock->lock);
+        futex_wake(&rwlock->readers_wakeup, MAX_INT);
+        return;
+      }
+  }
+
+  lll_unlock(rwlock->lock);
+}

+ 46 - 0
libpthread/nptl/DESIGN-sem.txt

@@ -0,0 +1,46 @@
+Semaphores pseudocode
+==============================
+
+       int sem_wait(sem_t * sem);
+       int sem_trywait(sem_t * sem);
+       int sem_post(sem_t * sem);
+       int sem_getvalue(sem_t * sem, int * sval);
+
+struct sem_t {
+
+   unsigned int count;
+         - current semaphore count, also used as a futex
+}
+
+sem_wait(sem_t *sem)
+{
+  for (;;) {
+
+    if (atomic_decrement_if_positive(sem->count))
+      break;
+
+    futex_wait(&sem->count, 0)
+  }
+}
+
+sem_post(sem_t *sem)
+{
+  n = atomic_increment(sem->count);
+  // Pass the new value of sem->count
+  futex_wake(&sem->count, n + 1);
+}
+
+sem_trywait(sem_t *sem)
+{
+  if (atomic_decrement_if_positive(sem->count)) {
+    return 0;
+  } else {
+    return EAGAIN;
+  }
+}
+
+sem_getvalue(sem_t *sem, int *sval)
+{
+  *sval = sem->count;
+  read_barrier();
+}

+ 7 - 0
libpthread/nptl/Makefile.in

@@ -31,9 +31,16 @@ libpthread-routines = init vars events version \
 		      pthread_mutex_init pthread_mutex_destroy \
 		      pthread_mutex_lock pthread_mutex_trylock \
 		      pthread_mutex_timedlock pthread_mutex_unlock \
+		      pthread_mutex_consistent \
 		      pthread_mutexattr_init pthread_mutexattr_destroy \
 		      pthread_mutexattr_getpshared \
 		      pthread_mutexattr_setpshared \
+		      pthread_mutexattr_getrobust \
+		      pthread_mutexattr_setrobust \
+		      pthread_mutexattr_getprotocol \
+		      pthread_mutexattr_setprotocol \
+		      pthread_mutexattr_getprioceiling \
+		      pthread_mutexattr_setprioceiling \
 		      pthread_mutexattr_gettype pthread_mutexattr_settype \
 		      pthread_rwlock_init pthread_rwlock_destroy \
 		      pthread_rwlock_rdlock pthread_rwlock_timedrdlock \

+ 31 - 0
libpthread/nptl/TODO

@@ -0,0 +1,31 @@
+- we should probably extend pthread_mutexattr_t with a field to create a
+  single linked list of all instances.  This requires changing the
+  pthread_mutexattr_* functions.
+
+
+- a new attribute for mutexes: number of times we spin before calling
+sys_futex
+
+- for adaptive mutexes: when releasing, determine whether somebody spins.
+If yes, for a short time release lock.  If someone else locks no wakeup
+syscall needed.
+
+
+
+- test with threaded process terminating and semadj (?) being applied
+  only after all threads are gone
+
+
+
+- semaphore changes:
+
+  - sem_post should only wake one thread and only when the state of
+    the semaphore changed from 0 to 1
+
+    this also requires that sem_wait and sem_timedwait don't drop the
+    post if they get canceled.
+
+  - possibly add counter field.  This requires reviving the
+    differences between old and new semaphose funtions.  The old ones
+    stay as they are now.  The new once can use an additional field
+    wich is the counter for the number of waiters

+ 20 - 0
libpthread/nptl/TODO-kernel

@@ -0,0 +1,20 @@
+- setuid/setgid must effect process
+  + test syscalls (getuid) afterwards
+  + test core file content
+
+  + use UID/GID in access(2), chmod(2), chown(2), link(2)
+
+- nice level is process property
+
+- rlimit should be process-wide and SIGXCPU should be sent if all threads
+  together exceed the limit
+
+- getrusage() must return resource utilization for the process
+
+
+
+The following are possible optimizations and in no way required:
+
+
+- the scheduler should be thread group-aware, i.e., it has to give time to
+  the thread group not proportional to the number of threads.

+ 20 - 0
libpthread/nptl/TODO-testing

@@ -0,0 +1,20 @@
+pthread_attr_setguardsize
+
+  test effectiveness
+
+pthread_attr_[sg]etschedparam
+
+  what to test?
+
+pthread_attr_[sg]etstack
+
+  some more tests needed
+
+pthread_getcpuclockid
+
+  check that value is reset -> rt subdir
+
+pthread_getschedparam
+pthread_setschedparam
+
+  what to test?

+ 421 - 130
libpthread/nptl/allocatestack.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -28,13 +28,13 @@
 #include <tls.h>
 #include <lowlevellock.h>
 #include <link.h>
+#include <bits/kernel-features.h>
 
-#define __getpagesize getpagesize
 
 #ifndef NEED_SEPARATE_REGISTER_STACK
 
 /* Most architectures have exactly one stack pointer.  Some have more.  */
-# define STACK_VARIABLES void *stackaddr = 0
+# define STACK_VARIABLES void *stackaddr = NULL
 
 /* How to pass the values to the 'create_thread' function.  */
 # define STACK_VARIABLES_ARGS stackaddr
@@ -53,7 +53,7 @@
 
 /* We need two stacks.  The kernel will place them but we have to tell
    the kernel about the size of the reserved address space.  */
-# define STACK_VARIABLES void *stackaddr = 0; size_t stacksize
+# define STACK_VARIABLES void *stackaddr = NULL; size_t stacksize = 0
 
 /* How to pass the values to the 'create_thread' function.  */
 # define STACK_VARIABLES_ARGS stackaddr, stacksize
@@ -84,10 +84,10 @@
 #endif
 
 
-/* Let the architecture add some flags to the mmap() call used to
-   allocate stacks.  */
-#ifndef ARCH_MAP_FLAGS
-# define ARCH_MAP_FLAGS 0
+/* Newer kernels have the MAP_STACK flag to indicate a mapping is used for
+   a stack.  Use it when possible.  */
+#ifndef MAP_STACK
+# define MAP_STACK 0
 #endif
 
 /* This yields the pointer that TLS support code calls the thread pointer.  */
@@ -104,7 +104,7 @@ static size_t stack_cache_maxsize = 40 * 1024 * 1024; /* 40MiBi by default.  */
 static size_t stack_cache_actsize;
 
 /* Mutex protecting this variable.  */
-static lll_lock_t stack_cache_lock = LLL_LOCK_INITIALIZER;
+static int stack_cache_lock = LLL_LOCK_INITIALIZER;
 
 /* List of queued stack frames.  */
 static LIST_HEAD (stack_cache);
@@ -112,10 +112,15 @@ static LIST_HEAD (stack_cache);
 /* List of the stacks in use.  */
 static LIST_HEAD (stack_used);
 
+/* We need to record what list operations we are going to do so that,
+   in case of an asynchronous interruption due to a fork() call, we
+   can correct for the work.  */
+static uintptr_t in_flight_stack;
+
 /* List of the threads with user provided stacks in use.  No need to
    initialize this, since it's done in __pthread_initialize_minimal.  */
 list_t __stack_user __attribute__ ((nocommon));
-hidden_def (__stack_user)
+hidden_data_def (__stack_user)
 
 #if COLORING_INCREMENT != 0
 /* Number of threads created.  */
@@ -127,6 +132,36 @@ static unsigned int nptl_ncreated;
 #define FREE_P(descr) ((descr)->tid <= 0)
 
 
+static void
+stack_list_del (list_t *elem)
+{
+  in_flight_stack = (uintptr_t) elem;
+
+  atomic_write_barrier ();
+
+  list_del (elem);
+
+  atomic_write_barrier ();
+
+  in_flight_stack = 0;
+}
+
+
+static void
+stack_list_add (list_t *elem, list_t *list)
+{
+  in_flight_stack = (uintptr_t) elem | 1;
+
+  atomic_write_barrier ();
+
+  list_add (elem, list);
+
+  atomic_write_barrier ();
+
+  in_flight_stack = 0;
+}
+
+
 /* We create a double linked list of all cache entries.  Double linked
    because this allows removing entries from the end.  */
 
@@ -140,7 +175,7 @@ get_cached_stack (size_t *sizep, void **memp)
   struct pthread *result = NULL;
   list_t *entry;
 
-  lll_lock (stack_cache_lock);
+  lll_lock (stack_cache_lock, LLL_PRIVATE);
 
   /* Search the cache for a matching entry.  We search for the
      smallest stack which has at least the required size.  Note that
@@ -173,22 +208,22 @@ get_cached_stack (size_t *sizep, void **memp)
       || __builtin_expect (result->stackblock_size > 4 * size, 0))
     {
       /* Release the lock.  */
-      lll_unlock (stack_cache_lock);
+      lll_unlock (stack_cache_lock, LLL_PRIVATE);
 
       return NULL;
     }
 
   /* Dequeue the entry.  */
-  list_del (&result->list);
+  stack_list_del (&result->list);
 
   /* And add to the list of stacks in use.  */
-  list_add (&result->list, &stack_used);
+  stack_list_add (&result->list, &stack_used);
 
   /* And decrease the cache size.  */
   stack_cache_actsize -= result->stackblock_size;
 
   /* Release the lock early.  */
-  lll_unlock (stack_cache_lock);
+  lll_unlock (stack_cache_lock, LLL_PRIVATE);
 
   /* Report size and location of the stack to the caller.  */
   *sizep = result->stackblock_size;
@@ -212,6 +247,45 @@ get_cached_stack (size_t *sizep, void **memp)
 }
 
 
+/* Free stacks until cache size is lower than LIMIT.  */
+void
+__free_stacks (size_t limit)
+{
+  /* We reduce the size of the cache.  Remove the last entries until
+     the size is below the limit.  */
+  list_t *entry;
+  list_t *prev;
+
+  /* Search from the end of the list.  */
+  list_for_each_prev_safe (entry, prev, &stack_cache)
+    {
+      struct pthread *curr;
+
+      curr = list_entry (entry, struct pthread, list);
+      if (FREE_P (curr))
+	{
+	  /* Unlink the block.  */
+	  stack_list_del (entry);
+
+	  /* Account for the freed memory.  */
+	  stack_cache_actsize -= curr->stackblock_size;
+
+	  /* Free the memory associated with the ELF TLS.  */
+	  _dl_deallocate_tls (TLS_TPADJ (curr), false);
+
+	  /* Remove this block.  This should never fail.  If it does
+	     something is really wrong.  */
+	  if (munmap (curr->stackblock, curr->stackblock_size) != 0)
+	    abort ();
+
+	  /* Maybe we have freed enough.  */
+	  if (stack_cache_actsize <= limit)
+	    break;
+	}
+    }
+}
+
+
 /* Add a stack frame which is not used anymore to the stack.  Must be
    called with the cache lock held.  */
 static inline void
@@ -221,44 +295,11 @@ queue_stack (struct pthread *stack)
   /* We unconditionally add the stack to the list.  The memory may
      still be in use but it will not be reused until the kernel marks
      the stack as not used anymore.  */
-  list_add (&stack->list, &stack_cache);
+  stack_list_add (&stack->list, &stack_cache);
 
   stack_cache_actsize += stack->stackblock_size;
   if (__builtin_expect (stack_cache_actsize > stack_cache_maxsize, 0))
-    {
-      /* We reduce the size of the cache.  Remove the last entries
-	 until the size is below the limit.  */
-      list_t *entry;
-      list_t *prev;
-
-      /* Search from the end of the list.  */
-      list_for_each_prev_safe (entry, prev, &stack_cache)
-	{
-	  struct pthread *curr;
-
-	  curr = list_entry (entry, struct pthread, list);
-	  if (FREE_P (curr))
-	    {
-	      /* Unlink the block.  */
-	      list_del (entry);
-
-	      /* Account for the freed memory.  */
-	      stack_cache_actsize -= curr->stackblock_size;
-
-	      /* Free the memory associated with the ELF TLS.  */
-	      _dl_deallocate_tls (TLS_TPADJ (curr), false);
-
-	      /* Remove this block.  This should never fail.  If it
-		 does something is really wrong.  */
-	      if (munmap (curr->stackblock, curr->stackblock_size) != 0)
-		abort ();
-
-	      /* Maybe we have freed enough.  */
-	      if (stack_cache_actsize <= stack_cache_maxsize)
-		break;
-	    }
-	}
-    }
+    __free_stacks (stack_cache_maxsize);
 }
 
 
@@ -275,9 +316,14 @@ change_stack_perm (struct pthread *pd
 		 + (((((pd->stackblock_size - pd->guardsize) / 2)
 		      & pagemask) + pd->guardsize) & pagemask));
   size_t len = pd->stackblock + pd->stackblock_size - stack;
-#else
+#elif _STACK_GROWS_DOWN
   void *stack = pd->stackblock + pd->guardsize;
   size_t len = pd->stackblock_size - pd->guardsize;
+#elif _STACK_GROWS_UP
+  void *stack = pd->stackblock;
+  size_t len = (uintptr_t) pd - pd->guardsize - (uintptr_t) pd->stackblock;
+#else
+# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
 #endif
   if (mprotect (stack, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
     return errno;
@@ -358,6 +404,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
       __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
 #endif
 
+#ifndef __ASSUME_PRIVATE_FUTEX
+      /* The thread must know when private futexes are supported.  */
+      pd->header.private_futex = THREAD_GETMEM (THREAD_SELF,
+						header.private_futex);
+#endif
+
 #ifdef NEED_DL_SYSINFO
       /* Copy the sysinfo value from the parent.  */
       THREAD_SYSINFO(pd) = THREAD_SELF_SYSINFO;
@@ -376,12 +428,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 
 
       /* Prepare to modify global data.  */
-      lll_lock (stack_cache_lock);
+      lll_lock (stack_cache_lock, LLL_PRIVATE);
 
       /* And add to the list of stacks in use.  */
       list_add (&pd->list, &__stack_user);
 
-      lll_unlock (stack_cache_lock);
+      lll_unlock (stack_cache_lock, LLL_PRIVATE);
     }
   else
     {
@@ -406,8 +458,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
       /* Make sure the size of the stack is enough for the guard and
 	 eventually the thread descriptor.  */
       guardsize = (attr->guardsize + pagesize_m1) & ~pagesize_m1;
-      if (__builtin_expect (size < (guardsize + __static_tls_size
-				    + MINIMAL_REST_STACK + pagesize_m1 + 1),
+      if (__builtin_expect (size < ((guardsize + __static_tls_size
+				     + MINIMAL_REST_STACK + pagesize_m1)
+				    & ~pagesize_m1),
 			    0))
 	/* The stack is too small (or the guard too large).  */
 	return EINVAL;
@@ -427,15 +480,14 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 #endif
 
 	  mem = mmap (NULL, size, prot,
-		      MAP_PRIVATE | MAP_ANONYMOUS | ARCH_MAP_FLAGS, -1, 0);
+		      MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
 
 	  if (__builtin_expect (mem == MAP_FAILED, 0))
 	    {
-#ifdef ARCH_RETRY_MMAP
-	      mem = ARCH_RETRY_MMAP (size);
-	      if (__builtin_expect (mem == MAP_FAILED, 0))
-#endif
-		return errno;
+	      if (errno == ENOMEM)
+		__set_errno (EAGAIN);
+
+	       return errno;
 	    }
 
 	  /* SIZE is guaranteed to be greater than zero.
@@ -490,6 +542,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	  __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
 #endif
 
+#ifndef __ASSUME_PRIVATE_FUTEX
+	  /* The thread must know when private futexes are supported.  */
+	  pd->header.private_futex = THREAD_GETMEM (THREAD_SELF,
+                                                    header.private_futex);
+#endif
+
 #ifdef NEED_DL_SYSINFO
 	  /* Copy the sysinfo value from the parent.  */
 	  THREAD_SYSINFO(pd) = THREAD_SELF_SYSINFO;
@@ -512,12 +570,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 
 
 	  /* Prepare to modify global data.  */
-	  lll_lock (stack_cache_lock);
+	  lll_lock (stack_cache_lock, LLL_PRIVATE);
 
 	  /* And add to the list of stacks in use.  */
-	  list_add (&pd->list, &stack_used);
+	  stack_list_add (&pd->list, &stack_used);
 
-	  lll_unlock (stack_cache_lock);
+	  lll_unlock (stack_cache_lock, LLL_PRIVATE);
 
 
 	  /* Note that all of the stack and the thread descriptor is
@@ -533,8 +591,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	{
 #ifdef NEED_SEPARATE_REGISTER_STACK
 	  char *guard = mem + (((size - guardsize) / 2) & ~pagesize_m1);
-#else
+#elif _STACK_GROWS_DOWN
 	  char *guard = mem;
+# elif _STACK_GROWS_UP
+	  char *guard = (char *) (((uintptr_t) pd - guardsize) & ~pagesize_m1);
 #endif
 	  if (mprotect (guard, guardsize, PROT_NONE) != 0)
 	    {
@@ -542,12 +602,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	    mprot_error:
 	      err = errno;
 
-	      lll_lock (stack_cache_lock);
+	      lll_lock (stack_cache_lock, LLL_PRIVATE);
 
 	      /* Remove the thread from the list.  */
-	      list_del (&pd->list);
+	      stack_list_del (&pd->list);
 
-	      lll_unlock (stack_cache_lock);
+	      lll_unlock (stack_cache_lock, LLL_PRIVATE);
 
 	      /* Get rid of the TLS block we allocated.  */
 	      _dl_deallocate_tls (TLS_TPADJ (pd), false);
@@ -581,10 +641,14 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 			oldguard + pd->guardsize - guard - guardsize,
 			prot) != 0)
 	    goto mprot_error;
-#else
+#elif _STACK_GROWS_DOWN
 	  if (mprotect ((char *) mem + guardsize, pd->guardsize - guardsize,
 			prot) != 0)
 	    goto mprot_error;
+#elif _STACK_GROWS_UP
+	  if (mprotect ((char *) pd - pd->guardsize,
+			pd->guardsize - guardsize, prot) != 0)
+	    goto mprot_error;
 #endif
 
 	  pd->guardsize = guardsize;
@@ -599,6 +663,18 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
      stillborn thread could be canceled while the lock is taken.  */
   pd->lock = LLL_LOCK_INITIALIZER;
 
+  /* The robust mutex lists also need to be initialized
+     unconditionally because the cleanup for the previous stack owner
+     might have happened in the kernel.  */
+  pd->robust_head.futex_offset = (offsetof (pthread_mutex_t, __data.__lock)
+				  - offsetof (pthread_mutex_t,
+					      __data.__list.__next));
+  pd->robust_head.list_op_pending = NULL;
+#ifdef __PTHREAD_MUTEX_HAVE_PREV
+  pd->robust_prev = &pd->robust_head;
+#endif
+  pd->robust_head.list = &pd->robust_head;
+
   /* We place the thread descriptor at the end of the stack.  */
   *pdp = pd;
 
@@ -612,8 +688,11 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 #ifdef NEED_SEPARATE_REGISTER_STACK
   *stack = pd->stackblock;
   *stacksize = stacktop - *stack;
-#else
+#elif _STACK_GROWS_DOWN
   *stack = stacktop;
+#elif _STACK_GROWS_UP
+  *stack = pd->stackblock;
+  assert (*stack > 0);
 #endif
 
   return 0;
@@ -624,11 +703,11 @@ void
 internal_function
 __deallocate_stack (struct pthread *pd)
 {
-  lll_lock (stack_cache_lock);
+  lll_lock (stack_cache_lock, LLL_PRIVATE);
 
   /* Remove the thread from the list of threads with user defined
      stacks.  */
-  list_del (&pd->list);
+  stack_list_del (&pd->list);
 
   /* Not much to do.  Just free the mmap()ed memory.  Note that we do
      not reset the 'used' flag in the 'tid' field.  This is done by
@@ -640,7 +719,7 @@ __deallocate_stack (struct pthread *pd)
     /* Free the memory associated with the ELF TLS.  */
     _dl_deallocate_tls (TLS_TPADJ (pd), false);
 
-  lll_unlock (stack_cache_lock);
+  lll_unlock (stack_cache_lock, LLL_PRIVATE);
 }
 
 
@@ -657,7 +736,7 @@ __make_stacks_executable (void **stack_endp)
   const size_t pagemask = ~(__getpagesize () - 1);
 #endif
 
-  lll_lock (stack_cache_lock);
+  lll_lock (stack_cache_lock, LLL_PRIVATE);
 
   list_t *runp;
   list_for_each (runp, &stack_used)
@@ -686,7 +765,7 @@ __make_stacks_executable (void **stack_endp)
 	  break;
       }
 
-  lll_unlock (stack_cache_lock);
+  lll_unlock (stack_cache_lock, LLL_PRIVATE);
 
   return err;
 }
@@ -701,15 +780,51 @@ __reclaim_stacks (void)
 {
   struct pthread *self = (struct pthread *) THREAD_SELF;
 
-  /* No locking necessary.  The caller is the only stack in use.  */
+  /* No locking necessary.  The caller is the only stack in use.  But
+     we have to be aware that we might have interrupted a list
+     operation.  */
+
+  if (in_flight_stack != 0)
+    {
+      bool add_p = in_flight_stack & 1;
+      list_t *elem = (list_t *) (in_flight_stack & ~UINTMAX_C (1));
+
+      if (add_p)
+	{
+	  /* We always add at the beginning of the list.  So in this
+	     case we only need to check the beginning of these lists.  */
+	  int check_list (list_t *l)
+	  {
+	    if (l->next->prev != l)
+	      {
+		assert (l->next->prev == elem);
+
+		elem->next = l->next;
+		elem->prev = l;
+		l->next = elem;
+
+		return 1;
+	      }
+
+	    return 0;
+	  }
+
+	  if (check_list (&stack_used) == 0)
+	    (void) check_list (&stack_cache);
+	}
+      else
+	{
+	  /* We can simply always replay the delete operation.  */
+	  elem->next->prev = elem->prev;
+	  elem->prev->next = elem->next;
+	}
+    }
 
   /* Mark all stacks except the still running one as free.  */
   list_t *runp;
   list_for_each (runp, &stack_used)
     {
-      struct pthread *curp;
-
-      curp = list_entry (runp, struct pthread, list);
+      struct pthread *curp = list_entry (runp, struct pthread, list);
       if (curp != self)
 	{
 	  /* This marks the stack as free.  */
@@ -720,16 +835,43 @@ __reclaim_stacks (void)
 
 	  /* Account for the size of the stack.  */
 	  stack_cache_actsize += curp->stackblock_size;
+
+	  if (curp->specific_used)
+	    {
+	      /* Clear the thread-specific data.  */
+	      memset (curp->specific_1stblock, '\0',
+		      sizeof (curp->specific_1stblock));
+
+	      curp->specific_used = false;
+
+	      for (size_t cnt = 1; cnt < PTHREAD_KEY_1STLEVEL_SIZE; ++cnt)
+		if (curp->specific[cnt] != NULL)
+		  {
+		    memset (curp->specific[cnt], '\0',
+			    sizeof (curp->specific_1stblock));
+
+		    /* We have allocated the block which we do not
+		       free here so re-set the bit.  */
+		    curp->specific_used = true;
+		  }
+	    }
 	}
     }
 
+  /* Reset the PIDs in any cached stacks.  */
+  list_for_each (runp, &stack_cache)
+    {
+      struct pthread *curp = list_entry (runp, struct pthread, list);
+      curp->pid = self->pid;
+    }
+
   /* Add the stack of all running threads to the cache.  */
   list_splice (&stack_used, &stack_cache);
 
   /* Remove the entry for the current thread to from the cache list
      and add it to the list of running threads.  Which of the two
      lists is decided by the user_stack flag.  */
-  list_del (&self->list);
+  stack_list_del (&self->list);
 
   /* Re-initialize the lists for all the threads.  */
   INIT_LIST_HEAD (&stack_used);
@@ -743,6 +885,8 @@ __reclaim_stacks (void)
   /* There is one thread running.  */
   __nptl_nthreads = 1;
 
+  in_flight_stack = 0;
+
   /* Initialize the lock.  */
   stack_cache_lock = LLL_LOCK_INITIALIZER;
 }
@@ -757,7 +901,7 @@ __find_thread_by_id (pid_t tid)
 {
   struct pthread *result = NULL;
 
-  lll_lock (stack_cache_lock);
+  lll_lock (stack_cache_lock, LLL_PRIVATE);
 
   /* Iterate over the list with system-allocated threads first.  */
   list_t *runp;
@@ -789,24 +933,100 @@ __find_thread_by_id (pid_t tid)
     }
 
  out:
-  lll_unlock (stack_cache_lock);
+  lll_unlock (stack_cache_lock, LLL_PRIVATE);
 
   return result;
 }
 #endif
 
+
+static void
+internal_function
+setxid_mark_thread (struct xid_command *cmdp, struct pthread *t)
+{
+  int ch;
+
+  /* Don't let the thread exit before the setxid handler runs.  */
+  t->setxid_futex = 0;
+
+  do
+    {
+      ch = t->cancelhandling;
+
+      /* If the thread is exiting right now, ignore it.  */
+      if ((ch & EXITING_BITMASK) != 0)
+	return;
+    }
+  while (atomic_compare_and_exchange_bool_acq (&t->cancelhandling,
+					       ch | SETXID_BITMASK, ch));
+}
+
+
+static void
+internal_function
+setxid_unmark_thread (struct xid_command *cmdp, struct pthread *t)
+{
+  int ch;
+
+  do
+    {
+      ch = t->cancelhandling;
+      if ((ch & SETXID_BITMASK) == 0)
+	return;
+    }
+  while (atomic_compare_and_exchange_bool_acq (&t->cancelhandling,
+					       ch & ~SETXID_BITMASK, ch));
+
+  /* Release the futex just in case.  */
+  t->setxid_futex = 1;
+  lll_futex_wake (&t->setxid_futex, 1, LLL_PRIVATE);
+}
+
+
+static int
+internal_function
+setxid_signal_thread (struct xid_command *cmdp, struct pthread *t)
+{
+  if ((t->cancelhandling & SETXID_BITMASK) == 0)
+    return 0;
+
+  int val;
+  INTERNAL_SYSCALL_DECL (err);
+#if __ASSUME_TGKILL
+  val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
+			  t->tid, SIGSETXID);
+#else
+# ifdef __NR_tgkill
+  val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
+			  t->tid, SIGSETXID);
+  if (INTERNAL_SYSCALL_ERROR_P (val, err)
+      && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
+# endif
+    val = INTERNAL_SYSCALL (tkill, err, 2, t->tid, SIGSETXID);
+#endif
+
+  /* If this failed, it must have had not started yet or else exited.  */
+  if (!INTERNAL_SYSCALL_ERROR_P (val, err))
+    {
+      atomic_increment (&cmdp->cntr);
+      return 1;
+    }
+  else
+    return 0;
+}
+
+
 int
 attribute_hidden
 __nptl_setxid (struct xid_command *cmdp)
 {
+  int signalled;
   int result;
-  lll_lock (stack_cache_lock);
+  lll_lock (stack_cache_lock, LLL_PRIVATE);
 
   __xidcmd = cmdp;
   cmdp->cntr = 0;
 
-  INTERNAL_SYSCALL_DECL (err);
-
   struct pthread *self = THREAD_SELF;
 
   /* Iterate over the list with system-allocated threads first.  */
@@ -814,65 +1034,79 @@ __nptl_setxid (struct xid_command *cmdp)
   list_for_each (runp, &stack_used)
     {
       struct pthread *t = list_entry (runp, struct pthread, list);
-      if (t != self)
-	{
-	  int val;
-#if __ASSUME_TGKILL
-	  val = INTERNAL_SYSCALL (tgkill, err, 3,
-				  THREAD_GETMEM (THREAD_SELF, pid),
-				  t->tid, SIGSETXID);
-#else
-# ifdef __NR_tgkill
-	  val = INTERNAL_SYSCALL (tgkill, err, 3,
-				  THREAD_GETMEM (THREAD_SELF, pid),
-				  t->tid, SIGSETXID);
-	  if (INTERNAL_SYSCALL_ERROR_P (val, err)
-	      && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
-# endif
-	    val = INTERNAL_SYSCALL (tkill, err, 2, t->tid, SIGSETXID);
-#endif
+      if (t == self)
+	continue;
 
-	  if (!INTERNAL_SYSCALL_ERROR_P (val, err))
-	    atomic_increment (&cmdp->cntr);
-	}
+      setxid_mark_thread (cmdp, t);
     }
 
   /* Now the list with threads using user-allocated stacks.  */
   list_for_each (runp, &__stack_user)
     {
       struct pthread *t = list_entry (runp, struct pthread, list);
-      if (t != self)
+      if (t == self)
+	continue;
+
+      setxid_mark_thread (cmdp, t);
+    }
+
+  /* Iterate until we don't succeed in signalling anyone.  That means
+     we have gotten all running threads, and their children will be
+     automatically correct once started.  */
+  do
+    {
+      signalled = 0;
+
+      list_for_each (runp, &stack_used)
 	{
-	  int val;
-#if __ASSUME_TGKILL
-	  val = INTERNAL_SYSCALL (tgkill, err, 3,
-				  THREAD_GETMEM (THREAD_SELF, pid),
-				  t->tid, SIGSETXID);
-#else
-# ifdef __NR_tgkill
-	  val = INTERNAL_SYSCALL (tgkill, err, 3,
-				  THREAD_GETMEM (THREAD_SELF, pid),
-				  t->tid, SIGSETXID);
-	  if (INTERNAL_SYSCALL_ERROR_P (val, err)
-	      && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
-# endif
-	    val = INTERNAL_SYSCALL (tkill, err, 2, t->tid, SIGSETXID);
-#endif
+	  struct pthread *t = list_entry (runp, struct pthread, list);
+	  if (t == self)
+	    continue;
+
+	  signalled += setxid_signal_thread (cmdp, t);
+	}
 
-	  if (!INTERNAL_SYSCALL_ERROR_P (val, err))
-	    atomic_increment (&cmdp->cntr);
+      list_for_each (runp, &__stack_user)
+	{
+	  struct pthread *t = list_entry (runp, struct pthread, list);
+	  if (t == self)
+	    continue;
+
+	  signalled += setxid_signal_thread (cmdp, t);
+	}
+
+      int cur = cmdp->cntr;
+      while (cur != 0)
+	{
+	  lll_futex_wait (&cmdp->cntr, cur, LLL_PRIVATE);
+	  cur = cmdp->cntr;
 	}
     }
+  while (signalled != 0);
 
-  int cur = cmdp->cntr;
-  while (cur != 0)
+  /* Clean up flags, so that no thread blocks during exit waiting
+     for a signal which will never come.  */
+  list_for_each (runp, &stack_used)
     {
-      lll_futex_wait (&cmdp->cntr, cur);
-      cur = cmdp->cntr;
+      struct pthread *t = list_entry (runp, struct pthread, list);
+      if (t == self)
+	continue;
+
+      setxid_unmark_thread (cmdp, t);
+    }
+
+  list_for_each (runp, &__stack_user)
+    {
+      struct pthread *t = list_entry (runp, struct pthread, list);
+      if (t == self)
+	continue;
+
+      setxid_unmark_thread (cmdp, t);
     }
 
   /* This must be last, otherwise the current thread might not have
      permissions to send SIGSETXID syscall to the other threads.  */
+  INTERNAL_SYSCALL_DECL (err);
   result = INTERNAL_SYSCALL_NCS (cmdp->syscall_no, err, 3,
 				 cmdp->id[0], cmdp->id[1], cmdp->id[2]);
   if (INTERNAL_SYSCALL_ERROR_P (result, err))
@@ -881,7 +1115,7 @@ __nptl_setxid (struct xid_command *cmdp)
       result = -1;
     }
 
-  lll_unlock (stack_cache_lock);
+  lll_unlock (stack_cache_lock, LLL_PRIVATE);
   return result;
 }
 
@@ -910,7 +1144,7 @@ void
 attribute_hidden
 __pthread_init_static_tls (struct link_map *map)
 {
-  lll_lock (stack_cache_lock);
+  lll_lock (stack_cache_lock, LLL_PRIVATE);
 
   /* Iterate over the list with system-allocated threads first.  */
   list_t *runp;
@@ -921,5 +1155,62 @@ __pthread_init_static_tls (struct link_map *map)
   list_for_each (runp, &__stack_user)
     init_one_static_tls (list_entry (runp, struct pthread, list), map);
 
-  lll_unlock (stack_cache_lock);
+  lll_unlock (stack_cache_lock, LLL_PRIVATE);
+}
+
+
+void
+attribute_hidden
+__wait_lookup_done (void)
+{
+  lll_lock (stack_cache_lock, LLL_PRIVATE);
+
+  struct pthread *self = THREAD_SELF;
+
+  /* Iterate over the list with system-allocated threads first.  */
+  list_t *runp;
+  list_for_each (runp, &stack_used)
+    {
+      struct pthread *t = list_entry (runp, struct pthread, list);
+      if (t == self || t->header.gscope_flag == THREAD_GSCOPE_FLAG_UNUSED)
+	continue;
+
+      int *const gscope_flagp = &t->header.gscope_flag;
+
+      /* We have to wait until this thread is done with the global
+	 scope.  First tell the thread that we are waiting and
+	 possibly have to be woken.  */
+      if (atomic_compare_and_exchange_bool_acq (gscope_flagp,
+						THREAD_GSCOPE_FLAG_WAIT,
+						THREAD_GSCOPE_FLAG_USED))
+	continue;
+
+      do
+	lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT, LLL_PRIVATE);
+      while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
+    }
+
+  /* Now the list with threads using user-allocated stacks.  */
+  list_for_each (runp, &__stack_user)
+    {
+      struct pthread *t = list_entry (runp, struct pthread, list);
+      if (t == self || t->header.gscope_flag == THREAD_GSCOPE_FLAG_UNUSED)
+	continue;
+
+      int *const gscope_flagp = &t->header.gscope_flag;
+
+      /* We have to wait until this thread is done with the global
+	 scope.  First tell the thread that we are waiting and
+	 possibly have to be woken.  */
+      if (atomic_compare_and_exchange_bool_acq (gscope_flagp,
+						THREAD_GSCOPE_FLAG_WAIT,
+						THREAD_GSCOPE_FLAG_USED))
+	continue;
+
+      do
+	lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT, LLL_PRIVATE);
+      while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
+    }
+
+  lll_unlock (stack_cache_lock, LLL_PRIVATE);
 }

+ 15 - 5
libpthread/nptl/cancellation.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -70,14 +70,13 @@ __pthread_disable_asynccancel (int oldtype)
     return;
 
   struct pthread *self = THREAD_SELF;
+  int newval;
+
   int oldval = THREAD_GETMEM (self, cancelhandling);
 
   while (1)
     {
-      int newval = oldval & ~CANCELTYPE_BITMASK;
-
-      if (newval == oldval)
-	break;
+      newval = oldval & ~CANCELTYPE_BITMASK;
 
       int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
 					      oldval);
@@ -87,4 +86,15 @@ __pthread_disable_asynccancel (int oldtype)
       /* Prepare the next round.  */
       oldval = curval;
     }
+
+  /* We cannot return when we are being canceled.  Upon return the
+     thread might be things which would have to be undone.  The
+     following loop should loop until the cancellation signal is
+     delivered.  */
+  while (__builtin_expect ((newval & (CANCELING_BITMASK | CANCELED_BITMASK))
+			   == CANCELING_BITMASK, 0))
+    {
+      lll_futex_wait (&self->cancelhandling, newval, LLL_PRIVATE);
+      newval = THREAD_GETMEM (self, cancelhandling);
+    }
 }

+ 122 - 17
libpthread/nptl/descr.h

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2006, 2007, 2008, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -36,6 +36,7 @@
 #endif
 #define __need_res_state
 #include <resolv.h>
+#include <bits/kernel-features.h>
 
 #ifndef TCB_ALIGNMENT
 # define TCB_ALIGNMENT	sizeof (double)
@@ -101,6 +102,23 @@ struct xid_command
 };
 
 
+/* Data structure used by the kernel to find robust futexes.  */
+struct robust_list_head
+{
+  void *list;
+  long int futex_offset;
+  void *list_op_pending;
+};
+
+
+/* Data strcture used to handle thread priority protection.  */
+struct priority_protection_data
+{
+  int priomax;
+  unsigned int priomap[];
+};
+
+
 /* Thread descriptor data structure.  */
 struct pthread
 {
@@ -113,6 +131,10 @@ struct pthread
     struct
     {
       int multiple_threads;
+      int gscope_flag;
+# ifndef __ASSUME_PRIVATE_FUTEX
+      int private_futex;
+# endif
     } header;
 #endif
 
@@ -120,7 +142,7 @@ struct pthread
        is private and subject to change without affecting the official ABI.
        We just have it here in case it might be convenient for some
        implementation-specific instrumentation hack or suchlike.  */
-    void *__padding[16];
+    void *__padding[24];
   };
 
   /* This descriptor's link on the `stack_used' or `__stack_user' list.  */
@@ -133,6 +155,82 @@ struct pthread
   /* Process ID - thread group ID in kernel speak.  */
   pid_t pid;
 
+  /* List of robust mutexes the thread is holding.  */
+#ifdef __PTHREAD_MUTEX_HAVE_PREV
+  void *robust_prev;
+  struct robust_list_head robust_head;
+
+  /* The list above is strange.  It is basically a double linked list
+     but the pointer to the next/previous element of the list points
+     in the middle of the object, the __next element.  Whenever
+     casting to __pthread_list_t we need to adjust the pointer
+     first.  */
+# define QUEUE_PTR_ADJUST (offsetof (__pthread_list_t, __next))
+
+# define ENQUEUE_MUTEX_BOTH(mutex, val)					      \
+  do {									      \
+    __pthread_list_t *next = (__pthread_list_t *)			      \
+      ((((uintptr_t) THREAD_GETMEM (THREAD_SELF, robust_head.list)) & ~1ul)   \
+       - QUEUE_PTR_ADJUST);						      \
+    next->__prev = (void *) &mutex->__data.__list.__next;		      \
+    mutex->__data.__list.__next = THREAD_GETMEM (THREAD_SELF,		      \
+						 robust_head.list);	      \
+    mutex->__data.__list.__prev = (void *) &THREAD_SELF->robust_head;	      \
+    THREAD_SETMEM (THREAD_SELF, robust_head.list,			      \
+		   (void *) (((uintptr_t) &mutex->__data.__list.__next)	      \
+			     | val));					      \
+  } while (0)
+# define DEQUEUE_MUTEX(mutex) \
+  do {									      \
+    __pthread_list_t *next = (__pthread_list_t *)			      \
+      ((char *) (((uintptr_t) mutex->__data.__list.__next) & ~1ul)	      \
+       - QUEUE_PTR_ADJUST);						      \
+    next->__prev = mutex->__data.__list.__prev;				      \
+    __pthread_list_t *prev = (__pthread_list_t *)			      \
+      ((char *) (((uintptr_t) mutex->__data.__list.__prev) & ~1ul)	      \
+       - QUEUE_PTR_ADJUST);						      \
+    prev->__next = mutex->__data.__list.__next;				      \
+    mutex->__data.__list.__prev = NULL;					      \
+    mutex->__data.__list.__next = NULL;					      \
+  } while (0)
+#else
+  union
+  {
+    __pthread_slist_t robust_list;
+    struct robust_list_head robust_head;
+  };
+
+# define ENQUEUE_MUTEX_BOTH(mutex, val)					      \
+  do {									      \
+    mutex->__data.__list.__next						      \
+      = THREAD_GETMEM (THREAD_SELF, robust_list.__next);		      \
+    THREAD_SETMEM (THREAD_SELF, robust_list.__next,			      \
+		   (void *) (((uintptr_t) &mutex->__data.__list) | val));     \
+  } while (0)
+# define DEQUEUE_MUTEX(mutex) \
+  do {									      \
+    __pthread_slist_t *runp = (__pthread_slist_t *)			      \
+      (((uintptr_t) THREAD_GETMEM (THREAD_SELF, robust_list.__next)) & ~1ul); \
+    if (runp == &mutex->__data.__list)					      \
+      THREAD_SETMEM (THREAD_SELF, robust_list.__next, runp->__next);	      \
+    else								      \
+      {									      \
+	__pthread_slist_t *next = (__pthread_slist_t *)		      \
+	  (((uintptr_t) runp->__next) & ~1ul);				      \
+	while (next != &mutex->__data.__list)				      \
+	  {								      \
+	    runp = next;						      \
+	    next = (__pthread_slist_t *) (((uintptr_t) runp->__next) & ~1ul); \
+	  }								      \
+									      \
+	runp->__next = next->__next;					      \
+	mutex->__data.__list.__next = NULL;				      \
+      }									      \
+  } while (0)
+#endif
+#define ENQUEUE_MUTEX(mutex) ENQUEUE_MUTEX_BOTH (mutex, 0)
+#define ENQUEUE_MUTEX_PI(mutex) ENQUEUE_MUTEX_BOTH (mutex, 1)
+
   /* List of cleanup buffers.  */
   struct _pthread_cleanup_buffer *cleanup;
 
@@ -144,25 +242,25 @@ struct pthread
   int cancelhandling;
   /* Bit set if cancellation is disabled.  */
 #define CANCELSTATE_BIT		0
-#define CANCELSTATE_BITMASK	0x01
+#define CANCELSTATE_BITMASK	(0x01 << CANCELSTATE_BIT)
   /* Bit set if asynchronous cancellation mode is selected.  */
 #define CANCELTYPE_BIT		1
-#define CANCELTYPE_BITMASK	0x02
+#define CANCELTYPE_BITMASK	(0x01 << CANCELTYPE_BIT)
   /* Bit set if canceling has been initiated.  */
 #define CANCELING_BIT		2
-#define CANCELING_BITMASK	0x04
+#define CANCELING_BITMASK	(0x01 << CANCELING_BIT)
   /* Bit set if canceled.  */
 #define CANCELED_BIT		3
-#define CANCELED_BITMASK	0x08
+#define CANCELED_BITMASK	(0x01 << CANCELED_BIT)
   /* Bit set if thread is exiting.  */
 #define EXITING_BIT		4
-#define EXITING_BITMASK		0x10
+#define EXITING_BITMASK		(0x01 << EXITING_BIT)
   /* Bit set if thread terminated and TCB is freed.  */
 #define TERMINATED_BIT		5
-#define TERMINATED_BITMASK	0x20
+#define TERMINATED_BITMASK	(0x01 << TERMINATED_BIT)
   /* Bit set if thread is supposed to change XID.  */
 #define SETXID_BIT		6
-#define SETXID_BITMASK		0x40
+#define SETXID_BITMASK		(0x01 << SETXID_BIT)
   /* Mask for the rest.  Helps the compiler to optimize.  */
 #define CANCEL_RESTMASK		0xffffff80
 
@@ -174,6 +272,9 @@ struct pthread
 	       | EXITING_BITMASK | CANCEL_RESTMASK | TERMINATED_BITMASK))     \
    == (CANCELTYPE_BITMASK | CANCELED_BITMASK))
 
+  /* Flags.  Including those copied from the thread attribute.  */
+  int flags;
+
   /* We allocate one block of references here.  This should be enough
      to avoid allocating any memory dynamically for most applications.  */
   struct pthread_key_data
@@ -187,12 +288,12 @@ struct pthread
     void *data;
   } specific_1stblock[PTHREAD_KEY_2NDLEVEL_SIZE];
 
-  /* Flag which is set when specific data is set.  */
-  bool specific_used;
-
   /* Two-level array for the thread-specific data.  */
   struct pthread_key_data *specific[PTHREAD_KEY_1STLEVEL_SIZE];
 
+  /* Flag which is set when specific data is set.  */
+  bool specific_used;
+
   /* True if events must be reported.  */
   bool report_events;
 
@@ -202,11 +303,15 @@ struct pthread
   /* True if thread must stop at startup time.  */
   bool stopped_start;
 
+  /* The parent's cancel handling at the time of the pthread_create
+     call.  This might be needed to undo the effects of a cancellation.  */
+  int parent_cancelhandling;
+
   /* Lock to synchronize access to the descriptor.  */
-  lll_lock_t lock;
+  int lock;
 
   /* Lock for synchronizing setxid calls.  */
-  lll_lock_t setxid_futex;
+  int setxid_futex;
 
 #if HP_TIMING_AVAIL
   /* Offset of the CPU clock at start thread start time.  */
@@ -223,9 +328,6 @@ struct pthread
   /* Check whether a thread is detached.  */
 #define IS_DETACHED(pd) ((pd)->joinid == (pd))
 
-  /* Flags.  Including those copied from the thread attribute.  */
-  int flags;
-
   /* The result of the thread function.  */
   void *result;
 
@@ -257,6 +359,9 @@ struct pthread
   /* This is what the user specified and what we will report.  */
   size_t reported_guardsize;
 
+  /* Thread Priority Protection data.  */
+  struct priority_protection_data *tpp;
+
   /* Resolver state.  */
   struct __res_state res;
 

+ 7 - 25
libpthread/nptl/forward.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -21,22 +21,24 @@
 #include <pthreadP.h>
 #include <signal.h>
 #include <stdlib.h>
+
 #include <atomic.h>
 #include <sysdep.h>
 
 
 /* Pointers to the libc functions.  */
 struct pthread_functions __libc_pthread_functions attribute_hidden;
+int __libc_pthread_functions_init attribute_hidden;
 
 
 #define FORWARD2(name, rettype, decl, params, defaction) \
 rettype									      \
 name decl								      \
 {									      \
-  if (__libc_pthread_functions.ptr_##name == NULL)			      \
+  if (!__libc_pthread_functions_init)					      \
     defaction;								      \
 									      \
-  return __libc_pthread_functions.ptr_##name params;			      \
+  return PTHFCT_CALL (ptr_##name, params);				      \
 }
 
 #define FORWARD(name, decl, params, defretval) \
@@ -123,34 +125,13 @@ FORWARD (pthread_setschedparam,
 
 FORWARD (pthread_mutex_destroy, (pthread_mutex_t *mutex), (mutex), 0)
 
-libc_hidden_proto(pthread_mutex_init)
 FORWARD (pthread_mutex_init,
 	 (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr),
 	 (mutex, mutexattr), 0)
-strong_alias(pthread_mutex_init, __pthread_mutex_init)
-libc_hidden_def(pthread_mutex_init)
-
-libc_hidden_proto(pthread_mutex_trylock)
-FORWARD (pthread_mutex_trylock, (pthread_mutex_t *mutex), (mutex), 0)
-strong_alias(pthread_mutex_trylock, __pthread_mutex_trylock)
-libc_hidden_def(pthread_mutex_trylock)
 
-libc_hidden_proto(pthread_mutex_lock)
 FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0)
-strong_alias(pthread_mutex_lock, __pthread_mutex_lock)
-libc_hidden_def(pthread_mutex_lock)
 
-libc_hidden_proto(pthread_mutex_unlock)
 FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0)
-strong_alias(pthread_mutex_unlock, __pthread_mutex_unlock)
-libc_hidden_def(pthread_mutex_unlock)
-
-FORWARD (pthread_mutexattr_init, (pthread_mutexattr_t *attr), (attr), 0)
-
-FORWARD (pthread_mutexattr_destroy, (pthread_mutexattr_t *attr), (attr), 0)
-
-FORWARD (pthread_mutexattr_settype, (pthread_mutexattr_t *attr, int kind),
-				    (attr, kind), 0)
 
 
 FORWARD2 (pthread_self, pthread_t, (void), (), return 0)
@@ -163,7 +144,8 @@ FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0)
 
 #define return /* value is void */
 FORWARD2(__pthread_unwind,
-	 void attribute_hidden __attribute ((noreturn)) __cleanup_fct_attribute,
+	 void attribute_hidden __attribute ((noreturn)) __cleanup_fct_attribute
+	 attribute_compat_text_section,
 	 (__pthread_unwind_buf_t *buf), (buf), {
 		       /* We cannot call abort() here.  */
 		       INTERNAL_SYSCALL_DECL (err);

+ 142 - 35
libpthread/nptl/init.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2008, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include <assert.h>
+#include <errno.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdlib.h>
@@ -29,49 +30,46 @@
 #include <ldsodefs.h>
 #include <tls.h>
 #include <fork.h>
+#include <version.h>
 #include <smp.h>
 #include <lowlevellock.h>
-#include <version.h>
-
-
-#ifndef __NR_set_tid_address
-/* XXX For the time being...  Once we can rely on the kernel headers
-   having the definition remove these lines.  */
-#if defined __s390__
-# define __NR_set_tid_address	252
-#elif defined __ia64__
-# define __NR_set_tid_address	1233
-#elif defined __i386__
-# define __NR_set_tid_address	258
-#elif defined __x86_64__
-# define __NR_set_tid_address	218
-#elif defined __powerpc__
-# define __NR_set_tid_address	232
-#elif defined __sparc__
-# define __NR_set_tid_address	166
-#else
-# error "define __NR_set_tid_address"
-#endif
-#endif
+#include <bits/kernel-features.h>
 
 
 /* Size and alignment of static TLS block.  */
 size_t __static_tls_size;
 size_t __static_tls_align_m1;
 
+#ifndef __ASSUME_SET_ROBUST_LIST
+/* Negative if we do not have the system call and we can use it.  */
+int __set_robust_list_avail;
+# define set_robust_list_not_avail() \
+  __set_robust_list_avail = -1
+#else
+# define set_robust_list_not_avail() do { } while (0)
+#endif
+
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+/* Nonzero if we do not have FUTEX_CLOCK_REALTIME.  */
+int __have_futex_clock_realtime;
+# define __set_futex_clock_realtime() \
+  __have_futex_clock_realtime = 1
+#else
+#define __set_futex_clock_realtime() do { } while (0)
+#endif
+
 /* Version of the library, used in libthread_db to detect mismatches.  */
 static const char nptl_version[] __attribute_used__ = VERSION;
 
 
-#if defined USE_TLS && !defined SHARED
+#ifndef SHARED
 extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
 #endif
 
-int
-__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact);
+#ifdef SHARED
+static void nptl_freeres (void);
 
 
-#ifdef SHARED
 static const struct pthread_functions pthread_functions =
   {
     .ptr_pthread_attr_destroy = __pthread_attr_destroy,
@@ -98,10 +96,10 @@ static const struct pthread_functions pthread_functions =
     .ptr___pthread_exit = __pthread_exit,
     .ptr_pthread_getschedparam = __pthread_getschedparam,
     .ptr_pthread_setschedparam = __pthread_setschedparam,
-    .ptr_pthread_mutex_destroy = __pthread_mutex_destroy,
-    .ptr_pthread_mutex_init = __pthread_mutex_init,
-    .ptr_pthread_mutex_lock = __pthread_mutex_lock,
-    .ptr_pthread_mutex_unlock = __pthread_mutex_unlock,
+    .ptr_pthread_mutex_destroy = INTUSE(__pthread_mutex_destroy),
+    .ptr_pthread_mutex_init = INTUSE(__pthread_mutex_init),
+    .ptr_pthread_mutex_lock = INTUSE(__pthread_mutex_lock),
+    .ptr_pthread_mutex_unlock = INTUSE(__pthread_mutex_unlock),
     .ptr_pthread_self = __pthread_self,
     .ptr_pthread_setcancelstate = __pthread_setcancelstate,
     .ptr_pthread_setcanceltype = __pthread_setcanceltype,
@@ -118,7 +116,9 @@ static const struct pthread_functions pthread_functions =
     .ptr_nthreads = &__nptl_nthreads,
     .ptr___pthread_unwind = &__pthread_unwind,
     .ptr__nptl_deallocate_tsd = __nptl_deallocate_tsd,
-    .ptr__nptl_setxid = __nptl_setxid
+    .ptr__nptl_setxid = __nptl_setxid,
+    /* For now only the stack cache needs to be freed.  */
+    .ptr_freeres = nptl_freeres
   };
 # define ptr_pthread_functions &pthread_functions
 #else
@@ -126,10 +126,30 @@ static const struct pthread_functions pthread_functions =
 #endif
 
 
+#ifdef SHARED
+/* This function is called indirectly from the freeres code in libc.  */
+static void
+__libc_freeres_fn_section
+nptl_freeres (void)
+{
+  __unwind_freeres ();
+  __free_stacks (0);
+}
+#endif
+
+
 /* For asynchronous cancellation we use a signal.  This is the handler.  */
 static void
 sigcancel_handler (int sig, siginfo_t *si, void *ctx)
 {
+#ifdef __ASSUME_CORRECT_SI_PID
+  /* Determine the process ID.  It might be negative if the thread is
+     in the middle of a fork() call.  */
+  pid_t pid = THREAD_GETMEM (THREAD_SELF, pid);
+  if (__builtin_expect (pid < 0, 0))
+    pid = -pid;
+#endif
+
   /* Safety check.  It would be possible to call this function for
      other signals and send a signal from another process.  This is not
      correct and might even be a security problem.  Try to catch as
@@ -138,7 +158,7 @@ sigcancel_handler (int sig, siginfo_t *si, void *ctx)
 #ifdef __ASSUME_CORRECT_SI_PID
       /* Kernels before 2.5.75 stored the thread ID and not the process
 	 ID in si_pid so we skip this test.  */
-      || si->si_pid != THREAD_GETMEM (THREAD_SELF, pid)
+      || si->si_pid != pid
 #endif
       || si->si_code != SI_TKILL)
     return;
@@ -183,6 +203,14 @@ struct xid_command *__xidcmd attribute_hidden;
 static void
 sighandler_setxid (int sig, siginfo_t *si, void *ctx)
 {
+#ifdef __ASSUME_CORRECT_SI_PID
+  /* Determine the process ID.  It might be negative if the thread is
+     in the middle of a fork() call.  */
+  pid_t pid = THREAD_GETMEM (THREAD_SELF, pid);
+  if (__builtin_expect (pid < 0, 0))
+    pid = -pid;
+#endif
+
   /* Safety check.  It would be possible to call this function for
      other signals and send a signal from another process.  This is not
      correct and might even be a security problem.  Try to catch as
@@ -191,7 +219,7 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
 #ifdef __ASSUME_CORRECT_SI_PID
       /* Kernels before 2.5.75 stored the thread ID and not the process
 	 ID in si_pid so we skip this test.  */
-      || si->si_pid != THREAD_GETMEM (THREAD_SELF, pid)
+      || si->si_pid != pid
 #endif
       || si->si_code != SI_TKILL)
     return;
@@ -200,8 +228,23 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
   INTERNAL_SYSCALL_NCS (__xidcmd->syscall_no, err, 3, __xidcmd->id[0],
 			__xidcmd->id[1], __xidcmd->id[2]);
 
+  /* Reset the SETXID flag.  */
+  struct pthread *self = THREAD_SELF;
+  int flags, newval;
+  do
+    {
+      flags = THREAD_GETMEM (self, cancelhandling);
+      newval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
+					  flags & ~SETXID_BITMASK, flags);
+    }
+  while (flags != newval);
+
+  /* And release the futex.  */
+  self->setxid_futex = 1;
+  lll_futex_wake (&self->setxid_futex, 1, LLL_PRIVATE);
+
   if (atomic_decrement_val (&__xidcmd->cntr) == 0)
-    lll_futex_wake (&__xidcmd->cntr, 1);
+    lll_futex_wake (&__xidcmd->cntr, 1, LLL_PRIVATE);
 }
 
 
@@ -210,6 +253,9 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
 extern void **__libc_dl_error_tsd (void) __attribute__ ((const));
 
 
+/* This can be set by the debugger before initialization is complete.  */
+static bool __nptl_initial_report_events __attribute_used__;
+
 void
 __pthread_initialize_minimal_internal (void)
 {
@@ -237,6 +283,55 @@ __pthread_initialize_minimal_internal (void)
   THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
 #endif
 
+  /* Initialize the robust mutex data.  */
+#ifdef __PTHREAD_MUTEX_HAVE_PREV
+  pd->robust_prev = &pd->robust_head;
+#endif
+  pd->robust_head.list = &pd->robust_head;
+#ifdef __NR_set_robust_list
+  pd->robust_head.futex_offset = (offsetof (pthread_mutex_t, __data.__lock)
+				  - offsetof (pthread_mutex_t,
+					      __data.__list.__next));
+  int res = INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
+			      sizeof (struct robust_list_head));
+  if (INTERNAL_SYSCALL_ERROR_P (res, err))
+#endif
+    set_robust_list_not_avail ();
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+  /* Private futexes are always used (at least internally) so that
+     doing the test once this early is beneficial.  */
+  {
+    int word = 0;
+    word = INTERNAL_SYSCALL (futex, err, 3, &word,
+			    FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1);
+    if (!INTERNAL_SYSCALL_ERROR_P (word, err))
+      THREAD_SETMEM (pd, header.private_futex, FUTEX_PRIVATE_FLAG);
+  }
+
+  /* Private futexes have been introduced earlier than the
+     FUTEX_CLOCK_REALTIME flag.  We don't have to run the test if we
+     know the former are not supported.  This also means we know the
+     kernel will return ENOSYS for unknown operations.  */
+  if (THREAD_GETMEM (pd, header.private_futex) != 0)
+#endif
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+    {
+      int word = 0;
+      /* NB: the syscall actually takes six parameters.  The last is the
+	 bit mask.  But since we will not actually wait at all the value
+	 is irrelevant.  Given that passing six parameters is difficult
+	 on some architectures we just pass whatever random value the
+	 calling convention calls for to the kernel.  It causes no harm.  */
+      word = INTERNAL_SYSCALL (futex, err, 5, &word,
+			       FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME
+			       | FUTEX_PRIVATE_FLAG, 1, NULL, 0);
+      assert (INTERNAL_SYSCALL_ERROR_P (word, err));
+      if (INTERNAL_SYSCALL_ERRNO (word, err) != ENOSYS)
+	__set_futex_clock_realtime ();
+    }
+#endif
+
   /* Set initial thread's stack block from 0 up to __libc_stack_end.
      It will be bigger than it actually is, but for unwind.c/pt-longjmp.c
      purposes this is good enough.  */
@@ -246,6 +341,9 @@ __pthread_initialize_minimal_internal (void)
   INIT_LIST_HEAD (&__stack_user);
   list_add (&pd->list, &__stack_user);
 
+  /* Before initializing __stack_user, the debugger could not find us and
+     had to set __nptl_initial_report_events.  Propagate its setting.  */
+  THREAD_SETMEM (pd, report_events, __nptl_initial_report_events);
 
   /* Install the cancellation signal handler.  If for some reason we
      cannot install the handler we do not abort.  Maybe we should, but
@@ -311,6 +409,15 @@ __pthread_initialize_minimal_internal (void)
   /* Transfer the old value from the dynamic linker's internal location.  */
   *__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
   GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
+
+  /* Make __rtld_lock_{,un}lock_recursive use pthread_mutex_{,un}lock,
+     keep the lock count from the ld.so implementation.  */
+  GL(dl_rtld_lock_recursive) = (void *) INTUSE (__pthread_mutex_lock);
+  GL(dl_rtld_unlock_recursive) = (void *) INTUSE (__pthread_mutex_unlock);
+  unsigned int rtld_lock_count = GL(dl_load_lock).mutex.__data.__count;
+  GL(dl_load_lock).mutex.__data.__count = 0;
+  while (rtld_lock_count-- > 0)
+    INTUSE (__pthread_mutex_lock) (&GL(dl_load_lock).mutex);
 #endif
 
   GL(dl_init_static_tls) = &__pthread_init_static_tls;

+ 4 - 95
libpthread/nptl/libc-cancellation.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -17,100 +17,9 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <setjmp.h>
-#include <stdlib.h>
 #include "pthreadP.h"
-#include "atomic.h"
-#include <bits/libc-lock.h>
 
 
-#ifndef NOT_IN_libc
-
-/* The next two functions are similar to pthread_setcanceltype() but
-   more specialized for the use in the cancelable functions like write().
-   They do not need to check parameters etc.  */
-int
-attribute_hidden
-__libc_enable_asynccancel (void)
-{
-  struct pthread *self = THREAD_SELF;
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-
-  while (1)
-    {
-      int newval = oldval | CANCELTYPE_BITMASK;
-
-      if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0))
-	{
-	  /* If we are already exiting or if PTHREAD_CANCEL_DISABLED,
-	     stop right here.  */
-	  if ((oldval & (EXITING_BITMASK | CANCELSTATE_BITMASK)) != 0)
-	    break;
-
-	  int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
-						  newval, oldval);
-	  if (__builtin_expect (curval != oldval, 0))
-	    {
-	      /* Somebody else modified the word, try again.  */
-	      oldval = curval;
-	      continue;
-	    }
-
-	  THREAD_SETMEM (self, result, PTHREAD_CANCELED);
-
-	  __do_cancel ();
-
-	  /* NOTREACHED */
-	}
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (__builtin_expect (curval == oldval, 1))
-	break;
-
-      /* Prepare the next round.  */
-      oldval = curval;
-    }
-
-  return oldval;
-}
-
-
-void
-internal_function attribute_hidden
-__libc_disable_asynccancel (int oldtype)
-{
-  /* If asynchronous cancellation was enabled before we do not have
-     anything to do.  */
-  if (oldtype & CANCELTYPE_BITMASK)
-    return;
-
-  struct pthread *self = THREAD_SELF;
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-
-  while (1)
-    {
-      int newval = oldval & ~CANCELTYPE_BITMASK;
-
-      if (newval == oldval)
-	break;
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (__builtin_expect (curval == oldval, 1))
-	break;
-
-      /* Prepare the next round.  */
-      oldval = curval;
-    }
-}
-
-
-void
-__libc_cleanup_routine (struct __pthread_cleanup_frame *f)
-{
-  if (f->__do_it)
-    f->__cancel_routine (f->__cancel_arg);
-}
-
-#endif
+#define __pthread_enable_asynccancel __libc_enable_asynccancel
+#define __pthread_disable_asynccancel __libc_disable_asynccancel
+#include "cancellation.c"

+ 2 - 2
libpthread/nptl/pt-cleanup.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 <setjmp.h>
 #include <stdlib.h>
 #include "pthreadP.h"
-#include "jmpbuf-unwind.h"
+#include <jmpbuf-unwind.h>
 
 void
 __pthread_cleanup_upto (__jmp_buf target, char *targetframe)

+ 1 - 1
libpthread/nptl/pt-system.c

@@ -22,10 +22,10 @@
 #include <sysdep.h>
 #include "pthreadP.h"
 
-
 extern __typeof(system) __libc_system;
 #include <system.c>
 
+
 int
 system (const char *line)
 {

+ 1 - 0
libpthread/nptl/pthread-errnos.sym

@@ -8,5 +8,6 @@ EDEADLK		EDEADLK
 EINTR		EINTR
 EINVAL		EINVAL
 ENOSYS		ENOSYS
+EOVERFLOW	EOVERFLOW
 ETIMEDOUT	ETIMEDOUT
 EWOULDBLOCK	EWOULDBLOCK

+ 139 - 13
libpthread/nptl/pthreadP.h

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -31,6 +31,7 @@
 #include <internaltypes.h>
 #include <pthread-functions.h>
 #include <atomic.h>
+#include <bits/kernel-features.h>
 
 
 /* Atomic operations on TLS memory.  */
@@ -51,6 +52,99 @@
 #endif
 
 
+/* Magic cookie representing robust mutex with dead owner.  */
+#define PTHREAD_MUTEX_INCONSISTENT	INT_MAX
+/* Magic cookie representing not recoverable robust mutex.  */
+#define PTHREAD_MUTEX_NOTRECOVERABLE	(INT_MAX - 1)
+
+
+/* Internal mutex type value.  */
+enum
+{
+  PTHREAD_MUTEX_KIND_MASK_NP = 3,
+  PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16,
+  PTHREAD_MUTEX_ROBUST_RECURSIVE_NP
+  = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_RECURSIVE_NP,
+  PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP
+  = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
+  PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP
+  = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
+  PTHREAD_MUTEX_PRIO_INHERIT_NP = 32,
+  PTHREAD_MUTEX_PI_NORMAL_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_NORMAL,
+  PTHREAD_MUTEX_PI_RECURSIVE_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_RECURSIVE_NP,
+  PTHREAD_MUTEX_PI_ERRORCHECK_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
+  PTHREAD_MUTEX_PI_ADAPTIVE_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
+  PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NORMAL_NP,
+  PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_RECURSIVE_NP,
+  PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP,
+  PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP,
+  PTHREAD_MUTEX_PRIO_PROTECT_NP = 64,
+  PTHREAD_MUTEX_PP_NORMAL_NP
+  = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_NORMAL,
+  PTHREAD_MUTEX_PP_RECURSIVE_NP
+  = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_RECURSIVE_NP,
+  PTHREAD_MUTEX_PP_ERRORCHECK_NP
+  = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
+  PTHREAD_MUTEX_PP_ADAPTIVE_NP
+  = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ADAPTIVE_NP
+};
+#define PTHREAD_MUTEX_PSHARED_BIT 128
+
+#define PTHREAD_MUTEX_TYPE(m) \
+  ((m)->__data.__kind & 127)
+
+#if LLL_PRIVATE == 0 && LLL_SHARED == 128
+# define PTHREAD_MUTEX_PSHARED(m) \
+  ((m)->__data.__kind & 128)
+#else
+# define PTHREAD_MUTEX_PSHARED(m) \
+  (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE)
+#endif
+
+/* The kernel when waking robust mutexes on exit never uses
+   FUTEX_PRIVATE_FLAG FUTEX_WAKE.  */
+#define PTHREAD_ROBUST_MUTEX_PSHARED(m) LLL_SHARED
+
+/* Ceiling in __data.__lock.  __data.__lock is signed, so don't
+   use the MSB bit in there, but in the mask also include that bit,
+   so that the compiler can optimize & PTHREAD_MUTEX_PRIO_CEILING_MASK
+   masking if the value is then shifted down by
+   PTHREAD_MUTEX_PRIO_CEILING_SHIFT.  */
+#define PTHREAD_MUTEX_PRIO_CEILING_SHIFT	19
+#define PTHREAD_MUTEX_PRIO_CEILING_MASK		0xfff80000
+
+
+/* Flags in mutex attr.  */
+#define PTHREAD_MUTEXATTR_PROTOCOL_SHIFT	28
+#define PTHREAD_MUTEXATTR_PROTOCOL_MASK		0x30000000
+#define PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT	12
+#define PTHREAD_MUTEXATTR_PRIO_CEILING_MASK	0x00fff000
+#define PTHREAD_MUTEXATTR_FLAG_ROBUST		0x40000000
+#define PTHREAD_MUTEXATTR_FLAG_PSHARED		0x80000000
+#define PTHREAD_MUTEXATTR_FLAG_BITS \
+  (PTHREAD_MUTEXATTR_FLAG_ROBUST | PTHREAD_MUTEXATTR_FLAG_PSHARED \
+   | PTHREAD_MUTEXATTR_PROTOCOL_MASK | PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
+
+
+/* Check whether rwlock prefers readers.   */
+#define PTHREAD_RWLOCK_PREFER_READER_P(rwlock) \
+  ((rwlock)->__data.__flags == 0)
+
+
+/* Bits used in robust mutex implementation.  */
+#define FUTEX_WAITERS		0x80000000
+#define FUTEX_OWNER_DIED	0x40000000
+#define FUTEX_TID_MASK		0x3fffffff
+
+
 /* Internal variables.  */
 
 
@@ -70,7 +164,7 @@ hidden_proto (__stack_user)
 
 /* Attribute handling.  */
 extern struct pthread_attr *__attr_list attribute_hidden;
-extern lll_lock_t __attr_list_lock attribute_hidden;
+extern int __attr_list_lock attribute_hidden;
 
 /* First available RT signal.  */
 extern int __current_sigrtmin attribute_hidden;
@@ -87,6 +181,19 @@ hidden_proto (__pthread_keys)
 /* Number of threads running.  */
 extern unsigned int __nptl_nthreads attribute_hidden;
 
+#ifndef __ASSUME_SET_ROBUST_LIST
+/* Negative if we do not have the system call and we can use it.  */
+extern int __set_robust_list_avail attribute_hidden;
+#endif
+
+/* Thread Priority Protection.  */
+extern int __sched_fifo_min_prio attribute_hidden;
+extern int __sched_fifo_max_prio attribute_hidden;
+extern void __init_sched_fifo_prio (void) attribute_hidden;
+extern int __pthread_tpp_change_priority (int prev_prio, int new_prio)
+     attribute_hidden;
+extern int __pthread_current_priority (void) attribute_hidden;
+
 /* The library can run in debugging mode where it performs a lot more
    tests.  */
 extern int __pthread_debug attribute_hidden;
@@ -108,8 +215,8 @@ extern int __pthread_debug attribute_hidden;
 /* Cancellation test.  */
 #define CANCELLATION_P(self) \
   do {									      \
-    int _cancelhandling = THREAD_GETMEM (self, cancelhandling);		      \
-    if (CANCEL_ENABLED_AND_CANCELED (_cancelhandling))			      \
+    int cancelhandling = THREAD_GETMEM (self, cancelhandling);		      \
+    if (CANCEL_ENABLED_AND_CANCELED (cancelhandling))			      \
       {									      \
 	THREAD_SETMEM (self, result, PTHREAD_CANCELED);			      \
 	__do_cancel ();							      \
@@ -140,6 +247,7 @@ hidden_proto (__pthread_register_cancel)
 hidden_proto (__pthread_unregister_cancel)
 # ifdef SHARED
 extern void attribute_hidden pthread_cancel_init (void);
+extern void __unwind_freeres (void);
 # endif
 #endif
 
@@ -174,22 +282,22 @@ __do_cancel (void)
 # define LIBC_CANCEL_RESET(oldtype) \
   __libc_disable_asynccancel (oldtype)
 # define LIBC_CANCEL_HANDLED() \
-  __asm (".globl " __USER_LABEL_PREFIX__ "__libc_enable_asynccancel"); \
-  __asm (".globl " __USER_LABEL_PREFIX__ "__libc_disable_asynccancel")
+  __asm__ (".globl " __USER_LABEL_PREFIX__ "__libc_enable_asynccancel"); \
+  __asm__ (".globl " __USER_LABEL_PREFIX__ "__libc_disable_asynccancel")
 #elif defined NOT_IN_libc && defined IS_IN_libpthread
 # define LIBC_CANCEL_ASYNC() CANCEL_ASYNC ()
 # define LIBC_CANCEL_RESET(val) CANCEL_RESET (val)
 # define LIBC_CANCEL_HANDLED() \
-  __asm (".globl " __USER_LABEL_PREFIX__ "__pthread_enable_asynccancel"); \
-  __asm (".globl " __USER_LABEL_PREFIX__ "__pthread_disable_asynccancel")
+  __asm__ (".globl " __USER_LABEL_PREFIX__ "__pthread_enable_asynccancel"); \
+  __asm__ (".globl " __USER_LABEL_PREFIX__ "__pthread_disable_asynccancel")
 #elif defined NOT_IN_libc && defined IS_IN_librt
 # define LIBC_CANCEL_ASYNC() \
   __librt_enable_asynccancel ()
 # define LIBC_CANCEL_RESET(val) \
   __librt_disable_asynccancel (val)
 # define LIBC_CANCEL_HANDLED() \
-  __asm (".globl " __USER_LABEL_PREFIX__ "__librt_enable_asynccancel"); \
-  __asm (".globl " __USER_LABEL_PREFIX__ "__librt_disable_asynccancel")
+  __asm__ (".globl " __USER_LABEL_PREFIX__ "__librt_enable_asynccancel"); \
+  __asm__ (".globl " __USER_LABEL_PREFIX__ "__librt_disable_asynccancel")
 #else
 # define LIBC_CANCEL_ASYNC()	0 /* Just a dummy value.  */
 # define LIBC_CANCEL_RESET(val)	((void)(val)) /* Nothing, but evaluate it.  */
@@ -263,11 +371,13 @@ hidden_proto (__nptl_death_event)
 #ifdef TLS_MULTIPLE_THREADS_IN_TCB
 extern void __libc_pthread_init (unsigned long int *ptr,
 				 void (*reclaim) (void),
-				 const struct pthread_functions *functions);
+				 const struct pthread_functions *functions)
+     internal_function;
 #else
 extern int *__libc_pthread_init (unsigned long int *ptr,
 				 void (*reclaim) (void),
-				 const struct pthread_functions *functions);
+				 const struct pthread_functions *functions)
+     internal_function;
 
 /* Variable set to a nonzero value if more than one thread runs or ran.  */
 extern int __pthread_multiple_threads attribute_hidden;
@@ -307,6 +417,7 @@ extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
 extern int __pthread_mutex_lock_internal (pthread_mutex_t *__mutex)
      attribute_hidden;
 extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex);
+extern void __pthread_mutex_cond_lock_adjust (pthread_mutex_t *__mutex);
 extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
 extern int __pthread_mutex_unlock_internal (pthread_mutex_t *__mutex)
      attribute_hidden;
@@ -454,10 +565,25 @@ extern void __nptl_deallocate_tsd (void) attribute_hidden;
 
 extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
 
+extern void __free_stacks (size_t limit) attribute_hidden;
+
+extern void __wait_lookup_done (void) attribute_hidden;
+
 #ifdef SHARED
 # define PTHREAD_STATIC_FN_REQUIRE(name)
 #else
-# define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name);
+# define PTHREAD_STATIC_FN_REQUIRE(name) __asm__ (".globl " #name);
+#endif
+
+
+#ifndef __NR_set_robust_list
+/* XXX For the time being...  Once we can rely on the kernel headers
+   having the definition remove these lines.  */
+# if defined __i386__
+#  define __NR_set_robust_list  311
+# elif defined __x86_64__
+#  define __NR_set_robust_list  273
+# endif
 #endif
 
 #endif	/* pthreadP.h */

+ 4 - 3
libpthread/nptl/pthread_atfork.c

@@ -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.
 
@@ -38,7 +38,8 @@
 #include <fork.h>
 
 /* This is defined by newer gcc version unique for each module.  */
-extern void *__dso_handle __attribute__ ((__weak__));
+extern void *__dso_handle __attribute__ ((__weak__,
+					  __visibility__ ("hidden")));
 
 
 /* Hide the symbol so that no definition but the one locally in the
@@ -52,4 +53,4 @@ __pthread_atfork (
   return __register_atfork (prepare, parent, child,
 			    &__dso_handle == NULL ? NULL : __dso_handle);
 }
-strong_alias(__pthread_atfork, pthread_atfork)
+strong_alias (__pthread_atfork, pthread_atfork)

+ 2 - 1
libpthread/nptl/pthread_attr_destroy.c

@@ -24,7 +24,8 @@
 #include "pthreadP.h"
 
 int
-__pthread_attr_destroy (pthread_attr_t *attr)
+__pthread_attr_destroy (
+     pthread_attr_t *attr)
 {
   struct pthread_attr *iattr;
 

+ 3 - 1
libpthread/nptl/pthread_attr_getdetachstate.c

@@ -22,7 +22,9 @@
 
 
 int
-__pthread_attr_getdetachstate (const pthread_attr_t *attr, int *detachstate)
+__pthread_attr_getdetachstate (
+     const pthread_attr_t *attr,
+     int *detachstate)
 {
   struct pthread_attr *iattr;
 

+ 4 - 3
libpthread/nptl/pthread_attr_init.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -25,11 +25,12 @@
 
 
 struct pthread_attr *__attr_list;
-lll_lock_t __attr_list_lock = LLL_LOCK_INITIALIZER;
+int __attr_list_lock = LLL_LOCK_INITIALIZER;
 
 
 int
-__pthread_attr_init_2_1 (pthread_attr_t *attr)
+__pthread_attr_init_2_1 (
+     pthread_attr_t *attr)
 {
   struct pthread_attr *iattr;
 

+ 7 - 1
libpthread/nptl/pthread_attr_setschedparam.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2004, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -31,6 +31,12 @@ __pthread_attr_setschedparam (
   assert (sizeof (*attr) >= sizeof (struct pthread_attr));
   struct pthread_attr *iattr = (struct pthread_attr *) attr;
 
+  int min = sched_get_priority_min (iattr->schedpolicy);
+  int max = sched_get_priority_max (iattr->schedpolicy);
+  if (min == -1 || max == -1
+      || param->sched_priority > max || param->sched_priority < min)
+    return EINVAL;
+
   /* Copy the new values.  */
   memcpy (&iattr->schedparam, param, sizeof (struct sched_param));
 

+ 1 - 1
libpthread/nptl/pthread_attr_setstack.c

@@ -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.
 

+ 5 - 4
libpthread/nptl/pthread_barrier_destroy.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -23,21 +23,22 @@
 
 
 int
-pthread_barrier_destroy (pthread_barrier_t *barrier)
+pthread_barrier_destroy (
+     pthread_barrier_t *barrier)
 {
   struct pthread_barrier *ibarrier;
   int result = EBUSY;
 
   ibarrier = (struct pthread_barrier *) barrier;
 
-  lll_lock (ibarrier->lock);
+  lll_lock (ibarrier->lock, ibarrier->private ^ FUTEX_PRIVATE_FLAG);
 
   if (__builtin_expect (ibarrier->left == ibarrier->init_count, 1))
     /* The barrier is not used anymore.  */
     result = 0;
   else
     /* Still used, return with an error.  */
-    lll_unlock (ibarrier->lock);
+    lll_unlock (ibarrier->lock, ibarrier->private ^ FUTEX_PRIVATE_FLAG);
 
   return result;
 }

+ 25 - 11
libpthread/nptl/pthread_barrier_init.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,6 +20,13 @@
 #include <errno.h>
 #include "pthreadP.h"
 #include <lowlevellock.h>
+#include <bits/kernel-features.h>
+
+
+static const struct pthread_barrierattr default_attr =
+  {
+    .pshared = PTHREAD_PROCESS_PRIVATE
+  };
 
 
 int
@@ -33,17 +40,15 @@ pthread_barrier_init (
   if (__builtin_expect (count == 0, 0))
     return EINVAL;
 
-  if (attr != NULL)
-    {
-      struct pthread_barrierattr *iattr;
-
-      iattr = (struct pthread_barrierattr *) attr;
+  const struct pthread_barrierattr *iattr
+    = (attr != NULL
+       ? iattr = (struct pthread_barrierattr *) attr
+       : &default_attr);
 
-      if (iattr->pshared != PTHREAD_PROCESS_PRIVATE
-	  && __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0))
-	/* Invalid attribute.  */
-	return EINVAL;
-    }
+  if (iattr->pshared != PTHREAD_PROCESS_PRIVATE
+      && __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0))
+    /* Invalid attribute.  */
+    return EINVAL;
 
   ibarrier = (struct pthread_barrier *) barrier;
 
@@ -53,5 +58,14 @@ pthread_barrier_init (
   ibarrier->init_count = count;
   ibarrier->curr_event = 0;
 
+#ifdef __ASSUME_PRIVATE_FUTEX
+  ibarrier->private = (iattr->pshared != PTHREAD_PROCESS_PRIVATE
+		       ? 0 : FUTEX_PRIVATE_FLAG);
+#else
+  ibarrier->private = (iattr->pshared != PTHREAD_PROCESS_PRIVATE
+		       ? 0 : THREAD_GETMEM (THREAD_SELF,
+					    header.private_futex));
+#endif
+
   return 0;
 }

+ 8 - 3
libpthread/nptl/pthread_cancel.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -26,7 +26,8 @@
 
 
 int
-pthread_cancel (pthread_t th)
+pthread_cancel (
+     pthread_t th)
 {
   volatile struct pthread *pd = (volatile struct pthread *) th;
 
@@ -43,6 +44,7 @@ pthread_cancel (pthread_t th)
   int newval;
   do
     {
+    again:
       oldval = pd->cancelhandling;
       newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
 
@@ -58,7 +60,10 @@ pthread_cancel (pthread_t th)
       if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
 	{
 	  /* Mark the cancellation as "in progress".  */
-	  atomic_bit_set (&pd->cancelhandling, CANCELING_BIT);
+	  if (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling,
+						    oldval | CANCELING_BITMASK,
+						    oldval))
+	    goto again;
 
 	  /* The cancellation handler will take care of marking the
 	     thread as canceled.  */

+ 34 - 9
libpthread/nptl/pthread_cond_destroy.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -22,16 +22,20 @@
 
 
 int
-__pthread_cond_destroy (pthread_cond_t *cond)
+__pthread_cond_destroy (
+     pthread_cond_t *cond)
 {
+  int pshared = (cond->__data.__mutex == (void *) ~0l)
+		? LLL_SHARED : LLL_PRIVATE;
+
   /* Make sure we are alone.  */
-  lll_mutex_lock (cond->__data.__lock);
+  lll_lock (cond->__data.__lock, pshared);
 
   if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
     {
       /* If there are still some waiters which have not been
 	 woken up, this is an application bug.  */
-      lll_mutex_unlock (cond->__data.__lock);
+      lll_unlock (cond->__data.__lock, pshared);
       return EBUSY;
     }
 
@@ -42,15 +46,36 @@ __pthread_cond_destroy (pthread_cond_t *cond)
      broadcasted, but still are using the pthread_cond_t structure,
      pthread_cond_destroy needs to wait for them.  */
   unsigned int nwaiters = cond->__data.__nwaiters;
-  while (nwaiters >= (1 << COND_CLOCK_BITS))
+
+  if (nwaiters >= (1 << COND_NWAITERS_SHIFT))
     {
-      lll_mutex_unlock (cond->__data.__lock);
+      /* Wake everybody on the associated mutex in case there are
+         threads that have been requeued to it.
+         Without this, pthread_cond_destroy could block potentially
+         for a long time or forever, as it would depend on other
+         thread's using the mutex.
+         When all threads waiting on the mutex are woken up, pthread_cond_wait
+         only waits for threads to acquire and release the internal
+         condvar lock.  */
+      if (cond->__data.__mutex != NULL
+	  && cond->__data.__mutex != (void *) ~0l)
+	{
+	  pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
+	  lll_futex_wake (&mut->__data.__lock, INT_MAX,
+			  PTHREAD_MUTEX_PSHARED (mut));
+	}
+
+      do
+	{
+	  lll_unlock (cond->__data.__lock, pshared);
 
-      lll_futex_wait (&cond->__data.__nwaiters, nwaiters);
+	  lll_futex_wait (&cond->__data.__nwaiters, nwaiters, pshared);
 
-      lll_mutex_lock (cond->__data.__lock);
+	  lll_lock (cond->__data.__lock, pshared);
 
-      nwaiters = cond->__data.__nwaiters;
+	  nwaiters = cond->__data.__nwaiters;
+	}
+      while (nwaiters >= (1 << COND_NWAITERS_SHIFT));
     }
 
   return 0;

+ 6 - 4
libpthread/nptl/pthread_cond_init.c

@@ -1,4 +1,5 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -27,11 +28,12 @@ __pthread_cond_init (
 {
   struct pthread_condattr *icond_attr = (struct pthread_condattr *) cond_attr;
 
-  cond->__data.__lock = LLL_MUTEX_LOCK_INITIALIZER;
+  cond->__data.__lock = LLL_LOCK_INITIALIZER;
   cond->__data.__futex = 0;
   cond->__data.__nwaiters = (icond_attr != NULL
-			     && ((icond_attr->value & (COND_CLOCK_BITS << 1))
-				 >> 1));
+			     ? ((icond_attr->value >> 1)
+				& ((1 << COND_NWAITERS_SHIFT) - 1))
+			     : CLOCK_REALTIME);
   cond->__data.__total_seq = 0;
   cond->__data.__wakeup_seq = 0;
   cond->__data.__woken_seq = 0;

+ 2 - 2
libpthread/nptl/pthread_condattr_getclock.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -26,6 +26,6 @@ pthread_condattr_getclock (
      clockid_t *clock_id)
 {
   *clock_id = (((((const struct pthread_condattr *) attr)->value) >> 1)
-	       & ((1 << COND_CLOCK_BITS) - 1));
+	       & ((1 << COND_NWAITERS_SHIFT) - 1));
   return 0;
 }

+ 4 - 3
libpthread/nptl/pthread_condattr_setclock.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -62,11 +62,12 @@ pthread_condattr_setclock (
     return EINVAL;
 
   /* Make sure the value fits in the bits we reserved.  */
-  assert (clock_id < (1 << COND_CLOCK_BITS));
+  assert (clock_id < (1 << COND_NWAITERS_SHIFT));
 
   int *valuep = &((struct pthread_condattr *) attr)->value;
 
-  *valuep = (*valuep & ~(1 << (COND_CLOCK_BITS + 1)) & ~1) | (clock_id << 1);
+  *valuep = ((*valuep & ~(((1 << COND_NWAITERS_SHIFT) - 1) << 1))
+	     | (clock_id << 1));
 
   return 0;
 }

+ 112 - 10
libpthread/nptl/pthread_create.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007,2008,2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -27,6 +27,7 @@
 #include <atomic.h>
 #include <libc-internal.h>
 #include <resolv.h>
+#include <bits/kernel-features.h>
 
 
 /* Local function to start thread and handle cleanup.  */
@@ -37,10 +38,10 @@ static int start_thread (void *arg);
 int __pthread_debug;
 
 /* Globally enabled events.  */
-static td_thr_events_t __nptl_threads_events;
+static td_thr_events_t __nptl_threads_events __attribute_used__;
 
 /* Pointer to descriptor with the last event.  */
-static struct pthread *__nptl_last_event;
+static struct pthread *__nptl_last_event __attribute_used__;
 
 /* Number of threads running.  */
 unsigned int __nptl_nthreads = 1;
@@ -50,17 +51,18 @@ unsigned int __nptl_nthreads = 1;
 #include "allocatestack.c"
 
 /* Code to create the thread.  */
-#include "createthread.c"
+#include <createthread.c>
 
 
 struct pthread *
 internal_function
-__find_in_stack_list (struct pthread *pd)
+__find_in_stack_list (
+     struct pthread *pd)
 {
   list_t *entry;
   struct pthread *result = NULL;
 
-  lll_lock (stack_cache_lock);
+  lll_lock (stack_cache_lock, LLL_PRIVATE);
 
   list_for_each (entry, &stack_used)
     {
@@ -87,7 +89,7 @@ __find_in_stack_list (struct pthread *pd)
 	  }
       }
 
-  lll_unlock (stack_cache_lock);
+  lll_unlock (stack_cache_lock, LLL_PRIVATE);
 
   return result;
 }
@@ -203,6 +205,15 @@ __free_tcb (struct pthread *pd)
 	   running thread is gone.  */
 	abort ();
 
+      /* Free TPP data.  */
+      if (__builtin_expect (pd->tpp != NULL, 0))
+	{
+	  struct priority_protection_data *tpp = pd->tpp;
+
+	  pd->tpp = NULL;
+	  free (tpp);
+	}
+
       /* Queue the stack memory block for reuse and exit the process.  The
 	 kernel will signal via writing to the address returned by
 	 QUEUE-STACK when the stack is available.  */
@@ -226,6 +237,32 @@ start_thread (void *arg)
   /* Initialize resolver state pointer.  */
   __resp = &pd->res;
 
+#ifdef __NR_set_robust_list
+# ifndef __ASSUME_SET_ROBUST_LIST
+  if (__set_robust_list_avail >= 0)
+# endif
+    {
+      INTERNAL_SYSCALL_DECL (err);
+      /* This call should never fail because the initial call in init.c
+	 succeeded.  */
+      INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
+			sizeof (struct robust_list_head));
+    }
+#endif
+
+  /* If the parent was running cancellation handlers while creating
+     the thread the new thread inherited the signal mask.  Reset the
+     cancellation signal mask.  */
+  if (__builtin_expect (pd->parent_cancelhandling & CANCELING_BITMASK, 0))
+    {
+      INTERNAL_SYSCALL_DECL (err);
+      sigset_t mask;
+      __sigemptyset (&mask);
+      __sigaddset (&mask, SIGCANCEL);
+      (void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &mask,
+			       NULL, _NSIG / 8);
+    }
+
   /* This is where the try/finally block should be created.  For
      compilers without that support we do use setjmp.  */
   struct pthread_unwind_buf unwind_buf;
@@ -246,9 +283,9 @@ start_thread (void *arg)
 	  int oldtype = CANCEL_ASYNC ();
 
 	  /* Get the lock the parent locked to force synchronization.  */
-	  lll_lock (pd->lock);
+	  lll_lock (pd->lock, LLL_PRIVATE);
 	  /* And give it up right away.  */
-	  lll_unlock (pd->lock);
+	  lll_unlock (pd->lock, LLL_PRIVATE);
 
 	  CANCEL_RESET (oldtype);
 	}
@@ -264,6 +301,9 @@ start_thread (void *arg)
   /* Run the destructor for the thread-local data.  */
   __nptl_deallocate_tsd ();
 
+  /* Clean up any state libc stored in thread-local variables.  */
+  __libc_thread_freeres ();
+
   /* If this is the last thread we terminate the process now.  We
      do not notify the debugger, it might just irritate it if there
      is no thread left.  */
@@ -304,10 +344,65 @@ start_thread (void *arg)
      the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE.  */
   atomic_bit_set (&pd->cancelhandling, EXITING_BIT);
 
+#ifndef __ASSUME_SET_ROBUST_LIST
+  /* If this thread has any robust mutexes locked, handle them now.  */
+# if __WORDSIZE == 64
+  void *robust = pd->robust_head.list;
+# else
+  __pthread_slist_t *robust = pd->robust_list.__next;
+# endif
+  /* We let the kernel do the notification if it is able to do so.
+     If we have to do it here there for sure are no PI mutexes involved
+     since the kernel support for them is even more recent.  */
+  if (__set_robust_list_avail < 0
+      && __builtin_expect (robust != (void *) &pd->robust_head, 0))
+    {
+      do
+	{
+	  struct __pthread_mutex_s *this = (struct __pthread_mutex_s *)
+	    ((char *) robust - offsetof (struct __pthread_mutex_s,
+					 __list.__next));
+	  robust = *((void **) robust);
+
+# ifdef __PTHREAD_MUTEX_HAVE_PREV
+	  this->__list.__prev = NULL;
+# endif
+	  this->__list.__next = NULL;
+
+	  lll_robust_dead (this->__lock, /* XYZ */ LLL_SHARED);
+	}
+      while (robust != (void *) &pd->robust_head);
+    }
+#endif
+
+  /* Mark the memory of the stack as usable to the kernel.  We free
+     everything except for the space used for the TCB itself.  */
+  size_t pagesize_m1 = __getpagesize () - 1;
+#ifdef _STACK_GROWS_DOWN
+  char *sp = CURRENT_STACK_FRAME;
+  size_t freesize = (sp - (char *) pd->stackblock) & ~pagesize_m1;
+#else
+# error "to do"
+#endif
+  assert (freesize < pd->stackblock_size);
+  if (freesize > PTHREAD_STACK_MIN)
+    madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
+
   /* If the thread is detached free the TCB.  */
   if (IS_DETACHED (pd))
     /* Free the TCB.  */
     __free_tcb (pd);
+  else if (__builtin_expect (pd->cancelhandling & SETXID_BITMASK, 0))
+    {
+      /* Some other thread might call any of the setXid functions and expect
+	 us to reply.  In this case wait until we did that.  */
+      do
+	lll_futex_wait (&pd->setxid_futex, 0, LLL_PRIVATE);
+      while (pd->cancelhandling & SETXID_BITMASK);
+
+      /* Reset the value so that the stack can be reused.  */
+      pd->setxid_futex = 0;
+    }
 
   /* We cannot call '_exit' here.  '_exit' will terminate the process.
 
@@ -348,7 +443,7 @@ __pthread_create_2_1 (
        accessing far-away memory.  */
     iattr = &default_attr;
 
-  struct pthread *pd = 0;
+  struct pthread *pd = NULL;
   int err = ALLOCATE_STACK (iattr, &pd);
   if (__builtin_expect (err != 0, 0))
     /* Something went wrong.  Maybe a parameter of the attributes is
@@ -398,6 +493,11 @@ __pthread_create_2_1 (
   THREAD_COPY_STACK_GUARD (pd);
 #endif
 
+  /* Copy the pointer guard value.  */
+#ifdef THREAD_COPY_POINTER_GUARD
+  THREAD_COPY_POINTER_GUARD (pd);
+#endif
+
   /* Determine scheduling parameters for the thread.  */
   if (attr != NULL
       && __builtin_expect ((iattr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0, 0)
@@ -468,12 +568,14 @@ weak_alias(__pthread_create_2_1, pthread_create)
 /* If pthread_create is present, libgcc_eh.a and libsupc++.a expects some other POSIX thread
    functions to be present as well.  */
 PTHREAD_STATIC_FN_REQUIRE (pthread_mutex_lock)
+PTHREAD_STATIC_FN_REQUIRE (pthread_mutex_trylock)
 PTHREAD_STATIC_FN_REQUIRE (pthread_mutex_unlock)
 
 PTHREAD_STATIC_FN_REQUIRE (pthread_once)
 PTHREAD_STATIC_FN_REQUIRE (pthread_cancel)
 
 PTHREAD_STATIC_FN_REQUIRE (pthread_key_create)
+PTHREAD_STATIC_FN_REQUIRE (pthread_key_delete)
 PTHREAD_STATIC_FN_REQUIRE (pthread_setspecific)
 PTHREAD_STATIC_FN_REQUIRE (pthread_getspecific)
 

+ 48 - 40
libpthread/nptl/pthread_getattr_np.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -39,7 +39,7 @@ pthread_getattr_np (
   struct pthread_attr *iattr = (struct pthread_attr *) attr;
   int ret = 0;
 
-  lll_lock (thread->lock);
+  lll_lock (thread->lock, LLL_PRIVATE);
 
   /* The thread library is responsible for keeping the values in the
      thread desriptor up-to-date in case the user changes them.  */
@@ -79,51 +79,55 @@ pthread_getattr_np (
       if (fp == NULL)
 	ret = errno;
       /* We need the limit of the stack in any case.  */
-      else if (getrlimit (RLIMIT_STACK, &rl) != 0)
-	ret = errno;
       else
 	{
-	  /* We need no locking.  */
-	  __fsetlocking (fp, FSETLOCKING_BYCALLER);
+	  if (getrlimit (RLIMIT_STACK, &rl) != 0)
+	    ret = errno;
+	  else
+	    {
+	      /* We need no locking.  */
+	      __fsetlocking (fp, FSETLOCKING_BYCALLER);
 
-	  /* Until we found an entry (which should always be the case)
-	     mark the result as a failure.  */
-	  ret = ENOENT;
+	      /* Until we found an entry (which should always be the case)
+		 mark the result as a failure.  */
+	      ret = ENOENT;
 
-	  char *line = NULL;
-	  size_t linelen = 0;
-	  uintptr_t last_to = 0;
+	      char *line = NULL;
+	      size_t linelen = 0;
+	      uintptr_t last_to = 0;
 
-	  while (! feof_unlocked (fp))
-	    {
-	      if (getdelim (&line, &linelen, '\n', fp) <= 0)
-		break;
-
-	      uintptr_t from;
-	      uintptr_t to;
-	      if (sscanf (line, "%" SCNxPTR "-%" SCNxPTR, &from, &to) != 2)
-		continue;
-	      if (from <= (uintptr_t) __libc_stack_end
-		  && (uintptr_t) __libc_stack_end < to)
+	      while (! feof_unlocked (fp))
 		{
-		  /* Found the entry.  Now we have the info we need.  */
-		  iattr->stacksize = rl.rlim_cur;
-		  iattr->stackaddr = (void *) to;
-
-		  /* The limit might be too high.  */
-		  if ((size_t) iattr->stacksize
-		      > (size_t) iattr->stackaddr - last_to)
-		    iattr->stacksize = (size_t) iattr->stackaddr - last_to;
-
-		  /* We succeed and no need to look further.  */
-		  ret = 0;
-		  break;
+		  if (__getdelim (&line, &linelen, '\n', fp) <= 0)
+		    break;
+
+		  uintptr_t from;
+		  uintptr_t to;
+		  if (sscanf (line, "%" SCNxPTR "-%" SCNxPTR, &from, &to) != 2)
+		    continue;
+		  if (from <= (uintptr_t) __libc_stack_end
+		      && (uintptr_t) __libc_stack_end < to)
+		    {
+		      /* Found the entry.  Now we have the info we need.  */
+		      iattr->stacksize = rl.rlim_cur;
+		      iattr->stackaddr = (void *) to;
+
+		      /* The limit might be too high.  */
+		      if ((size_t) iattr->stacksize
+			  > (size_t) iattr->stackaddr - last_to)
+			iattr->stacksize = (size_t) iattr->stackaddr - last_to;
+
+		      /* We succeed and no need to look further.  */
+		      ret = 0;
+		      break;
+		    }
+		  last_to = to;
 		}
-	      last_to = to;
+
+	      free (line);
 	    }
 
 	  fclose (fp);
-	  free (line);
 	}
     }
 
@@ -160,12 +164,16 @@ pthread_getattr_np (
 	{
 	  free (cpuset);
 	  if (ret == ENOSYS)
-	    /* There is no such functionality.  */
-	    ret = 0;
+	    {
+	      /* There is no such functionality.  */
+	      ret = 0;
+	      iattr->cpuset = NULL;
+	      iattr->cpusetsize = 0;
+	    }
 	}
     }
 
-  lll_unlock (thread->lock);
+  lll_unlock (thread->lock, LLL_PRIVATE);
 
   return ret;
 }

+ 6 - 6
libpthread/nptl/pthread_getschedparam.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -25,9 +25,9 @@
 
 int
 __pthread_getschedparam (
-        pthread_t threadid,
-        int *policy,
-        struct sched_param *param)
+     pthread_t threadid,
+     int *policy,
+     struct sched_param *param)
 {
   struct pthread *pd = (struct pthread *) threadid;
 
@@ -38,7 +38,7 @@ __pthread_getschedparam (
 
   int result = 0;
 
-  lll_lock (pd->lock);
+  lll_lock (pd->lock, LLL_PRIVATE);
 
   /* The library is responsible for maintaining the values at all
      times.  If the user uses a interface other than
@@ -68,7 +68,7 @@ __pthread_getschedparam (
       memcpy (param, &pd->schedparam, sizeof (struct sched_param));
     }
 
-  lll_unlock (pd->lock);
+  lll_unlock (pd->lock, LLL_PRIVATE);
 
   return result;
 }

+ 46 - 38
libpthread/nptl/pthread_join.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.
 
@@ -20,21 +20,26 @@
 #include <errno.h>
 #include <stdlib.h>
 
-#include "atomic.h"
+#include <atomic.h>
 #include "pthreadP.h"
 
 
 static void
 cleanup (void *arg)
 {
-  *(void **) arg = NULL;
+  /* If we already changed the waiter ID, reset it.  The call cannot
+     fail for any reason but the thread not having done that yet so
+     there is no reason for a loop.  */
+  (void) atomic_compare_and_exchange_bool_acq ((struct pthread **) arg, NULL,
+					       THREAD_SELF);
 }
 
 
 int
-pthread_join (pthread_t threadid, void **thread_return)
+pthread_join (
+     pthread_t threadid,
+     void **thread_return)
 {
-  struct pthread *self;
   struct pthread *pd = (struct pthread *) threadid;
 
   /* Make sure the descriptor is valid.  */
@@ -47,12 +52,23 @@ pthread_join (pthread_t threadid, void **thread_return)
     /* We cannot wait for the thread.  */
     return EINVAL;
 
-  self = THREAD_SELF;
-  if (pd == self
-      || (self->joinid == pd
-	  && (pd->cancelhandling
-	      & (CANCELING_BITMASK | CANCELED_BITMASK | EXITING_BITMASK
-		 | TERMINATED_BITMASK)) == 0))
+  struct pthread *self = THREAD_SELF;
+  int result = 0;
+
+  /* During the wait we change to asynchronous cancellation.  If we
+     are canceled the thread we are waiting for must be marked as
+     un-wait-ed for again.  */
+  pthread_cleanup_push (cleanup, &pd->joinid);
+
+  /* Switch to asynchronous cancellation.  */
+  int oldtype = CANCEL_ASYNC ();
+
+  if ((pd == self
+       || (self->joinid == pd
+	   && (pd->cancelhandling
+	       & (CANCELING_BITMASK | CANCELED_BITMASK | EXITING_BITMASK
+		  | TERMINATED_BITMASK)) == 0))
+      && !CANCEL_ENABLED_AND_CANCELED (self->cancelhandling))
     /* This is a deadlock situation.  The threads are waiting for each
        other to finish.  Note that this is a "may" error.  To be 100%
        sure we catch this error we would have to lock the data
@@ -60,28 +76,17 @@ pthread_join (pthread_t threadid, void **thread_return)
        two threads are really caught in this situation they will
        deadlock.  It is the programmer's problem to figure this
        out.  */
-    return EDEADLK;
-
+    result = EDEADLK;
   /* Wait for the thread to finish.  If it is already locked something
      is wrong.  There can only be one waiter.  */
-  if (__builtin_expect (atomic_compare_and_exchange_bool_acq (&pd->joinid,
-							      self,
-							      NULL), 0))
+  else if (__builtin_expect (atomic_compare_and_exchange_bool_acq (&pd->joinid,
+								   self,
+								   NULL), 0))
     /* There is already somebody waiting for the thread.  */
-    return EINVAL;
-
-
-  /* During the wait we change to asynchronous cancellation.  If we
-     are cancelled the thread we are waiting for must be marked as
-     un-wait-ed for again.  */
-  pthread_cleanup_push (cleanup, &pd->joinid);
-
-  /* Switch to asynchronous cancellation.  */
-  int oldtype = CANCEL_ASYNC ();
-
-
-  /* Wait for the child.  */
-  lll_wait_tid (pd->tid);
+    result = EINVAL;
+  else
+    /* Wait for the child.  */
+    lll_wait_tid (pd->tid);
 
 
   /* Restore cancellation mode.  */
@@ -91,16 +96,19 @@ pthread_join (pthread_t threadid, void **thread_return)
   pthread_cleanup_pop (0);
 
 
-  /* We mark the thread as terminated and as joined.  */
-  pd->tid = -1;
+  if (__builtin_expect (result == 0, 1))
+    {
+      /* We mark the thread as terminated and as joined.  */
+      pd->tid = -1;
 
-  /* Store the return value if the caller is interested.  */
-  if (thread_return != NULL)
-    *thread_return = pd->result;
+      /* Store the return value if the caller is interested.  */
+      if (thread_return != NULL)
+	*thread_return = pd->result;
 
 
-  /* Free the TCB.  */
-  __free_tcb (pd);
+      /* Free the TCB.  */
+      __free_tcb (pd);
+    }
 
-  return 0;
+  return result;
 }

+ 23 - 32
libpthread/nptl/pthread_key_create.c

@@ -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.
 
@@ -19,45 +19,36 @@
 
 #include <errno.h>
 #include "pthreadP.h"
+#include <atomic.h>
 
 
-/* Internal mutex for __pthread_keys table handling.  */
-lll_lock_t __pthread_keys_lock = LLL_LOCK_INITIALIZER;
-
 int
 __pthread_key_create (
      pthread_key_t *key,
      void (*destr) (void *))
 {
-  int result = EAGAIN;
-  size_t cnt;
-
-  lll_lock (__pthread_keys_lock);
-
   /* Find a slot in __pthread_kyes which is unused.  */
-  for (cnt = 0; cnt < PTHREAD_KEYS_MAX; ++cnt)
-    if (KEY_UNUSED (__pthread_keys[cnt].seq)
-	&& KEY_USABLE (__pthread_keys[cnt].seq))
-      {
-	/* We found an unused slot.  */
-	++__pthread_keys[cnt].seq;
-
-	/* Remember the destructor.  */
-	__pthread_keys[cnt].destr = destr;
-
-	/* Return the key to the caller.  */
-	*key = cnt;
-
-	/* The call succeeded.  */
-	result = 0;
-
-	/* We found a key and can stop now.  */
-	break;
-      }
-
-  lll_unlock (__pthread_keys_lock);
-
-  return result;
+  for (size_t cnt = 0; cnt < PTHREAD_KEYS_MAX; ++cnt)
+    {
+      uintptr_t seq = __pthread_keys[cnt].seq;
+
+      if (KEY_UNUSED (seq) && KEY_USABLE (seq)
+	  /* We found an unused slot.  Try to allocate it.  */
+	  && ! atomic_compare_and_exchange_bool_acq (&__pthread_keys[cnt].seq,
+						     seq + 1, seq))
+	{
+	  /* Remember the destructor.  */
+	  __pthread_keys[cnt].destr = destr;
+
+	  /* Return the key to the caller.  */
+	  *key = cnt;
+
+	  /* The call succeeded.  */
+	  return 0;
+	}
+    }
+
+  return EAGAIN;
 }
 strong_alias (__pthread_key_create, pthread_key_create)
 strong_alias (__pthread_key_create, __pthread_key_create_internal)

+ 37 - 0
libpthread/nptl/pthread_mutex_consistent.c

@@ -0,0 +1,37 @@
+/* Copyright (C) 2005, 2006, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   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>
+
+
+int
+pthread_mutex_consistent (
+     pthread_mutex_t *mutex)
+{
+  /* Test whether this is a robust mutex with a dead owner.  */
+  if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
+      || mutex->__data.__owner != PTHREAD_MUTEX_INCONSISTENT)
+    return EINVAL;
+
+  mutex->__data.__owner = THREAD_GETMEM (THREAD_SELF, tid);
+
+  return 0;
+}
+weak_alias (pthread_mutex_consistent, pthread_mutex_consistent_np)

+ 9 - 3
libpthread/nptl/pthread_mutex_destroy.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.
 
@@ -22,11 +22,17 @@
 
 
 int
-__pthread_mutex_destroy (pthread_mutex_t *mutex)
+__pthread_mutex_destroy (
+     pthread_mutex_t *mutex)
 {
-  if (mutex->__data.__nusers != 0)
+  if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
+      && mutex->__data.__nusers != 0)
     return EBUSY;
 
+  /* Set to an invalid value.  */
+  mutex->__data.__kind = -1;
+
   return 0;
 }
 strong_alias (__pthread_mutex_destroy, pthread_mutex_destroy)
+INTDEF(__pthread_mutex_destroy)

+ 38 - 0
libpthread/nptl/pthread_mutex_getprioceiling.c

@@ -0,0 +1,38 @@
+/* Get current priority ceiling of pthread_mutex_t.
+   Copyright (C) 2006 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 <pthreadP.h>
+
+
+int
+pthread_mutex_getprioceiling (mutex, prioceiling)
+     const pthread_mutex_t *mutex;
+     int *prioceiling;
+{
+  if (__builtin_expect ((mutex->__data.__kind
+			 & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0, 0))
+    return EINVAL;
+
+  *prioceiling = (mutex->__data.__lock & PTHREAD_MUTEX_PRIO_CEILING_MASK)
+		 >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+
+  return 0;
+}

+ 87 - 3
libpthread/nptl/pthread_mutex_init.c

@@ -1,4 +1,5 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -18,10 +19,11 @@
    02111-1307 USA.  */
 
 #include <assert.h>
+#include <errno.h>
 #include <string.h>
+#include <bits/kernel-features.h>
 #include "pthreadP.h"
 
-
 static const struct pthread_mutexattr default_attr =
   {
     /* Default is a normal mutex, not shared between processes.  */
@@ -29,6 +31,11 @@ static const struct pthread_mutexattr default_attr =
   };
 
 
+#ifndef __ASSUME_FUTEX_LOCK_PI
+static int tpi_supported;
+#endif
+
+
 int
 __pthread_mutex_init (
      pthread_mutex_t *mutex,
@@ -40,18 +47,95 @@ __pthread_mutex_init (
 
   imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr;
 
+  /* Sanity checks.  */
+  switch (__builtin_expect (imutexattr->mutexkind
+			    & PTHREAD_MUTEXATTR_PROTOCOL_MASK,
+			    PTHREAD_PRIO_NONE
+			    << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT))
+    {
+    case PTHREAD_PRIO_NONE << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
+      break;
+
+    case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
+#ifndef __ASSUME_FUTEX_LOCK_PI
+      if (__builtin_expect (tpi_supported == 0, 0))
+	{
+	  int lock = 0;
+	  INTERNAL_SYSCALL_DECL (err);
+	  int ret = INTERNAL_SYSCALL (futex, err, 4, &lock, FUTEX_UNLOCK_PI,
+				      0, 0);
+	  assert (INTERNAL_SYSCALL_ERROR_P (ret, err));
+	  tpi_supported = INTERNAL_SYSCALL_ERRNO (ret, err) == ENOSYS ? -1 : 1;
+	}
+      if (__builtin_expect (tpi_supported < 0, 0))
+	return ENOTSUP;
+#endif
+      break;
+
+    default:
+      /* XXX: For now we don't support robust priority protected mutexes.  */
+      if (imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST)
+	return ENOTSUP;
+      break;
+    }
+
   /* Clear the whole variable.  */
   memset (mutex, '\0', __SIZEOF_PTHREAD_MUTEX_T);
 
   /* Copy the values from the attribute.  */
-  mutex->__data.__kind = imutexattr->mutexkind & ~0x80000000;
+  mutex->__data.__kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
+
+  if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0)
+    {
+#ifndef __ASSUME_SET_ROBUST_LIST
+      if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_PSHARED) != 0
+	  && __set_robust_list_avail < 0)
+	return ENOTSUP;
+#endif
+
+      mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+    }
+
+  switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
+    {
+    case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
+      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP;
+      break;
+
+    case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
+      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP;
+
+      int ceiling = (imutexattr->mutexkind
+		     & PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
+		    >> PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT;
+      if (! ceiling)
+	{
+	  if (__sched_fifo_min_prio == -1)
+	    __init_sched_fifo_prio ();
+	  if (ceiling < __sched_fifo_min_prio)
+	    ceiling = __sched_fifo_min_prio;
+	}
+      mutex->__data.__lock = ceiling << PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+      break;
+
+    default:
+      break;
+    }
+
+  /* The kernel when waking robust mutexes on exit never uses
+     FUTEX_PRIVATE_FLAG FUTEX_WAKE.  */
+  if ((imutexattr->mutexkind & (PTHREAD_MUTEXATTR_FLAG_PSHARED
+				| PTHREAD_MUTEXATTR_FLAG_ROBUST)) != 0)
+    mutex->__data.__kind |= PTHREAD_MUTEX_PSHARED_BIT;
 
   /* Default values: mutex not used yet.  */
   // mutex->__count = 0;	already done by memset
   // mutex->__owner = 0;	already done by memset
   // mutex->__nusers = 0;	already done by memset
   // mutex->__spins = 0;	already done by memset
+  // mutex->__next = NULL;	already done by memset
 
   return 0;
 }
 strong_alias (__pthread_mutex_init, pthread_mutex_init)
+INTDEF(__pthread_mutex_init)

+ 406 - 30
libpthread/nptl/pthread_mutex_lock.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2008, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -19,27 +19,52 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <not-cancel.h>
 #include "pthreadP.h"
 #include <lowlevellock.h>
 
 
 #ifndef LLL_MUTEX_LOCK
-# define LLL_MUTEX_LOCK(mutex) lll_mutex_lock (mutex)
-# define LLL_MUTEX_TRYLOCK(mutex) lll_mutex_trylock (mutex)
+# define LLL_MUTEX_LOCK(mutex) \
+  lll_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex))
+# define LLL_MUTEX_TRYLOCK(mutex) \
+  lll_trylock ((mutex)->__data.__lock)
+# define LLL_ROBUST_MUTEX_LOCK(mutex, id) \
+  lll_robust_lock ((mutex)->__data.__lock, id, \
+		   PTHREAD_ROBUST_MUTEX_PSHARED (mutex))
 #endif
 
 
+static int __pthread_mutex_lock_full (pthread_mutex_t *mutex)
+     __attribute_noinline__;
+
+
 int
-__pthread_mutex_lock (pthread_mutex_t *mutex)
+__pthread_mutex_lock (
+     pthread_mutex_t *mutex)
 {
   assert (sizeof (mutex->__size) >= sizeof (mutex->__data));
 
+  unsigned int type = PTHREAD_MUTEX_TYPE (mutex);
+  if (__builtin_expect (type & ~PTHREAD_MUTEX_KIND_MASK_NP, 0))
+    return __pthread_mutex_lock_full (mutex);
+
   pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
 
-  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
+  if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP)
+      == PTHREAD_MUTEX_TIMED_NP)
+    {
+    simple:
+      /* Normal mutex.  */
+      LLL_MUTEX_LOCK (mutex);
+      assert (mutex->__data.__owner == 0);
+    }
+  else if (__builtin_expect (type == PTHREAD_MUTEX_RECURSIVE_NP, 1))
     {
       /* Recursive mutex.  */
-    case PTHREAD_MUTEX_RECURSIVE_NP:
+
       /* Check whether we already hold the mutex.  */
       if (mutex->__data.__owner == id)
 	{
@@ -54,32 +79,17 @@ __pthread_mutex_lock (pthread_mutex_t *mutex)
 	}
 
       /* We have to get the mutex.  */
-      LLL_MUTEX_LOCK (mutex->__data.__lock);
+      LLL_MUTEX_LOCK (mutex);
 
+      assert (mutex->__data.__owner == 0);
       mutex->__data.__count = 1;
-      break;
-
-      /* Error checking mutex.  */
-    case PTHREAD_MUTEX_ERRORCHECK_NP:
-      /* Check whether we already hold the mutex.  */
-      if (mutex->__data.__owner == id)
-	return EDEADLK;
-
-      /* FALLTHROUGH */
-
-    default:
-      /* Correct code cannot set any other type.  */
-    case PTHREAD_MUTEX_TIMED_NP:
-    simple:
-      /* Normal mutex.  */
-      LLL_MUTEX_LOCK (mutex->__data.__lock);
-      break;
-
-    case PTHREAD_MUTEX_ADAPTIVE_NP:
+    }
+  else if (__builtin_expect (type == PTHREAD_MUTEX_ADAPTIVE_NP, 1))
+    {
       if (! __is_smp)
 	goto simple;
 
-      if (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0)
+      if (LLL_MUTEX_TRYLOCK (mutex) != 0)
 	{
 	  int cnt = 0;
 	  int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
@@ -88,7 +98,7 @@ __pthread_mutex_lock (pthread_mutex_t *mutex)
 	    {
 	      if (cnt++ >= max_cnt)
 		{
-		  LLL_MUTEX_LOCK (mutex->__data.__lock);
+		  LLL_MUTEX_LOCK (mutex);
 		  break;
 		}
 
@@ -96,15 +106,362 @@ __pthread_mutex_lock (pthread_mutex_t *mutex)
 	      BUSY_WAIT_NOP;
 #endif
 	    }
-	  while (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0);
+	  while (LLL_MUTEX_TRYLOCK (mutex) != 0);
 
 	  mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
 	}
+      assert (mutex->__data.__owner == 0);
+    }
+  else
+    {
+      assert (type == PTHREAD_MUTEX_ERRORCHECK_NP);
+      /* Check whether we already hold the mutex.  */
+      if (__builtin_expect (mutex->__data.__owner == id, 0))
+	return EDEADLK;
+      goto simple;
+    }
+
+  /* Record the ownership.  */
+  mutex->__data.__owner = id;
+#ifndef NO_INCR
+  ++mutex->__data.__nusers;
+#endif
+
+  return 0;
+}
+
+static int
+__pthread_mutex_lock_full (pthread_mutex_t *mutex)
+{
+  int oldval;
+  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
+
+  switch (PTHREAD_MUTEX_TYPE (mutex))
+    {
+    case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+		     &mutex->__data.__list.__next);
+
+      oldval = mutex->__data.__lock;
+      do
+	{
+	again:
+	  if ((oldval & FUTEX_OWNER_DIED) != 0)
+	    {
+	      /* The previous owner died.  Try locking the mutex.  */
+	      int newval = id;
+#ifdef NO_INCR
+	      newval |= FUTEX_WAITERS;
+#else
+	      newval |= (oldval & FUTEX_WAITERS);
+#endif
+
+	      newval
+		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						       newval, oldval);
+
+	      if (newval != oldval)
+		{
+		  oldval = newval;
+		  goto again;
+		}
+
+	      /* We got the mutex.  */
+	      mutex->__data.__count = 1;
+	      /* But it is inconsistent unless marked otherwise.  */
+	      mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+	      ENQUEUE_MUTEX (mutex);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+	      /* Note that we deliberately exit here.  If we fall
+		 through to the end of the function __nusers would be
+		 incremented which is not correct because the old
+		 owner has to be discounted.  If we are not supposed
+		 to increment __nusers we actually have to decrement
+		 it here.  */
+#ifdef NO_INCR
+	      --mutex->__data.__nusers;
+#endif
+
+	      return EOWNERDEAD;
+	    }
+
+	  /* Check whether we already hold the mutex.  */
+	  if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
+	    {
+	      int kind = PTHREAD_MUTEX_TYPE (mutex);
+	      if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+		  return EDEADLK;
+		}
+
+	      if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+
+		  /* Just bump the counter.  */
+		  if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+		    /* Overflow of the counter.  */
+		    return EAGAIN;
+
+		  ++mutex->__data.__count;
+
+		  return 0;
+		}
+	    }
+
+	  oldval = LLL_ROBUST_MUTEX_LOCK (mutex, id);
+
+	  if (__builtin_expect (mutex->__data.__owner
+				== PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+	    {
+	      /* This mutex is now not recoverable.  */
+	      mutex->__data.__count = 0;
+	      lll_unlock (mutex->__data.__lock,
+			  PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+	      return ENOTRECOVERABLE;
+	    }
+	}
+      while ((oldval & FUTEX_OWNER_DIED) != 0);
+
+      mutex->__data.__count = 1;
+      ENQUEUE_MUTEX (mutex);
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+      break;
+
+    case PTHREAD_MUTEX_PI_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
+      {
+	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+	int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+
+	if (robust)
+	  /* Note: robust PI futexes are signaled by setting bit 0.  */
+	  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+			 (void *) (((uintptr_t) &mutex->__data.__list.__next)
+				   | 1));
+
+	oldval = mutex->__data.__lock;
+
+	/* Check whether we already hold the mutex.  */
+	if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
+	  {
+	    if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+	      {
+		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+		return EDEADLK;
+	      }
+
+	    if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+	      {
+		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+		/* Just bump the counter.  */
+		if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+		  /* Overflow of the counter.  */
+		  return EAGAIN;
+
+		++mutex->__data.__count;
+
+		return 0;
+	      }
+	  }
+
+	int newval = id;
+#ifdef NO_INCR
+	newval |= FUTEX_WAITERS;
+#endif
+	oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						      newval, 0);
+
+	if (oldval != 0)
+	  {
+	    /* The mutex is locked.  The kernel will now take care of
+	       everything.  */
+	    int private = (robust
+			   ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
+			   : PTHREAD_MUTEX_PSHARED (mutex));
+	    INTERNAL_SYSCALL_DECL (__err);
+	    int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+				      __lll_private_flag (FUTEX_LOCK_PI,
+							  private), 1, 0);
+
+	    if (INTERNAL_SYSCALL_ERROR_P (e, __err)
+		&& (INTERNAL_SYSCALL_ERRNO (e, __err) == ESRCH
+		    || INTERNAL_SYSCALL_ERRNO (e, __err) == EDEADLK))
+	      {
+		assert (INTERNAL_SYSCALL_ERRNO (e, __err) != EDEADLK
+			|| (kind != PTHREAD_MUTEX_ERRORCHECK_NP
+			    && kind != PTHREAD_MUTEX_RECURSIVE_NP));
+		/* ESRCH can happen only for non-robust PI mutexes where
+		   the owner of the lock died.  */
+		assert (INTERNAL_SYSCALL_ERRNO (e, __err) != ESRCH || !robust);
+
+		/* Delay the thread indefinitely.  */
+		while (1)
+		  pause_not_cancel ();
+	      }
+
+	    oldval = mutex->__data.__lock;
+
+	    assert (robust || (oldval & FUTEX_OWNER_DIED) == 0);
+	  }
+
+	if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
+	  {
+	    atomic_and (&mutex->__data.__lock, ~FUTEX_OWNER_DIED);
+
+	    /* We got the mutex.  */
+	    mutex->__data.__count = 1;
+	    /* But it is inconsistent unless marked otherwise.  */
+	    mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+	    ENQUEUE_MUTEX_PI (mutex);
+	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+	    /* Note that we deliberately exit here.  If we fall
+	       through to the end of the function __nusers would be
+	       incremented which is not correct because the old owner
+	       has to be discounted.  If we are not supposed to
+	       increment __nusers we actually have to decrement it here.  */
+#ifdef NO_INCR
+	    --mutex->__data.__nusers;
+#endif
+
+	    return EOWNERDEAD;
+	  }
+
+	if (robust
+	    && __builtin_expect (mutex->__data.__owner
+				 == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+	  {
+	    /* This mutex is now not recoverable.  */
+	    mutex->__data.__count = 0;
+
+	    INTERNAL_SYSCALL_DECL (__err);
+	    INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+			      __lll_private_flag (FUTEX_UNLOCK_PI,
+						  PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
+			      0, 0);
+
+	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+	    return ENOTRECOVERABLE;
+	  }
+
+	mutex->__data.__count = 1;
+	if (robust)
+	  {
+	    ENQUEUE_MUTEX_PI (mutex);
+	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+	  }
+      }
       break;
+
+    case PTHREAD_MUTEX_PP_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PP_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PP_NORMAL_NP:
+    case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
+      {
+	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+
+	oldval = mutex->__data.__lock;
+
+	/* Check whether we already hold the mutex.  */
+	if (mutex->__data.__owner == id)
+	  {
+	    if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+	      return EDEADLK;
+
+	    if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+	      {
+		/* Just bump the counter.  */
+		if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+		  /* Overflow of the counter.  */
+		  return EAGAIN;
+
+		++mutex->__data.__count;
+
+		return 0;
+	      }
+	  }
+
+	int oldprio = -1, ceilval;
+	do
+	  {
+	    int ceiling = (oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK)
+			  >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+
+	    if (__pthread_current_priority () > ceiling)
+	      {
+		if (oldprio != -1)
+		  __pthread_tpp_change_priority (oldprio, -1);
+		return EINVAL;
+	      }
+
+	    int retval = __pthread_tpp_change_priority (oldprio, ceiling);
+	    if (retval)
+	      return retval;
+
+	    ceilval = ceiling << PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+	    oldprio = ceiling;
+
+	    oldval
+	      = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+#ifdef NO_INCR
+						     ceilval | 2,
+#else
+						     ceilval | 1,
+#endif
+						     ceilval);
+
+	    if (oldval == ceilval)
+	      break;
+
+	    do
+	      {
+		oldval
+		  = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+							 ceilval | 2,
+							 ceilval | 1);
+
+		if ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval)
+		  break;
+
+		if (oldval != ceilval)
+		  lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
+				  PTHREAD_MUTEX_PSHARED (mutex));
+	      }
+	    while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+							ceilval | 2, ceilval)
+		   != ceilval);
+	  }
+	while ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval);
+
+	assert (mutex->__data.__owner == 0);
+	mutex->__data.__count = 1;
+      }
+      break;
+
+    default:
+      /* Correct code cannot set any other type.  */
+      return EINVAL;
     }
 
   /* Record the ownership.  */
-  assert (mutex->__data.__owner == 0);
   mutex->__data.__owner = id;
 #ifndef NO_INCR
   ++mutex->__data.__nusers;
@@ -116,3 +473,22 @@ __pthread_mutex_lock (pthread_mutex_t *mutex)
 strong_alias (__pthread_mutex_lock, pthread_mutex_lock)
 strong_alias (__pthread_mutex_lock, __pthread_mutex_lock_internal)
 #endif
+
+
+#ifdef NO_INCR
+void
+__pthread_mutex_cond_lock_adjust (
+     pthread_mutex_t *mutex)
+{
+  assert ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0);
+  assert ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0);
+  assert ((mutex->__data.__kind & PTHREAD_MUTEX_PSHARED_BIT) == 0);
+
+  /* Record the ownership.  */
+  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
+  mutex->__data.__owner = id;
+
+  if (mutex->__data.__kind == PTHREAD_MUTEX_PI_RECURSIVE_NP)
+    ++mutex->__data.__count;
+}
+#endif

+ 119 - 0
libpthread/nptl/pthread_mutex_setprioceiling.c

@@ -0,0 +1,119 @@
+/* Set current priority ceiling of pthread_mutex_t.
+   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 <stdbool.h>
+#include <errno.h>
+#include <pthreadP.h>
+
+
+int
+pthread_mutex_setprioceiling (mutex, prioceiling, old_ceiling)
+     pthread_mutex_t *mutex;
+     int prioceiling;
+     int *old_ceiling;
+{
+  /* The low bits of __kind aren't ever changed after pthread_mutex_init,
+     so we don't need a lock yet.  */
+  if ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0)
+    return EINVAL;
+
+  if (__sched_fifo_min_prio == -1)
+    __init_sched_fifo_prio ();
+
+  if (__builtin_expect (prioceiling < __sched_fifo_min_prio, 0)
+      || __builtin_expect (prioceiling > __sched_fifo_max_prio, 0)
+      || __builtin_expect ((prioceiling
+			    & (PTHREAD_MUTEXATTR_PRIO_CEILING_MASK
+			       >> PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT))
+			   != prioceiling, 0))
+    return EINVAL;
+
+  /* Check whether we already hold the mutex.  */
+  bool locked = false;
+  int kind = PTHREAD_MUTEX_TYPE (mutex);
+  if (mutex->__data.__owner == THREAD_GETMEM (THREAD_SELF, tid))
+    {
+      if (kind == PTHREAD_MUTEX_PP_ERRORCHECK_NP)
+	return EDEADLK;
+
+      if (kind == PTHREAD_MUTEX_PP_RECURSIVE_NP)
+	locked = true;
+    }
+
+  int oldval = mutex->__data.__lock;
+  if (! locked)
+    do
+      {
+	/* Need to lock the mutex, but without obeying the priority
+	   protect protocol.  */
+	int ceilval = (oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK);
+
+	oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						      ceilval | 1, ceilval);
+	if (oldval == ceilval)
+	  break;
+
+	do
+	  {
+	    oldval
+	      = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						     ceilval | 2,
+						     ceilval | 1);
+
+	    if ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval)
+	      break;
+
+	    if (oldval != ceilval)
+	      lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
+			      PTHREAD_MUTEX_PSHARED (mutex));
+	  }
+	while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						    ceilval | 2, ceilval)
+	       != ceilval);
+
+	if ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval)
+	  continue;
+      }
+    while (0);
+
+  int oldprio = (oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK)
+		>> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+  if (locked)
+    {
+      int ret = __pthread_tpp_change_priority (oldprio, prioceiling);
+      if (ret)
+	return ret;
+    }
+
+  if (old_ceiling != NULL)
+    *old_ceiling = oldprio;
+
+  int newlock = 0;
+  if (locked)
+    newlock = (mutex->__data.__lock & ~PTHREAD_MUTEX_PRIO_CEILING_MASK);
+  mutex->__data.__lock = newlock
+			 | (prioceiling << PTHREAD_MUTEX_PRIO_CEILING_SHIFT);
+  atomic_full_barrier ();
+
+  lll_futex_wake (&mutex->__data.__lock, INT_MAX,
+		  PTHREAD_MUTEX_PSHARED (mutex));
+
+  return 0;
+}

+ 384 - 18
libpthread/nptl/pthread_mutex_timedlock.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -17,9 +17,12 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <assert.h>
 #include <errno.h>
+#include <time.h>
 #include "pthreadP.h"
 #include <lowlevellock.h>
+#include <not-cancel.h>
 
 
 int
@@ -27,13 +30,15 @@ pthread_mutex_timedlock (
      pthread_mutex_t *mutex,
      const struct timespec *abstime)
 {
+  int oldval;
   pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
   int result = 0;
 
   /* We must not check ABSTIME here.  If the thread does not block
      abstime must not be checked for a valid value.  */
 
-  switch (mutex->__data.__kind)
+  switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex),
+			    PTHREAD_MUTEX_TIMED_NP))
     {
       /* Recursive mutex.  */
     case PTHREAD_MUTEX_RECURSIVE_NP:
@@ -49,40 +54,38 @@ pthread_mutex_timedlock (
 
 	  goto out;
 	}
-      else
-	{
-	  /* We have to get the mutex.  */
-	  result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
 
-	  if (result != 0)
-	    goto out;
+      /* We have to get the mutex.  */
+      result = lll_timedlock (mutex->__data.__lock, abstime,
+			      PTHREAD_MUTEX_PSHARED (mutex));
 
-	  /* Only locked once so far.  */
-	  mutex->__data.__count = 1;
-	}
+      if (result != 0)
+	goto out;
+
+      /* Only locked once so far.  */
+      mutex->__data.__count = 1;
       break;
 
       /* Error checking mutex.  */
     case PTHREAD_MUTEX_ERRORCHECK_NP:
       /* Check whether we already hold the mutex.  */
-      if (mutex->__data.__owner == id)
+      if (__builtin_expect (mutex->__data.__owner == id, 0))
 	return EDEADLK;
 
       /* FALLTHROUGH */
 
-    default:
-      /* Correct code cannot set any other type.  */
     case PTHREAD_MUTEX_TIMED_NP:
     simple:
       /* Normal mutex.  */
-      result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
+      result = lll_timedlock (mutex->__data.__lock, abstime,
+			      PTHREAD_MUTEX_PSHARED (mutex));
       break;
 
     case PTHREAD_MUTEX_ADAPTIVE_NP:
       if (! __is_smp)
 	goto simple;
 
-      if (lll_mutex_trylock (mutex->__data.__lock) != 0)
+      if (lll_trylock (mutex->__data.__lock) != 0)
 	{
 	  int cnt = 0;
 	  int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
@@ -91,7 +94,8 @@ pthread_mutex_timedlock (
 	    {
 	      if (cnt++ >= max_cnt)
 		{
-		  result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
+		  result = lll_timedlock (mutex->__data.__lock, abstime,
+					  PTHREAD_MUTEX_PSHARED (mutex));
 		  break;
 		}
 
@@ -99,11 +103,373 @@ pthread_mutex_timedlock (
 	      BUSY_WAIT_NOP;
 #endif
 	    }
-	  while (lll_mutex_trylock (mutex->__data.__lock) != 0);
+	  while (lll_trylock (mutex->__data.__lock) != 0);
 
 	  mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
 	}
       break;
+
+    case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+		     &mutex->__data.__list.__next);
+
+      oldval = mutex->__data.__lock;
+      do
+	{
+	again:
+	  if ((oldval & FUTEX_OWNER_DIED) != 0)
+	    {
+	      /* The previous owner died.  Try locking the mutex.  */
+	      int newval = id | (oldval & FUTEX_WAITERS);
+
+	      newval
+		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						       newval, oldval);
+	      if (newval != oldval)
+		{
+		  oldval = newval;
+		  goto again;
+		}
+
+	      /* We got the mutex.  */
+	      mutex->__data.__count = 1;
+	      /* But it is inconsistent unless marked otherwise.  */
+	      mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+	      ENQUEUE_MUTEX (mutex);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+	      /* Note that we deliberately exit here.  If we fall
+		 through to the end of the function __nusers would be
+		 incremented which is not correct because the old
+		 owner has to be discounted.  */
+	      return EOWNERDEAD;
+	    }
+
+	  /* Check whether we already hold the mutex.  */
+	  if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
+	    {
+	      int kind = PTHREAD_MUTEX_TYPE (mutex);
+	      if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+		  return EDEADLK;
+		}
+
+	      if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+
+		  /* Just bump the counter.  */
+		  if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+		    /* Overflow of the counter.  */
+		    return EAGAIN;
+
+		  ++mutex->__data.__count;
+
+		  return 0;
+		}
+	    }
+
+	  result = lll_robust_timedlock (mutex->__data.__lock, abstime, id,
+					 PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
+
+	  if (__builtin_expect (mutex->__data.__owner
+				== PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+	    {
+	      /* This mutex is now not recoverable.  */
+	      mutex->__data.__count = 0;
+	      lll_unlock (mutex->__data.__lock,
+			  PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+	      return ENOTRECOVERABLE;
+	    }
+
+	  if (result == ETIMEDOUT || result == EINVAL)
+	    goto out;
+
+	  oldval = result;
+	}
+      while ((oldval & FUTEX_OWNER_DIED) != 0);
+
+      mutex->__data.__count = 1;
+      ENQUEUE_MUTEX (mutex);
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+      break;
+
+    case PTHREAD_MUTEX_PI_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
+      {
+	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+	int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+
+	if (robust)
+	  /* Note: robust PI futexes are signaled by setting bit 0.  */
+	  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+			 (void *) (((uintptr_t) &mutex->__data.__list.__next)
+				   | 1));
+
+	oldval = mutex->__data.__lock;
+
+	/* Check whether we already hold the mutex.  */
+	if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
+	  {
+	    if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+	      {
+		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+		return EDEADLK;
+	      }
+
+	    if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+	      {
+		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+		/* Just bump the counter.  */
+		if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+		  /* Overflow of the counter.  */
+		  return EAGAIN;
+
+		++mutex->__data.__count;
+
+		return 0;
+	      }
+	  }
+
+	oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						      id, 0);
+
+	if (oldval != 0)
+	  {
+	    /* The mutex is locked.  The kernel will now take care of
+	       everything.  The timeout value must be a relative value.
+	       Convert it.  */
+	    int private = (robust
+			   ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
+			   : PTHREAD_MUTEX_PSHARED (mutex));
+	    INTERNAL_SYSCALL_DECL (__err);
+
+	    int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+				      __lll_private_flag (FUTEX_LOCK_PI,
+							  private), 1,
+				      abstime);
+	    if (INTERNAL_SYSCALL_ERROR_P (e, __err))
+	      {
+		if (INTERNAL_SYSCALL_ERRNO (e, __err) == ETIMEDOUT)
+		  return ETIMEDOUT;
+
+		if (INTERNAL_SYSCALL_ERRNO (e, __err) == ESRCH
+		    || INTERNAL_SYSCALL_ERRNO (e, __err) == EDEADLK)
+		  {
+		    assert (INTERNAL_SYSCALL_ERRNO (e, __err) != EDEADLK
+			    || (kind != PTHREAD_MUTEX_ERRORCHECK_NP
+				&& kind != PTHREAD_MUTEX_RECURSIVE_NP));
+		    /* ESRCH can happen only for non-robust PI mutexes where
+		       the owner of the lock died.  */
+		    assert (INTERNAL_SYSCALL_ERRNO (e, __err) != ESRCH
+			    || !robust);
+
+		    /* Delay the thread until the timeout is reached.
+		       Then return ETIMEDOUT.  */
+		    struct timespec reltime;
+		    struct timespec now;
+
+		    INTERNAL_SYSCALL (clock_gettime, __err, 2, CLOCK_REALTIME,
+				      &now);
+		    reltime.tv_sec = abstime->tv_sec - now.tv_sec;
+		    reltime.tv_nsec = abstime->tv_nsec - now.tv_nsec;
+		    if (reltime.tv_nsec < 0)
+		      {
+			reltime.tv_nsec += 1000000000;
+			--reltime.tv_sec;
+		      }
+		    if (reltime.tv_sec >= 0)
+		      while (nanosleep_not_cancel (&reltime, &reltime) != 0)
+			continue;
+
+		    return ETIMEDOUT;
+		  }
+
+		return INTERNAL_SYSCALL_ERRNO (e, __err);
+	      }
+
+	    oldval = mutex->__data.__lock;
+
+	    assert (robust || (oldval & FUTEX_OWNER_DIED) == 0);
+	  }
+
+	if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
+	  {
+	    atomic_and (&mutex->__data.__lock, ~FUTEX_OWNER_DIED);
+
+	    /* We got the mutex.  */
+	    mutex->__data.__count = 1;
+	    /* But it is inconsistent unless marked otherwise.  */
+	    mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+	    ENQUEUE_MUTEX_PI (mutex);
+	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+	    /* Note that we deliberately exit here.  If we fall
+	       through to the end of the function __nusers would be
+	       incremented which is not correct because the old owner
+	       has to be discounted.  */
+	    return EOWNERDEAD;
+	  }
+
+	if (robust
+	    && __builtin_expect (mutex->__data.__owner
+				 == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+	  {
+	    /* This mutex is now not recoverable.  */
+	    mutex->__data.__count = 0;
+
+	    INTERNAL_SYSCALL_DECL (__err);
+	    INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+			      __lll_private_flag (FUTEX_UNLOCK_PI,
+						  PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
+			      0, 0);
+
+	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+	    return ENOTRECOVERABLE;
+	  }
+
+	mutex->__data.__count = 1;
+	if (robust)
+	  {
+	    ENQUEUE_MUTEX_PI (mutex);
+	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+	  }
+	}
+      break;
+
+    case PTHREAD_MUTEX_PP_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PP_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PP_NORMAL_NP:
+    case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
+      {
+	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+
+	oldval = mutex->__data.__lock;
+
+	/* Check whether we already hold the mutex.  */
+	if (mutex->__data.__owner == id)
+	  {
+	    if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+	      return EDEADLK;
+
+	    if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+	      {
+		/* Just bump the counter.  */
+		if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+		  /* Overflow of the counter.  */
+		  return EAGAIN;
+
+		++mutex->__data.__count;
+
+		return 0;
+	      }
+	  }
+
+	int oldprio = -1, ceilval;
+	do
+	  {
+	    int ceiling = (oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK)
+			  >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+
+	    if (__pthread_current_priority () > ceiling)
+	      {
+		result = EINVAL;
+	      failpp:
+		if (oldprio != -1)
+		  __pthread_tpp_change_priority (oldprio, -1);
+		return result;
+	      }
+
+	    result = __pthread_tpp_change_priority (oldprio, ceiling);
+	    if (result)
+	      return result;
+
+	    ceilval = ceiling << PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+	    oldprio = ceiling;
+
+	    oldval
+	      = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						     ceilval | 1, ceilval);
+
+	    if (oldval == ceilval)
+	      break;
+
+	    do
+	      {
+		oldval
+		  = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+							 ceilval | 2,
+							 ceilval | 1);
+
+		if ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval)
+		  break;
+
+		if (oldval != ceilval)
+		  {
+		    /* Reject invalid timeouts.  */
+		    if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+		      {
+			result = EINVAL;
+			goto failpp;
+		      }
+
+		    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)
+		      {
+			result = ETIMEDOUT;
+			goto failpp;
+		      }
+
+		    lll_futex_timed_wait (&mutex->__data.__lock,
+					  ceilval | 2, &rt,
+					  PTHREAD_MUTEX_PSHARED (mutex));
+		  }
+	      }
+	    while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+							ceilval | 2, ceilval)
+		   != ceilval);
+	  }
+	while ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval);
+
+	assert (mutex->__data.__owner == 0);
+	mutex->__data.__count = 1;
+      }
+      break;
+
+    default:
+      /* Correct code cannot set any other type.  */
+      return EINVAL;
     }
 
   if (result == 0)

+ 320 - 14
libpthread/nptl/pthread_mutex_trylock.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005-2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -17,21 +17,25 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <assert.h>
 #include <errno.h>
+#include <stdlib.h>
 #include "pthreadP.h"
 #include <lowlevellock.h>
 
 
 int
-__pthread_mutex_trylock (pthread_mutex_t *mutex)
+__pthread_mutex_trylock (
+     pthread_mutex_t *mutex)
 {
-  pid_t id;
+  int oldval;
+  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
 
-  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
+  switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex),
+			    PTHREAD_MUTEX_TIMED_NP))
     {
       /* Recursive mutex.  */
     case PTHREAD_MUTEX_RECURSIVE_NP:
-      id = THREAD_GETMEM (THREAD_SELF, tid);
       /* Check whether we already hold the mutex.  */
       if (mutex->__data.__owner == id)
 	{
@@ -44,7 +48,7 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
 	  return 0;
 	}
 
-      if (lll_mutex_trylock (mutex->__data.__lock) == 0)
+      if (lll_trylock (mutex->__data.__lock) == 0)
 	{
 	  /* Record the ownership.  */
 	  mutex->__data.__owner = id;
@@ -55,20 +59,322 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
       break;
 
     case PTHREAD_MUTEX_ERRORCHECK_NP:
-      /* Error checking mutex.  We do not check for deadlocks.  */
-    default:
-      /* Correct code cannot set any other type.  */
     case PTHREAD_MUTEX_TIMED_NP:
     case PTHREAD_MUTEX_ADAPTIVE_NP:
       /* Normal mutex.  */
-      if (lll_mutex_trylock (mutex->__data.__lock) == 0)
+      if (lll_trylock (mutex->__data.__lock) != 0)
+	break;
+
+      /* Record the ownership.  */
+      mutex->__data.__owner = id;
+      ++mutex->__data.__nusers;
+
+      return 0;
+
+    case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+		     &mutex->__data.__list.__next);
+
+      oldval = mutex->__data.__lock;
+      do
 	{
-	  /* Record the ownership.  */
-	  mutex->__data.__owner = THREAD_GETMEM (THREAD_SELF, tid);
-	  ++mutex->__data.__nusers;
+	again:
+	  if ((oldval & FUTEX_OWNER_DIED) != 0)
+	    {
+	      /* The previous owner died.  Try locking the mutex.  */
+	      int newval = id | (oldval & FUTEX_WAITERS);
 
-	  return 0;
+	      newval
+		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						       newval, oldval);
+
+	      if (newval != oldval)
+		{
+		  oldval = newval;
+		  goto again;
+		}
+
+	      /* We got the mutex.  */
+	      mutex->__data.__count = 1;
+	      /* But it is inconsistent unless marked otherwise.  */
+	      mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+	      ENQUEUE_MUTEX (mutex);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+	      /* Note that we deliberately exist here.  If we fall
+		 through to the end of the function __nusers would be
+		 incremented which is not correct because the old
+		 owner has to be discounted.  */
+	      return EOWNERDEAD;
+	    }
+
+	  /* Check whether we already hold the mutex.  */
+	  if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
+	    {
+	      int kind = PTHREAD_MUTEX_TYPE (mutex);
+	      if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+		  return EDEADLK;
+		}
+
+	      if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+
+		  /* Just bump the counter.  */
+		  if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+		    /* Overflow of the counter.  */
+		    return EAGAIN;
+
+		  ++mutex->__data.__count;
+
+		  return 0;
+		}
+	    }
+
+	  oldval = lll_robust_trylock (mutex->__data.__lock, id);
+	  if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0)
+	    {
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+	      return EBUSY;
+	    }
+
+	  if (__builtin_expect (mutex->__data.__owner
+				== PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+	    {
+	      /* This mutex is now not recoverable.  */
+	      mutex->__data.__count = 0;
+	      if (oldval == id)
+		lll_unlock (mutex->__data.__lock,
+			    PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+	      return ENOTRECOVERABLE;
+	    }
 	}
+      while ((oldval & FUTEX_OWNER_DIED) != 0);
+
+      ENQUEUE_MUTEX (mutex);
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+      mutex->__data.__owner = id;
+      ++mutex->__data.__nusers;
+      mutex->__data.__count = 1;
+
+      return 0;
+
+    case PTHREAD_MUTEX_PI_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
+      {
+	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+	int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+
+	if (robust)
+	  /* Note: robust PI futexes are signaled by setting bit 0.  */
+	  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+			 (void *) (((uintptr_t) &mutex->__data.__list.__next)
+				   | 1));
+
+	oldval = mutex->__data.__lock;
+
+	/* Check whether we already hold the mutex.  */
+	if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
+	  {
+	    if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+	      {
+		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+		return EDEADLK;
+	      }
+
+	    if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+	      {
+		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+		/* Just bump the counter.  */
+		if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+		  /* Overflow of the counter.  */
+		  return EAGAIN;
+
+		++mutex->__data.__count;
+
+		return 0;
+	      }
+	  }
+
+	oldval
+	  = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						 id, 0);
+
+	if (oldval != 0)
+	  {
+	    if ((oldval & FUTEX_OWNER_DIED) == 0)
+	      {
+		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+		return EBUSY;
+	      }
+
+	    assert (robust);
+
+	    /* The mutex owner died.  The kernel will now take care of
+	       everything.  */
+	    int private = (robust
+			   ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
+			   : PTHREAD_MUTEX_PSHARED (mutex));
+	    INTERNAL_SYSCALL_DECL (__err);
+	    int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+				      __lll_private_flag (FUTEX_TRYLOCK_PI,
+							  private), 0, 0);
+
+	    if (INTERNAL_SYSCALL_ERROR_P (e, __err)
+		&& INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
+	      {
+		THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+		return EBUSY;
+	      }
+
+	    oldval = mutex->__data.__lock;
+	  }
+
+	if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
+	  {
+	    atomic_and (&mutex->__data.__lock, ~FUTEX_OWNER_DIED);
+
+	    /* We got the mutex.  */
+	    mutex->__data.__count = 1;
+	    /* But it is inconsistent unless marked otherwise.  */
+	    mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+	    ENQUEUE_MUTEX (mutex);
+	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+	    /* Note that we deliberately exit here.  If we fall
+	       through to the end of the function __nusers would be
+	       incremented which is not correct because the old owner
+	       has to be discounted.  */
+	    return EOWNERDEAD;
+	  }
+
+	if (robust
+	    && __builtin_expect (mutex->__data.__owner
+				 == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+	  {
+	    /* This mutex is now not recoverable.  */
+	    mutex->__data.__count = 0;
+
+	    INTERNAL_SYSCALL_DECL (__err);
+	    INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+			      __lll_private_flag (FUTEX_UNLOCK_PI,
+						  PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
+			      0, 0);
+
+	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+	    return ENOTRECOVERABLE;
+	  }
+
+	if (robust)
+	  {
+	    ENQUEUE_MUTEX_PI (mutex);
+	    THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+	  }
+
+	mutex->__data.__owner = id;
+	++mutex->__data.__nusers;
+	mutex->__data.__count = 1;
+
+	return 0;
+      }
+
+    case PTHREAD_MUTEX_PP_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PP_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PP_NORMAL_NP:
+    case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
+      {
+	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+
+	oldval = mutex->__data.__lock;
+
+	/* Check whether we already hold the mutex.  */
+	if (mutex->__data.__owner == id)
+	  {
+	    if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+	      return EDEADLK;
+
+	    if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+	      {
+		/* Just bump the counter.  */
+		if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+		  /* Overflow of the counter.  */
+		  return EAGAIN;
+
+		++mutex->__data.__count;
+
+		return 0;
+	      }
+	  }
+
+	int oldprio = -1, ceilval;
+	do
+	  {
+	    int ceiling = (oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK)
+			  >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+
+	    if (__pthread_current_priority () > ceiling)
+	      {
+		if (oldprio != -1)
+		  __pthread_tpp_change_priority (oldprio, -1);
+		return EINVAL;
+	      }
+
+	    int retval = __pthread_tpp_change_priority (oldprio, ceiling);
+	    if (retval)
+	      return retval;
+
+	    ceilval = ceiling << PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+	    oldprio = ceiling;
+
+	    oldval
+	      = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						     ceilval | 1, ceilval);
+
+	    if (oldval == ceilval)
+	      break;
+	  }
+	while ((oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK) != ceilval);
+
+	if (oldval != ceilval)
+	  {
+	    __pthread_tpp_change_priority (oldprio, -1);
+	    break;
+	  }
+
+	assert (mutex->__data.__owner == 0);
+	/* Record the ownership.  */
+	mutex->__data.__owner = id;
+	++mutex->__data.__nusers;
+	mutex->__data.__count = 1;
+
+	return 0;
+      }
+      break;
+
+    default:
+      /* Correct code cannot set any other type.  */
+      return EINVAL;
     }
 
   return EBUSY;

+ 236 - 20
libpthread/nptl/pthread_mutex_unlock.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005-2008, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -17,10 +17,16 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <assert.h>
 #include <errno.h>
+#include <stdlib.h>
 #include "pthreadP.h"
 #include <lowlevellock.h>
 
+static int
+internal_function
+__pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
+     __attribute_noinline__;
 
 int
 internal_function attribute_hidden
@@ -28,9 +34,26 @@ __pthread_mutex_unlock_usercnt (
      pthread_mutex_t *mutex,
      int decr)
 {
-  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
+  int type = PTHREAD_MUTEX_TYPE (mutex);
+  if (__builtin_expect (type & ~PTHREAD_MUTEX_KIND_MASK_NP, 0))
+    return __pthread_mutex_unlock_full (mutex, decr);
+
+  if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP)
+      == PTHREAD_MUTEX_TIMED_NP)
+    {
+      /* Always reset the owner field.  */
+    normal:
+      mutex->__data.__owner = 0;
+      if (decr)
+	/* One less user.  */
+	--mutex->__data.__nusers;
+
+      /* Unlock.  */
+      lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex));
+      return 0;
+    }
+  else if (__builtin_expect (type == PTHREAD_MUTEX_RECURSIVE_NP, 1))
     {
-    case PTHREAD_MUTEX_RECURSIVE_NP:
       /* Recursive mutex.  */
       if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
 	return EPERM;
@@ -38,38 +61,231 @@ __pthread_mutex_unlock_usercnt (
       if (--mutex->__data.__count != 0)
 	/* We still hold the mutex.  */
 	return 0;
+      goto normal;
+    }
+  else if (__builtin_expect (type == PTHREAD_MUTEX_ADAPTIVE_NP, 1))
+    goto normal;
+  else
+    {
+      /* Error checking mutex.  */
+      assert (type == PTHREAD_MUTEX_ERRORCHECK_NP);
+      if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid)
+	  || ! lll_islocked (mutex->__data.__lock))
+	return EPERM;
+      goto normal;
+    }
+}
+
+
+static int
+internal_function
+__pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
+{
+  int newowner = 0;
+
+  switch (PTHREAD_MUTEX_TYPE (mutex))
+    {
+    case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+      /* Recursive mutex.  */
+      if ((mutex->__data.__lock & FUTEX_TID_MASK)
+	  == THREAD_GETMEM (THREAD_SELF, tid)
+	  && __builtin_expect (mutex->__data.__owner
+			       == PTHREAD_MUTEX_INCONSISTENT, 0))
+	{
+	  if (--mutex->__data.__count != 0)
+	    /* We still hold the mutex.  */
+	    return ENOTRECOVERABLE;
+
+	  goto notrecoverable;
+	}
+
+      if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
+	return EPERM;
+
+      if (--mutex->__data.__count != 0)
+	/* We still hold the mutex.  */
+	return 0;
+
+      goto robust;
+
+    case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+      if ((mutex->__data.__lock & FUTEX_TID_MASK)
+	  != THREAD_GETMEM (THREAD_SELF, tid)
+	  || ! lll_islocked (mutex->__data.__lock))
+	return EPERM;
+
+      /* If the previous owner died and the caller did not succeed in
+	 making the state consistent, mark the mutex as unrecoverable
+	 and make all waiters.  */
+      if (__builtin_expect (mutex->__data.__owner
+			    == PTHREAD_MUTEX_INCONSISTENT, 0))
+      notrecoverable:
+	newowner = PTHREAD_MUTEX_NOTRECOVERABLE;
+
+    robust:
+      /* Remove mutex from the list.  */
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+		     &mutex->__data.__list.__next);
+      DEQUEUE_MUTEX (mutex);
+
+      mutex->__data.__owner = newowner;
+      if (decr)
+	/* One less user.  */
+	--mutex->__data.__nusers;
+
+      /* Unlock.  */
+      lll_robust_unlock (mutex->__data.__lock,
+			 PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
+
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
 
-    case PTHREAD_MUTEX_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_RECURSIVE_NP:
+      /* Recursive mutex.  */
+      if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
+	return EPERM;
+
+      if (--mutex->__data.__count != 0)
+	/* We still hold the mutex.  */
+	return 0;
+      goto continue_pi_non_robust;
+
+    case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
+      /* Recursive mutex.  */
+      if ((mutex->__data.__lock & FUTEX_TID_MASK)
+	  == THREAD_GETMEM (THREAD_SELF, tid)
+	  && __builtin_expect (mutex->__data.__owner
+			       == PTHREAD_MUTEX_INCONSISTENT, 0))
+	{
+	  if (--mutex->__data.__count != 0)
+	    /* We still hold the mutex.  */
+	    return ENOTRECOVERABLE;
+
+	  goto pi_notrecoverable;
+	}
+
+      if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
+	return EPERM;
+
+      if (--mutex->__data.__count != 0)
+	/* We still hold the mutex.  */
+	return 0;
+
+      goto continue_pi_robust;
+
+    case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
+      if ((mutex->__data.__lock & FUTEX_TID_MASK)
+	  != THREAD_GETMEM (THREAD_SELF, tid)
+	  || ! lll_islocked (mutex->__data.__lock))
+	return EPERM;
+
+      /* If the previous owner died and the caller did not succeed in
+	 making the state consistent, mark the mutex as unrecoverable
+	 and make all waiters.  */
+      if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0
+	  && __builtin_expect (mutex->__data.__owner
+			       == PTHREAD_MUTEX_INCONSISTENT, 0))
+      pi_notrecoverable:
+       newowner = PTHREAD_MUTEX_NOTRECOVERABLE;
+
+      if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
+	{
+	continue_pi_robust:
+	  /* Remove mutex from the list.
+	     Note: robust PI futexes are signaled by setting bit 0.  */
+	  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+			 (void *) (((uintptr_t) &mutex->__data.__list.__next)
+				   | 1));
+	  DEQUEUE_MUTEX (mutex);
+	}
+
+    continue_pi_non_robust:
+      mutex->__data.__owner = newowner;
+      if (decr)
+	/* One less user.  */
+	--mutex->__data.__nusers;
+
+      /* Unlock.  */
+      if ((mutex->__data.__lock & FUTEX_WAITERS) != 0
+	  || atomic_compare_and_exchange_bool_rel (&mutex->__data.__lock, 0,
+						   THREAD_GETMEM (THREAD_SELF,
+								  tid)))
+	{
+	  int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+	  int private = (robust
+			 ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
+			 : PTHREAD_MUTEX_PSHARED (mutex));
+	  INTERNAL_SYSCALL_DECL (__err);
+	  INTERNAL_SYSCALL (futex, __err, 2, &mutex->__data.__lock,
+			    __lll_private_flag (FUTEX_UNLOCK_PI, private));
+	}
+
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+      break;
+
+    case PTHREAD_MUTEX_PP_RECURSIVE_NP:
+      /* Recursive mutex.  */
+      if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
+	return EPERM;
+
+      if (--mutex->__data.__count != 0)
+	/* We still hold the mutex.  */
+	return 0;
+      goto pp;
+
+    case PTHREAD_MUTEX_PP_ERRORCHECK_NP:
       /* Error checking mutex.  */
       if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid)
-	  || ! lll_mutex_islocked (mutex->__data.__lock))
+	  || (mutex->__data.__lock & ~ PTHREAD_MUTEX_PRIO_CEILING_MASK) == 0)
 	return EPERM;
-      break;
+      /* FALLTHROUGH */
+
+    case PTHREAD_MUTEX_PP_NORMAL_NP:
+    case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
+      /* Always reset the owner field.  */
+    pp:
+      mutex->__data.__owner = 0;
+
+      if (decr)
+	/* One less user.  */
+	--mutex->__data.__nusers;
+
+      /* Unlock.  */
+      int newval, oldval;
+      do
+	{
+	  oldval = mutex->__data.__lock;
+	  newval = oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK;
+	}
+      while (atomic_compare_and_exchange_bool_rel (&mutex->__data.__lock,
+						   newval, oldval));
+
+      if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1)
+	lll_futex_wake (&mutex->__data.__lock, 1,
+			PTHREAD_MUTEX_PSHARED (mutex));
+
+      int oldprio = newval >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+      return __pthread_tpp_change_priority (oldprio, -1);
 
     default:
       /* Correct code cannot set any other type.  */
-    case PTHREAD_MUTEX_TIMED_NP:
-    case PTHREAD_MUTEX_ADAPTIVE_NP:
-      /* Normal mutex.  Nothing special to do.  */
-      break;
+      return EINVAL;
     }
 
-  /* Always reset the owner field.  */
-  mutex->__data.__owner = 0;
-  if (decr)
-    /* One less user.  */
-    --mutex->__data.__nusers;
-
-  /* Unlock.  */
-  lll_mutex_unlock (mutex->__data.__lock);
-
   return 0;
 }
 
 
 int
-__pthread_mutex_unlock (pthread_mutex_t *mutex)
+__pthread_mutex_unlock (
+     pthread_mutex_t *mutex)
 {
   return __pthread_mutex_unlock_usercnt (mutex, 1);
 }

+ 48 - 0
libpthread/nptl/pthread_mutexattr_getprioceiling.c

@@ -0,0 +1,48 @@
+/* Get priority ceiling setting from pthread_mutexattr_t.
+   Copyright (C) 2006 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 <pthreadP.h>
+
+
+int
+pthread_mutexattr_getprioceiling (
+     const pthread_mutexattr_t *attr,
+     int *prioceiling)
+{
+  const struct pthread_mutexattr *iattr;
+  int ceiling;
+
+  iattr = (const struct pthread_mutexattr *) attr;
+
+  ceiling = ((iattr->mutexkind & PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
+	     >> PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT);
+
+  if (! ceiling)
+    {
+      if (__sched_fifo_min_prio == -1)
+	__init_sched_fifo_prio ();
+      if (ceiling < __sched_fifo_min_prio)
+	ceiling = __sched_fifo_min_prio;
+    }
+
+  *prioceiling = ceiling;
+
+  return 0;
+}

+ 37 - 0
libpthread/nptl/pthread_mutexattr_getprotocol.c

@@ -0,0 +1,37 @@
+/* Get priority protocol setting from pthread_mutexattr_t.
+   Copyright (C) 2006 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 <pthreadP.h>
+
+
+int
+pthread_mutexattr_getprotocol (
+     const pthread_mutexattr_t *attr,
+     int *protocol)
+{
+  const struct pthread_mutexattr *iattr;
+
+  iattr = (const struct pthread_mutexattr *) attr;
+
+  *protocol = ((iattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
+	       >> PTHREAD_MUTEXATTR_PROTOCOL_SHIFT);
+
+  return 0;
+}

+ 2 - 4
libpthread/nptl/pthread_mutexattr_getpshared.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -29,9 +29,7 @@ pthread_mutexattr_getpshared (
 
   iattr = (const struct pthread_mutexattr *) attr;
 
-  /* We use bit 31 to signal whether the mutex is going to be
-     process-shared or not.  */
-  *pshared = ((iattr->mutexkind & 0x80000000) != 0
+  *pshared = ((iattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_PSHARED) != 0
 	      ? PTHREAD_PROCESS_SHARED : PTHREAD_PROCESS_PRIVATE);
 
   return 0;

+ 37 - 0
libpthread/nptl/pthread_mutexattr_getrobust.c

@@ -0,0 +1,37 @@
+/* Copyright (C) 2005, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   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_mutexattr_getrobust (
+     const pthread_mutexattr_t *attr,
+     int *robustness)
+{
+  const struct pthread_mutexattr *iattr;
+
+  iattr = (const struct pthread_mutexattr *) attr;
+
+  *robustness = ((iattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0
+		 ? PTHREAD_MUTEX_ROBUST_NP : PTHREAD_MUTEX_STALLED_NP);
+
+  return 0;
+}
+weak_alias (pthread_mutexattr_getrobust, pthread_mutexattr_getrobust_np)

+ 2 - 4
libpthread/nptl/pthread_mutexattr_gettype.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -29,9 +29,7 @@ pthread_mutexattr_gettype (
 
   iattr = (const struct pthread_mutexattr *) attr;
 
-  /* We use bit 31 to signal whether the mutex is going to be
-     process-shared or not.  */
-  *kind = iattr->mutexkind & ~0x80000000;
+  *kind = iattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
 
   return 0;
 }

+ 2 - 1
libpthread/nptl/pthread_mutexattr_init.c

@@ -22,7 +22,8 @@
 
 
 int
-__pthread_mutexattr_init (pthread_mutexattr_t *attr)
+__pthread_mutexattr_init (
+     pthread_mutexattr_t *attr)
 {
   if (sizeof (struct pthread_mutexattr) != sizeof (pthread_mutexattr_t))
     memset (attr, '\0', sizeof (*attr));

+ 47 - 0
libpthread/nptl/pthread_mutexattr_setprioceiling.c

@@ -0,0 +1,47 @@
+/* Change priority ceiling setting in pthread_mutexattr_t.
+   Copyright (C) 2006 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 <pthreadP.h>
+
+
+int
+pthread_mutexattr_setprioceiling (
+     pthread_mutexattr_t *attr,
+     int prioceiling)
+{
+  if (__sched_fifo_min_prio == -1)
+    __init_sched_fifo_prio ();
+
+  if (__builtin_expect (prioceiling < __sched_fifo_min_prio, 0)
+      || __builtin_expect (prioceiling > __sched_fifo_max_prio, 0)
+      || __builtin_expect ((prioceiling
+			    & (PTHREAD_MUTEXATTR_PRIO_CEILING_MASK
+			       >> PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT))
+			   != prioceiling, 0))
+    return EINVAL;
+
+  struct pthread_mutexattr *iattr = (struct pthread_mutexattr *) attr;
+
+  iattr->mutexkind = ((iattr->mutexkind & ~PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
+		      | (prioceiling << PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT));
+
+  return 0;
+}

+ 41 - 0
libpthread/nptl/pthread_mutexattr_setprotocol.c

@@ -0,0 +1,41 @@
+/* Change priority protocol setting in pthread_mutexattr_t.
+   Copyright (C) 2006 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 <pthreadP.h>
+
+
+int
+pthread_mutexattr_setprotocol (
+     pthread_mutexattr_t *attr,
+     int protocol)
+{
+  if (protocol != PTHREAD_PRIO_NONE
+      && protocol != PTHREAD_PRIO_INHERIT
+      && __builtin_expect (protocol != PTHREAD_PRIO_PROTECT, 0))
+    return EINVAL;
+
+  struct pthread_mutexattr *iattr = (struct pthread_mutexattr *) attr;
+
+  iattr->mutexkind = ((iattr->mutexkind & ~PTHREAD_MUTEXATTR_PROTOCOL_MASK)
+		      | (protocol << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT));
+
+  return 0;
+}

+ 3 - 5
libpthread/nptl/pthread_mutexattr_setpshared.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -34,12 +34,10 @@ pthread_mutexattr_setpshared (
 
   iattr = (struct pthread_mutexattr *) attr;
 
-  /* We use bit 31 to signal whether the mutex is going to be
-     process-shared or not.  */
   if (pshared == PTHREAD_PROCESS_PRIVATE)
-    iattr->mutexkind &= ~0x80000000;
+    iattr->mutexkind &= ~PTHREAD_MUTEXATTR_FLAG_PSHARED;
   else
-    iattr->mutexkind |= 0x80000000;
+    iattr->mutexkind |= PTHREAD_MUTEXATTR_FLAG_PSHARED;
 
   return 0;
 }

+ 44 - 0
libpthread/nptl/pthread_mutexattr_setrobust.c

@@ -0,0 +1,44 @@
+/* Copyright (C) 2005, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   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>
+
+
+int
+pthread_mutexattr_setrobust (
+     pthread_mutexattr_t *attr,
+     int robustness)
+{
+  if (robustness != PTHREAD_MUTEX_STALLED_NP
+      && __builtin_expect (robustness != PTHREAD_MUTEX_ROBUST_NP, 0))
+    return EINVAL;
+
+  struct pthread_mutexattr *iattr = (struct pthread_mutexattr *) attr;
+
+  /* We use bit 30 to signal whether the mutex is going to be
+     robust or not.  */
+  if (robustness == PTHREAD_MUTEX_STALLED_NP)
+    iattr->mutexkind &= ~PTHREAD_MUTEXATTR_FLAG_ROBUST;
+  else
+    iattr->mutexkind |= PTHREAD_MUTEXATTR_FLAG_ROBUST;
+
+  return 0;
+}
+weak_alias (pthread_mutexattr_setrobust, pthread_mutexattr_setrobust_np)

+ 2 - 4
libpthread/nptl/pthread_mutexattr_settype.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -33,9 +33,7 @@ __pthread_mutexattr_settype (
 
   iattr = (struct pthread_mutexattr *) attr;
 
-  /* We use bit 31 to signal whether the mutex is going to be
-     process-shared or not.  */
-  iattr->mutexkind = (iattr->mutexkind & 0x80000000) | kind;
+  iattr->mutexkind = (iattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_BITS) | kind;
 
   return 0;
 }

+ 30 - 8
libpthread/nptl/pthread_rwlock_init.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include "pthreadP.h"
+#include <bits/kernel-features.h>
 
 
 static const struct pthread_rwlockattr default_attr =
@@ -36,15 +37,36 @@ __pthread_rwlock_init (
 
   iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_attr;
 
-  rwlock->__data.__lock = 0;
+  memset (rwlock, '\0', sizeof (*rwlock));
+
   rwlock->__data.__flags
     = iattr->lockkind == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP;
-  rwlock->__data.__nr_readers = 0;
-  rwlock->__data.__writer = 0;
-  rwlock->__data.__readers_wakeup = 0;
-  rwlock->__data.__writer_wakeup = 0;
-  rwlock->__data.__nr_readers_queued = 0;
-  rwlock->__data.__nr_writers_queued = 0;
+
+  /* The __SHARED field is computed to minimize the work that needs to
+     be done while handling the futex.  There are two inputs: the
+     availability of private futexes and whether the rwlock is shared
+     or private.  Unfortunately the value of a private rwlock is
+     fixed: it must be zero.  The PRIVATE_FUTEX flag has the value
+     0x80 in case private futexes are available and zero otherwise.
+     This leads to the following table:
+
+		 |     pshared     |     result
+		 | shared  private | shared  private |
+     ------------+-----------------+-----------------+
+     !avail 0    |     0       0   |     0       0   |
+      avail 0x80 |  0x80       0   |     0    0x80   |
+
+     If the pshared value is in locking functions XORed with avail
+     we get the expected result.  */
+#ifdef __ASSUME_PRIVATE_FUTEX
+  rwlock->__data.__shared = (iattr->pshared == PTHREAD_PROCESS_PRIVATE
+			     ? 0 : FUTEX_PRIVATE_FLAG);
+#else
+  rwlock->__data.__shared = (iattr->pshared == PTHREAD_PROCESS_PRIVATE
+			     ? 0
+			     : THREAD_GETMEM (THREAD_SELF,
+					      header.private_futex));
+#endif
 
   return 0;
 }

+ 6 - 5
libpthread/nptl/pthread_rwlock_tryrdlock.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -23,15 +23,16 @@
 
 
 int
-__pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
+__pthread_rwlock_tryrdlock (
+     pthread_rwlock_t *rwlock)
 {
   int result = EBUSY;
 
-  lll_mutex_lock (rwlock->__data.__lock);
+  lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
 
   if (rwlock->__data.__writer == 0
       && (rwlock->__data.__nr_writers_queued == 0
-	  || rwlock->__data.__flags == 0))
+	  || PTHREAD_RWLOCK_PREFER_READER_P (rwlock)))
     {
       if (__builtin_expect (++rwlock->__data.__nr_readers == 0, 0))
 	{
@@ -42,7 +43,7 @@ __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
 	result = 0;
     }
 
-  lll_mutex_unlock (rwlock->__data.__lock);
+  lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
 
   return result;
 }

+ 5 - 4
libpthread/nptl/pthread_rwlock_trywrlock.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.
 
@@ -23,11 +23,12 @@
 
 
 int
-__pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
+__pthread_rwlock_trywrlock (
+     pthread_rwlock_t *rwlock)
 {
   int result = EBUSY;
 
-  lll_mutex_lock (rwlock->__data.__lock);
+  lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
 
   if (rwlock->__data.__writer == 0 && rwlock->__data.__nr_readers == 0)
     {
@@ -35,7 +36,7 @@ __pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
       result = 0;
     }
 
-  lll_mutex_unlock (rwlock->__data.__lock);
+  lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
 
   return result;
 }

+ 21 - 8
libpthread/nptl/pthread_setschedparam.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -26,9 +26,9 @@
 
 int
 __pthread_setschedparam (
-        pthread_t threadid,
-        int policy,
-        const struct sched_param *param)
+     pthread_t threadid,
+     int policy,
+     const struct sched_param *param)
 {
   struct pthread *pd = (struct pthread *) threadid;
 
@@ -39,10 +39,23 @@ __pthread_setschedparam (
 
   int result = 0;
 
-  lll_lock (pd->lock);
+  lll_lock (pd->lock, LLL_PRIVATE);
+
+  struct sched_param p;
+  const struct sched_param *orig_param = param;
+
+  /* If the thread should have higher priority because of some
+     PTHREAD_PRIO_PROTECT mutexes it holds, adjust the priority.  */
+  if (__builtin_expect (pd->tpp != NULL, 0)
+      && pd->tpp->priomax > param->sched_priority)
+    {
+      p = *param;
+      p.sched_priority = pd->tpp->priomax;
+      param = &p;
+    }
 
   /* Try to set the scheduler information.  */
-  if (__builtin_expect (sched_setscheduler (pd->tid, policy,
+  if (__builtin_expect (__sched_setscheduler (pd->tid, policy,
 					      param) == -1, 0))
     result = errno;
   else
@@ -50,11 +63,11 @@ __pthread_setschedparam (
       /* We succeeded changing the kernel information.  Reflect this
 	 change in the thread descriptor.  */
       pd->schedpolicy = policy;
-      memcpy (&pd->schedparam, param, sizeof (struct sched_param));
+      memcpy (&pd->schedparam, orig_param, sizeof (struct sched_param));
       pd->flags |= ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET;
     }
 
-  lll_unlock (pd->lock);
+  lll_unlock (pd->lock, LLL_PRIVATE);
 
   return result;
 }

+ 12 - 4
libpthread/nptl/pthread_setschedprio.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -26,7 +26,9 @@
 
 
 int
-pthread_setschedprio (pthread_t threadid, int prio)
+pthread_setschedprio (
+     pthread_t threadid,
+     int prio)
 {
   struct pthread *pd = (struct pthread *) threadid;
 
@@ -39,7 +41,12 @@ pthread_setschedprio (pthread_t threadid, int prio)
   struct sched_param param;
   param.sched_priority = prio;
 
-  lll_lock (pd->lock);
+  lll_lock (pd->lock, LLL_PRIVATE);
+
+  /* If the thread should have higher priority because of some
+     PTHREAD_PRIO_PROTECT mutexes it holds, adjust the priority.  */
+  if (__builtin_expect (pd->tpp != NULL, 0) && pd->tpp->priomax > prio)
+    param.sched_priority = pd->tpp->priomax;
 
   /* Try to set the scheduler information.  */
   if (__builtin_expect (sched_setparam (pd->tid, &param) == -1, 0))
@@ -48,11 +55,12 @@ pthread_setschedprio (pthread_t threadid, int prio)
     {
       /* We succeeded changing the kernel information.  Reflect this
 	 change in the thread descriptor.  */
+      param.sched_priority = prio;
       memcpy (&pd->schedparam, &param, sizeof (struct sched_param));
       pd->flags |= ATTR_FLAG_SCHED_SET;
     }
 
-  lll_unlock (pd->lock);
+  lll_unlock (pd->lock, LLL_PRIVATE);
 
   return result;
 }

+ 3 - 3
libpthread/nptl/pthread_setspecific.c

@@ -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.
 
@@ -52,8 +52,8 @@ __pthread_setspecific (
     }
   else
     {
-      if (KEY_UNUSED ((seq = __pthread_keys[key].seq))
-	  || key >= PTHREAD_KEYS_MAX)
+      if (key >= PTHREAD_KEYS_MAX
+	  || KEY_UNUSED ((seq = __pthread_keys[key].seq)))
 	/* Not valid.  */
 	return EINVAL;
 

+ 5 - 5
libpthread/nptl/pthread_timedjoin.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 "atomic.h"
+#include <atomic.h>
 #include "pthreadP.h"
 
 
@@ -32,9 +32,9 @@ cleanup (void *arg)
 
 int
 pthread_timedjoin_np (
-        pthread_t threadid,
-        void **thread_return,
-        const struct timespec *abstime)
+     pthread_t threadid,
+     void **thread_return,
+     const struct timespec *abstime)
 {
   struct pthread *self;
   struct pthread *pd = (struct pthread *) threadid;

+ 5 - 3
libpthread/nptl/pthread_tryjoin.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,12 +20,14 @@
 #include <errno.h>
 #include <stdlib.h>
 
-#include "atomic.h"
+#include <atomic.h>
 #include "pthreadP.h"
 
 
 int
-pthread_tryjoin_np (pthread_t threadid, void **thread_return)
+pthread_tryjoin_np (
+     pthread_t threadid,
+     void **thread_return)
 {
   struct pthread *self;
   struct pthread *pd = (struct pthread *) threadid;

+ 0 - 1
libpthread/nptl/res.c

@@ -17,7 +17,6 @@
    02111-1307 USA.  */
 
 #include <features.h>
-
 #include <tls.h>
 #include <resolv.h>
 

+ 4 - 3
libpthread/nptl/sem_close.c

@@ -41,12 +41,13 @@ walker (const void *inodep, const VISIT which, const int depth)
 
 
 int
-sem_close (sem_t *sem)
+sem_close (
+     sem_t *sem)
 {
   int result = 0;
 
   /* Get the lock.  */
-  lll_lock (__sem_mappings_lock);
+  lll_lock (__sem_mappings_lock, LLL_PRIVATE);
 
   /* Locate the entry for the mapping the caller provided.  */
   rec = NULL;
@@ -74,7 +75,7 @@ sem_close (sem_t *sem)
     }
 
   /* Release the lock.  */
-  lll_unlock (__sem_mappings_lock);
+  lll_unlock (__sem_mappings_lock, LLL_PRIVATE);
 
   return result;
 }

+ 2 - 1
libpthread/nptl/sem_destroy.c

@@ -22,7 +22,8 @@
 
 
 int
-__new_sem_destroy (sem_t *sem)
+__new_sem_destroy (
+     sem_t *sem)
 {
   /* XXX Check for valid parameter.  */
 

+ 3 - 3
libpthread/nptl/sem_getvalue.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -26,11 +26,11 @@ __new_sem_getvalue (
      sem_t *sem,
      int *sval)
 {
-  struct sem *isem = (struct sem *) sem;
+  struct new_sem *isem = (struct new_sem *) sem;
 
   /* XXX Check for valid SEM parameter.  */
 
-  *sval = isem->count;
+  *sval = isem->value;
 
   return 0;
 }

+ 14 - 8
libpthread/nptl/sem_init.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -21,6 +21,7 @@
 #include <semaphore.h>
 #include <lowlevellock.h>
 #include "semaphoreP.h"
+#include <bits/kernel-features.h>
 
 
 int
@@ -37,13 +38,18 @@ __new_sem_init (
     }
 
   /* Map to the internal type.  */
-  struct sem *isem = (struct sem *) sem;
-
-  /* Use the value the user provided.  */
-  isem->count = value;
-
-  /* We can completely ignore the PSHARED parameter since inter-process
-     use needs no special preparation.  */
+  struct new_sem *isem = (struct new_sem *) sem;
+
+  /* Use the values the user provided.  */
+  isem->value = value;
+#ifdef __ASSUME_PRIVATE_FUTEX
+  isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG;
+#else
+  isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF,
+					       header.private_futex);
+#endif
+
+  isem->nwaiters = 0;
 
   return 0;
 }

+ 26 - 21
libpthread/nptl/sem_open.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006, 2007, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -38,14 +38,15 @@
 
 
 /* Compatibility defines. */
-#define __endmntent			endmntent
-#define __fxstat64(vers, fd, buf)	fstat64(fd, buf)
-#define __getmntent_r			getmntent_r
-#define __setmntent			setmntent
-#define __statfs			statfs
-#define __libc_close			close
-#define __libc_open			open
-#define __libc_write			write
+#define __endmntent                    endmntent
+#define __fxstat64(vers, fd, buf)      fstat64(fd, buf)
+#define __getmntent_r                  getmntent_r
+#define __setmntent                    setmntent
+#define __statfs                       statfs
+#define __libc_close                   close
+#define __libc_open                    open
+#define __libc_write                   write
+
 
 /* Information about the mount point.  */
 struct mountpoint_info mountpoint attribute_hidden;
@@ -157,7 +158,7 @@ __sem_search (const void *a, const void *b)
 void *__sem_mappings attribute_hidden;
 
 /* Lock to protect the search tree.  */
-lll_lock_t __sem_mappings_lock = LLL_LOCK_INITIALIZER;
+int __sem_mappings_lock attribute_hidden = LLL_LOCK_INITIALIZER;
 
 
 /* Search for existing mapping and if possible add the one provided.  */
@@ -176,7 +177,7 @@ check_add_mapping (const char *name, size_t namelen, int fd, sem_t *existing)
 #endif
     {
       /* Get the lock.  */
-      lll_lock (__sem_mappings_lock);
+      lll_lock (__sem_mappings_lock, LLL_PRIVATE);
 
       /* Search for an existing mapping given the information we have.  */
       struct inuse_sem *fake;
@@ -225,7 +226,7 @@ check_add_mapping (const char *name, size_t namelen, int fd, sem_t *existing)
 	}
 
       /* Release the lock.  */
-      lll_unlock (__sem_mappings_lock);
+      lll_unlock (__sem_mappings_lock, LLL_PRIVATE);
     }
 
   if (result != existing && existing != SEM_FAILED && existing != MAP_FAILED)
@@ -317,24 +318,28 @@ sem_open (const char *name, int oflag, ...)
 	}
 
       /* Create the initial file content.  */
-      sem_t initsem;
+      union
+      {
+	sem_t initsem;
+	struct new_sem newsem;
+      } sem;
 
-      struct sem *iinitsem = (struct sem *) &initsem;
-      iinitsem->count = value;
+      sem.newsem.value = value;
+      sem.newsem.private = 0;
+      sem.newsem.nwaiters = 0;
 
       /* Initialize the remaining bytes as well.  */
-      memset ((char *) &initsem + sizeof (struct sem), '\0',
-	      sizeof (sem_t) - sizeof (struct sem));
+      memset ((char *) &sem.initsem + sizeof (struct new_sem), '\0',
+	      sizeof (sem_t) - sizeof (struct new_sem));
 
       tmpfname = (char *) alloca (mountpoint.dirlen + 6 + 1);
-      char *xxxxxx = mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen);
-      strcpy (xxxxxx, "XXXXXX");
+      mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen);
 
       fd = __gen_tempname (tmpfname, __GT_FILE, mode);
       if (fd == -1)
-          return SEM_FAILED;
+        return SEM_FAILED;
 
-      if (TEMP_FAILURE_RETRY (__libc_write (fd, &initsem, sizeof (sem_t)))
+      if (TEMP_FAILURE_RETRY (__libc_write (fd, &sem.initsem, sizeof (sem_t)))
 	  == sizeof (sem_t)
 	  /* Map the sem_t structure from the file.  */
 	  && (result = (sem_t *) mmap (NULL, sizeof (sem_t),

+ 2 - 1
libpthread/nptl/sem_unlink.c

@@ -26,7 +26,8 @@
 
 
 int
-sem_unlink (const char *name)
+sem_unlink (
+     const char *name)
 {
   char *fname;
   size_t namelen;

+ 4 - 2
libpthread/nptl/semaphoreP.h

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -48,7 +48,7 @@ extern pthread_once_t __namedsem_once attribute_hidden;
 extern void *__sem_mappings attribute_hidden;
 
 /* Lock to protect the search tree.  */
-extern lll_lock_t __sem_mappings_lock;
+extern int __sem_mappings_lock attribute_hidden;
 
 
 /* Initializer for mountpoint.  */
@@ -60,8 +60,10 @@ extern int __sem_search (const void *a, const void *b) attribute_hidden;
 
 /* Prototypes of functions with multiple interfaces.  */
 extern int __new_sem_init (sem_t *sem, int pshared, unsigned int value);
+extern int __old_sem_init (sem_t *sem, int pshared, unsigned int value);
 extern int __new_sem_destroy (sem_t *sem);
 extern int __new_sem_post (sem_t *sem);
 extern int __new_sem_wait (sem_t *sem);
+extern int __old_sem_wait (sem_t *sem);
 extern int __new_sem_trywait (sem_t *sem);
 extern int __new_sem_getvalue (sem_t *sem, int *sval);

+ 0 - 1
libpthread/nptl/sysdeps/arm/tls.h

@@ -21,7 +21,6 @@
 #define _TLS_H	1
 
 #ifndef __ASSEMBLER__
-#include <dl-sysdep.h>
 
 # include <stdbool.h>
 # include <stddef.h>

+ 8 - 13
libpthread/nptl/sysdeps/generic/lowlevellock.h

@@ -1,4 +1,5 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Low level locking macros used in NPTL implementation.  Stub version.
+   Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,16 +21,6 @@
 #include <atomic.h>
 
 
-/* Implement generic mutex.  Basic futex syscall support is required:
-
-     lll_futex_wait(futex, value) - call sys_futex with FUTEX_WAIT
-				    and third parameter VALUE
-
-     lll_futex_wake(futex, value) - call sys_futex with FUTEX_WAKE
-				    and third parameter VALUE
-*/
-
-
 /* Mutex lock counter:
    bit 31 clear means unlocked;
    bit 31 set means locked.
@@ -65,7 +56,9 @@ __generic_mutex_lock (int *mutex)
       if (v >= 0)
 	continue;
 
-      lll_futex_wait (mutex, v);
+      lll_futex_wait (mutex, v,
+		      // XYZ check mutex flag
+		      LLL_SHARED);
     }
 }
 
@@ -81,7 +74,9 @@ __generic_mutex_unlock (int *mutex)
 
   /* There are other threads waiting for this mutex, wake one of them
      up.  */
-  lll_futex_wake (mutex, 1);
+  lll_futex_wake (mutex, 1,
+		  // XYZ check mutex flag
+		  LLL_SHARED);
 }
 
 

+ 2 - 1
libpthread/nptl/sysdeps/i386/pthread_spin_lock.c

@@ -29,7 +29,8 @@
 
 
 int
-pthread_spin_lock (pthread_spinlock_t *lock)
+pthread_spin_lock (
+     pthread_spinlock_t *lock)
 {
   __asm__ ("\n"
        "1:\t" LOCK_PREFIX "decl %0\n\t"

+ 4 - 0
libpthread/nptl/sysdeps/i386/tcb-offsets.sym

@@ -11,3 +11,7 @@ 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)
+#ifndef __ASSUME_PRIVATE_FUTEX
+PRIVATE_FUTEX		offsetof (tcbhead_t, private_futex)
+#endif

+ 64 - 13
libpthread/nptl/sysdeps/i386/tls.h

@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  nptl/i386 version.
-   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2002-2007, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -26,6 +26,8 @@
 # include <stdint.h>
 # include <stdlib.h>
 # include <list.h>
+# include <sysdep.h>
+# include <bits/kernel-features.h>
 
 
 /* Type for the dtv.  */
@@ -49,6 +51,15 @@ typedef struct
   int multiple_threads;
   uintptr_t sysinfo;
   uintptr_t stack_guard;
+  uintptr_t pointer_guard;
+  int gscope_flag;
+#ifndef __ASSUME_PRIVATE_FUTEX
+  int private_futex;
+#else
+  int __unused1;
+#endif
+  /* Reservation of some values for the TM ABI.  */
+  void *__private_tm[5];
 } tcbhead_t;
 
 # define TLS_MULTIPLE_THREADS_IN_TCB 1
@@ -64,7 +75,8 @@ typedef struct
 #define HAVE_TLS_MODEL_ATTRIBUTE 1
 
 /* Signal that TLS support is available.  */
-#define USE_TLS	1
+#define USE_TLS        1
+
 
 /* Alignment requirement for the stack.  For IA-32 this is governed by
    the SSE memory functions.  */
@@ -99,6 +111,9 @@ union user_desc_init
 };
 
 
+/* Get the thread descriptor definition.  */
+# include <descr.h>
+
 /* 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.  */
@@ -113,9 +128,6 @@ union user_desc_init
 /* Alignment requirements for the TCB.  */
 # define TLS_TCB_ALIGN __alignof__ (struct pthread)
 
-/* Get the thread descriptor definition. */
-#include <descr.h>
-
 /* The TCB can have any size and the memory following the address the
    thread pointer points to is unspecified.  Allocate the TCB there.  */
 # define TLS_TCB_AT_TP	1
@@ -220,7 +232,7 @@ union user_desc_init
      _segdescr.vals[3] = 0x51;						      \
 									      \
      /* Install the TLS.  */						      \
-     __asm__ volatile (TLS_LOAD_EBX					      \
+     __asm__ volatile (TLS_LOAD_EBX						  \
 		   "int $0x80\n\t"					      \
 		   TLS_LOAD_EBX						      \
 		   : "=a" (_result), "=m" (_segdescr.desc.entry_number)	      \
@@ -256,7 +268,7 @@ union user_desc_init
    do not get optimized away.  */
 # define THREAD_SELF \
   ({ struct pthread *__self;						      \
-     __asm__ ("movl %%gs:%c1,%0" : "=r" (__self)			      \
+     __asm__ ("movl %%gs:%c1,%0" : "=r" (__self)				    \
 	  : "i" (offsetof (struct pthread, header.self)));		      \
      __self;})
 
@@ -270,11 +282,11 @@ union user_desc_init
 # define THREAD_GETMEM(descr, member) \
   ({ __typeof (descr->member) __value;					      \
      if (sizeof (__value) == 1)						      \
-       __asm__ volatile ("movb %%gs:%P2,%b0"				      \
+       __asm__ volatile ("movb %%gs:%P2,%b0"				    \
 		     : "=q" (__value)					      \
 		     : "0" (0), "i" (offsetof (struct pthread, member)));     \
      else if (sizeof (__value) == 4)					      \
-       __asm__ volatile ("movl %%gs:%P1,%0"				      \
+       __asm__ volatile ("movl %%gs:%P1,%0"					    \
 		     : "=r" (__value)					      \
 		     : "i" (offsetof (struct pthread, member)));	      \
      else								      \
@@ -297,12 +309,12 @@ union user_desc_init
 # define THREAD_GETMEM_NC(descr, member, idx) \
   ({ __typeof (descr->member[0]) __value;				      \
      if (sizeof (__value) == 1)						      \
-       __asm__ volatile ("movb %%gs:%P2(%3),%b0"			      \
+       __asm__ volatile ("movb %%gs:%P2(%3),%b0"				      \
 		     : "=q" (__value)					      \
 		     : "0" (0), "i" (offsetof (struct pthread, member[0])),   \
 		     "r" (idx));					      \
      else if (sizeof (__value) == 4)					      \
-       __asm__ volatile ("movl %%gs:%P1(,%2,4),%0"			      \
+       __asm__ volatile ("movl %%gs:%P1(,%2,4),%0"				      \
 		     : "=r" (__value)					      \
 		     : "i" (offsetof (struct pthread, member[0])),	      \
 		       "r" (idx));					      \
@@ -350,7 +362,7 @@ union user_desc_init
 /* Set member of the thread descriptor directly.  */
 # define THREAD_SETMEM_NC(descr, member, idx, value) \
   ({ if (sizeof (descr->member[0]) == 1)				      \
-       __asm__ volatile ("movb %b0,%%gs:%P1(%2)" :			      \
+       __asm__ volatile ("movb %b0,%%gs:%P1(%2)" :				      \
 		     : "iq" (value),					      \
 		       "i" (offsetof (struct pthread, member)),		      \
 		       "r" (idx));					      \
@@ -366,7 +378,7 @@ union user_desc_init
 	      4 or 8.  */						      \
 	   abort ();							      \
 									      \
-	 __asm__ volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t"		      \
+	 __asm__ volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t"			      \
 		       "movl %%edx,%%gs:4+%P1(,%2,8)" :			      \
 		       : "A" (value),					      \
 			 "i" (offsetof (struct pthread, member)),	      \
@@ -389,6 +401,17 @@ union user_desc_init
      __ret; })
 
 
+/* Atomic logical and.  */
+#define THREAD_ATOMIC_AND(descr, member, val) \
+  (void) ({ if (sizeof ((descr)->member) == 4)				      \
+	      __asm__ volatile (LOCK_PREFIX "andl %1, %%gs:%P0"		      \
+			    :: "i" (offsetof (struct pthread, member)),	      \
+			       "ir" (val));				      \
+	    else							      \
+	      /* Not necessary for other sizes in the moment.  */	      \
+	      abort (); })
+
+
 /* Atomic set bit.  */
 #define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
   (void) ({ if (sizeof ((descr)->member) == 4)				      \
@@ -424,6 +447,34 @@ union user_desc_init
    = 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, LLL_PRIVATE);    \
+    }									      \
+  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 */

+ 4 - 0
libpthread/nptl/sysdeps/powerpc/tcb-offsets.sym

@@ -14,3 +14,7 @@ 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))
+#ifndef __ASSUME_PRIVATE_FUTEX
+PRIVATE_FUTEX_OFFSET		thread_offsetof (header.private_futex)
+#endif

+ 39 - 3
libpthread/nptl/sysdeps/powerpc/tls.h

@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  NPTL/PowerPC version.
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005, 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,7 +47,7 @@ typedef union dtv
 #endif
 
 /* Signal that TLS support is available.  */
-# define USE_TLS	1
+# define USE_TLS       1
 
 #ifndef __ASSEMBLER__
 
@@ -64,9 +64,11 @@ typedef union dtv
 # include <nptl/descr.h>
 
 /* The stack_guard is accessed directly by GCC -fstack-protector code,
-   so it is a part of public ABI.  The dtv field is private.  */
+   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;
@@ -164,10 +166,44 @@ register void *__thread_register __asm__ ("r13");
      = ((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, LLL_PRIVATE);   \
+    }									     \
+  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 */

+ 8 - 1
libpthread/nptl/sysdeps/pthread/Makefile.in

@@ -18,7 +18,7 @@ libpthread_CSRC = pthread_barrier_wait.c pthread_cond_broadcast.c	\
 		  pthread_rwlock_wrlock.c pthread_sigmask.c		\
 		  pthread_spin_destroy.c pthread_spin_init.c		\
 		  pthread_spin_unlock.c pt-sigfillset.c	\
-		  pt-longjmp.c
+		  pt-longjmp.c tpp.c
 
 
 ifeq ($(TARGET_ARCH),i386)
@@ -43,6 +43,13 @@ SH_PTHREAD_EXCLUDE_LIST = pthread_spin_unlock.c pthread_spin_init.c \
 libpthread_CSRC := $(filter-out $(SH_PTHREAD_EXCLUDE_LIST),$(libpthread_CSRC))
 endif
 
+ifeq ($(TARGET_ARCH),sparc)
+SPARC_PTHREAD_EXCLUDE_LIST = pthread_barrier_init.c pthread_barrier_wait.c \
+		pthread_barrier_destroy.c
+
+libpthread_CSRC := $(filter-out $(SPARC_PTHREAD_EXCLUDE_LIST),$(libpthread_CSRC))
+endif
+
 ifeq ($(TARGET_ARCH),x86_64)
 X64_PTHREAD_EXCLUDE_LIST = pthread_spin_unlock.c pthread_spin_init.c \
 		pthread_barrier_wait.c pthread_cond_broadcast.c	\

+ 3 - 2
libpthread/nptl/sysdeps/pthread/allocalim.h

@@ -1,5 +1,5 @@
 /* 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
@@ -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)

+ 35 - 19
libpthread/nptl/sysdeps/pthread/bits/libc-lock.h

@@ -1,5 +1,5 @@
 /* libc-internal interface for mutex locks.  NPTL version.
-   Copyright (C) 1996-2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1996-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
@@ -150,13 +150,17 @@ typedef pthread_key_t __libc_key_t;
 
 /* Call thread functions through the function pointer table.  */
 #if defined SHARED && !defined NOT_IN_libc
-# define PTF(NAME) __libc_pthread_functions.ptr_##NAME
+# define PTFAVAIL(NAME) __libc_pthread_functions_init
 # define __libc_ptf_call(FUNC, ARGS, ELSE) \
-  (PTF(FUNC) != NULL ? PTF(FUNC) ARGS : ELSE)
+  (__libc_pthread_functions_init ? PTHFCT_CALL (ptr_##FUNC, ARGS) : ELSE)
+# define __libc_ptf_call_always(FUNC, ARGS) \
+  PTHFCT_CALL (ptr_##FUNC, ARGS)
 #else
-# define PTF(NAME) NAME
+# define PTFAVAIL(NAME) (NAME != NULL)
 # define __libc_ptf_call(FUNC, ARGS, ELSE) \
   __libc_maybe_call (FUNC, ARGS, ELSE)
+# define __libc_ptf_call_always(FUNC, ARGS) \
+  FUNC ARGS
 #endif
 
 
@@ -168,8 +172,15 @@ typedef pthread_key_t __libc_key_t;
 # define __libc_lock_init(NAME) \
   __libc_maybe_call (__pthread_mutex_init, (&(NAME), NULL), 0)
 #endif
-#define __libc_rwlock_init(NAME) \
+#if defined SHARED && !defined NOT_IN_libc
+/* ((NAME) = (__libc_rwlock_t) PTHREAD_RWLOCK_INITIALIZER, 0) is
+   inefficient.  */
+# define __libc_rwlock_init(NAME) \
+  (__builtin_memset (&(NAME), '\0', sizeof (NAME)), 0)
+#else
+# define __libc_rwlock_init(NAME) \
   __libc_maybe_call (__pthread_rwlock_init, (&(NAME), NULL), 0)
+#endif
 
 /* Same as last but this time we initialize a recursive mutex.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
@@ -210,8 +221,12 @@ typedef pthread_key_t __libc_key_t;
 # define __libc_lock_fini(NAME) \
   __libc_maybe_call (__pthread_mutex_destroy, (&(NAME)), 0)
 #endif
-#define __libc_rwlock_fini(NAME) \
+#if defined SHARED && !defined NOT_IN_libc
+# define __libc_rwlock_fini(NAME) ((void) 0)
+#else
+# define __libc_rwlock_fini(NAME) \
   __libc_maybe_call (__pthread_rwlock_destroy, (&(NAME)), 0)
+#endif
 
 /* Finalize recursive named lock.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
@@ -224,7 +239,7 @@ typedef pthread_key_t __libc_key_t;
 /* Lock the named lock variable.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
 # define __libc_lock_lock(NAME) \
-  ({ lll_lock (NAME); 0; })
+  ({ lll_lock (NAME, LLL_PRIVATE); 0; })
 #else
 # define __libc_lock_lock(NAME) \
   __libc_maybe_call (__pthread_mutex_lock, (&(NAME)), 0)
@@ -241,7 +256,7 @@ typedef pthread_key_t __libc_key_t;
     void *self = THREAD_SELF;						      \
     if ((NAME).owner != self)						      \
       {									      \
-	lll_lock ((NAME).lock);						      \
+	lll_lock ((NAME).lock, LLL_PRIVATE);				      \
 	(NAME).owner = self;						      \
       }									      \
     ++(NAME).cnt;							      \
@@ -295,7 +310,7 @@ typedef pthread_key_t __libc_key_t;
 /* Unlock the named lock variable.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
 # define __libc_lock_unlock(NAME) \
-  lll_unlock (NAME)
+  lll_unlock (NAME, LLL_PRIVATE)
 #else
 # define __libc_lock_unlock(NAME) \
   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
@@ -311,7 +326,7 @@ typedef pthread_key_t __libc_key_t;
     if (--(NAME).cnt == 0)						      \
       {									      \
 	(NAME).owner = NULL;						      \
-	lll_unlock ((NAME).lock);					      \
+	lll_unlock ((NAME).lock, LLL_PRIVATE);				      \
       }									      \
   } while (0)
 #else
@@ -353,8 +368,9 @@ typedef pthread_key_t __libc_key_t;
 /* Call handler iff the first call.  */
 #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
   do {									      \
-    if (PTF(__pthread_once) != NULL)					      \
-      PTF(__pthread_once) (&(ONCE_CONTROL), INIT_FUNCTION);		      \
+    if (PTFAVAIL (__pthread_once))					      \
+      __libc_ptf_call_always (__pthread_once, (&(ONCE_CONTROL),		      \
+					       INIT_FUNCTION));		      \
     else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) {			      \
       INIT_FUNCTION ();							      \
       (ONCE_CONTROL) |= 2;						      \
@@ -380,9 +396,10 @@ extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer
   { struct _pthread_cleanup_buffer _buffer;				      \
     int _avail;								      \
     if (DOIT) {								      \
-      _avail = PTF(_pthread_cleanup_push_defer) != NULL;		      \
+      _avail = PTFAVAIL (_pthread_cleanup_push_defer);			      \
       if (_avail) {							      \
-	PTF(_pthread_cleanup_push_defer) (&_buffer, FCT, ARG);		      \
+	__libc_ptf_call_always (_pthread_cleanup_push_defer, (&_buffer, FCT,  \
+							      ARG));	      \
       } else {								      \
 	_buffer.__routine = (FCT);					      \
 	_buffer.__arg = (ARG);						      \
@@ -394,7 +411,7 @@ extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer
 /* End critical region with cleanup.  */
 #define __libc_cleanup_region_end(DOIT) \
     if (_avail) {							      \
-      PTF(_pthread_cleanup_pop_restore) (&_buffer, DOIT);		      \
+      __libc_ptf_call_always (_pthread_cleanup_pop_restore, (&_buffer, DOIT));\
     } else if (DOIT)							      \
       _buffer.__routine (_buffer.__arg);				      \
   }
@@ -402,15 +419,12 @@ extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer
 /* Sometimes we have to exit the block in the middle.  */
 #define __libc_cleanup_end(DOIT) \
     if (_avail) {							      \
-      PTF(_pthread_cleanup_pop_restore) (&_buffer, DOIT);		      \
+      __libc_ptf_call_always (_pthread_cleanup_pop_restore, (&_buffer, DOIT));\
     } else if (DOIT)							      \
       _buffer.__routine (_buffer.__arg)
 
 
 /* Normal cleanup handling, based on C cleanup attribute.  */
-__extern_inline void
-__libc_cleanup_routine (struct __pthread_cleanup_frame *f);
-
 __extern_inline void
 __libc_cleanup_routine (struct __pthread_cleanup_frame *f)
 {
@@ -531,6 +545,7 @@ weak_extern (__pthread_key_create)
 weak_extern (__pthread_setspecific)
 weak_extern (__pthread_getspecific)
 weak_extern (__pthread_once)
+weak_extern (__pthread_initialize)
 weak_extern (__pthread_atfork)
 #ifdef SHARED
 weak_extern (_pthread_cleanup_push_defer)
@@ -556,6 +571,7 @@ weak_extern (pthread_setcancelstate)
 #  pragma weak __pthread_setspecific
 #  pragma weak __pthread_getspecific
 #  pragma weak __pthread_once
+#  pragma weak __pthread_initialize
 #  pragma weak __pthread_atfork
 #  pragma weak _pthread_cleanup_push_defer
 #  pragma weak _pthread_cleanup_pop_restore

+ 7 - 1
libpthread/nptl/sysdeps/pthread/bits/sigthread.h

@@ -1,5 +1,5 @@
 /* Signal handling function for threaded programs.
-   Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -35,4 +35,10 @@ extern int pthread_sigmask (int __how,
 /* Send signal SIGNO to the given thread. */
 extern int pthread_kill (pthread_t __threadid, int __signo) __THROW;
 
+#ifdef __USE_GNU
+/* Queue signal and data to a thread.  */
+extern int pthread_sigqueue (pthread_t __threadid, int __signo,
+			     const union sigval __value) __THROW;
+#endif
+
 #endif	/* bits/sigthread.h */

+ 10 - 4
libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h

@@ -1,5 +1,5 @@
 /* Thread package specific definitions of stream lock type.  NPTL version.
-   Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -42,7 +42,7 @@ typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
     void *__self = THREAD_SELF;						      \
     if ((_name).owner != __self)					      \
       {									      \
-        lll_lock ((_name).lock);					      \
+	lll_lock ((_name).lock, LLL_PRIVATE);				      \
         (_name).owner = __self;						      \
       }									      \
     ++(_name).cnt;							      \
@@ -72,7 +72,7 @@ typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
     if (--(_name).cnt == 0)						      \
       {									      \
         (_name).owner = NULL;						      \
-        lll_unlock ((_name).lock);					      \
+	lll_unlock ((_name).lock, LLL_PRIVATE);				      \
       }									      \
   } while (0)
 
@@ -94,9 +94,15 @@ typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
 	__attribute__((cleanup (_IO_acquire_lock_fct)))			      \
 	= (_fp);							      \
     _IO_flockfile (_IO_acquire_lock_file);
-
+#  define _IO_acquire_lock_clear_flags2(_fp) \
+  do {									      \
+    _IO_FILE *_IO_acquire_lock_file					      \
+	__attribute__((cleanup (_IO_acquire_lock_clear_flags2_fct)))	      \
+	= (_fp);							      \
+    _IO_flockfile (_IO_acquire_lock_file);
 # else
 #  define _IO_acquire_lock(_fp) _IO_acquire_lock_needs_exceptions_enabled
+#  define _IO_acquire_lock_clear_flags2(_fp) _IO_acquire_lock (_fp)
 # endif
 # define _IO_release_lock(_fp) ; } while (0)
 

+ 10 - 8
libpthread/nptl/sysdeps/pthread/createthread.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -56,11 +56,11 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
   PREPARE_CREATE;
 #endif
 
-  if (stopped)
-    /* We Make sure the thread does not run far by forcing it to get a
+  if (__builtin_expect (stopped != 0, 0))
+    /* We make sure the thread does not run far by forcing it to get a
        lock.  We lock it here too so that the new thread cannot continue
        until we tell it to.  */
-    lll_lock (pd->lock);
+    lll_lock (pd->lock, LLL_PRIVATE);
 
   /* One more thread.  We cannot have the thread do this itself, since it
      might exist but not have been scheduled yet by the time we've returned
@@ -84,7 +84,8 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
       if (IS_DETACHED (pd))
 	__deallocate_stack (pd);
 
-      return errno;
+      /* We have to translate error codes.  */
+      return errno == ENOMEM ? EAGAIN : errno;
     }
 
   /* Now we have the possibility to set scheduling parameters etc.  */
@@ -97,7 +98,7 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
       if (attr->cpuset != NULL)
 	{
 	  res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
-				  sizeof (cpu_set_t), attr->cpuset);
+				  attr->cpusetsize, attr->cpuset);
 
 	  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
 	    {
@@ -223,7 +224,7 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr,
 	      __nptl_create_event ();
 
 	      /* And finally restart the new thread.  */
-	      lll_unlock (pd->lock);
+	      lll_unlock (pd->lock, LLL_PRIVATE);
 	    }
 
 	  return res;
@@ -242,6 +243,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,
@@ -249,7 +251,7 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr,
 
   if (res == 0 && stopped)
     /* And finally restart the new thread.  */
-    lll_unlock (pd->lock);
+    lll_unlock (pd->lock, LLL_PRIVATE);
 
   return res;
 }

+ 4 - 87
libpthread/nptl/sysdeps/pthread/librt-cancellation.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -17,92 +17,9 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <setjmp.h>
-#include <signal.h>
-#include <stdlib.h>
 #include "pthreadP.h"
-#include "atomic.h"
 
 
-#ifdef IS_IN_librt
-/* The next two functions are similar to pthread_setcanceltype() but
-   more specialized for the use in the cancelable functions like write().
-   They do not need to check parameters etc.  */
-int
-attribute_hidden
-__librt_enable_asynccancel (void)
-{
-  struct pthread *self = THREAD_SELF;
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-
-  while (1)
-    {
-      int newval = oldval | CANCELTYPE_BITMASK;
-
-      if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0))
-	{
-	  /* If we are already exiting or if PTHREAD_CANCEL_DISABLED,
-	     stop right here.  */
-	  if ((oldval & (EXITING_BITMASK | CANCELSTATE_BITMASK)) != 0)
-	    break;
-
-	  int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
-						  newval, oldval);
-	  if (__builtin_expect (curval != oldval, 0))
-	    {
-	      /* Somebody else modified the word, try again.  */
-	      oldval = curval;
-	      continue;
-	    }
-
-	  THREAD_SETMEM (self, result, PTHREAD_CANCELED);
-
-	  __do_cancel ();
-
-	  /* NOTREACHED */
-	}
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (__builtin_expect (curval == oldval, 1))
-	break;
-
-      /* Prepare the next round.  */
-      oldval = curval;
-    }
-
-  return oldval;
-}
-
-
-void
-internal_function attribute_hidden
-__librt_disable_asynccancel (int oldtype)
-{
-  /* If asynchronous cancellation was enabled before we do not have
-     anything to do.  */
-  if (oldtype & CANCELTYPE_BITMASK)
-    return;
-
-  struct pthread *self = THREAD_SELF;
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-
-  while (1)
-    {
-      int newval = oldval & ~CANCELTYPE_BITMASK;
-
-      if (newval == oldval)
-	break;
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (__builtin_expect (curval == oldval, 1))
-	break;
-
-      /* Prepare the next round.  */
-      oldval = curval;
-    }
-}
-
-
-#endif
+#define __pthread_enable_asynccancel __librt_enable_asynccancel
+#define __pthread_disable_asynccancel __librt_disable_asynccancel
+#include "cancellation.c"

+ 2 - 13
libpthread/nptl/sysdeps/pthread/list.h

@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -46,24 +46,13 @@ typedef struct list_head
 static inline void
 list_add (list_t *newp, list_t *head)
 {
-  head->next->prev = newp;
   newp->next = head->next;
   newp->prev = head;
+  head->next->prev = newp;
   head->next = newp;
 }
 
 
-/* Add new element at the tail of the list.  */
-static inline void
-list_add_tail (list_t *newp, list_t *head)
-{
-  head->prev->next = newp;
-  newp->next = head;
-  newp->prev = head->prev;
-  head->prev = newp;
-}
-
-
 /* Remove element from list.  */
 static inline void
 list_del (list_t *elem)

+ 18 - 7
libpthread/nptl/sysdeps/pthread/malloc-machine.h

@@ -1,6 +1,6 @@
 /* Basic platform-independent macro definitions for mutexes,
    thread-specific data and parameters for malloc.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -38,13 +38,24 @@ extern void *__dso_handle __attribute__ ((__weak__));
 
 #include <fork.h>
 
+#define ATFORK_MEM static struct fork_handler atfork_mem
+
 #ifdef SHARED
 # define thread_atfork(prepare, parent, child) \
-   __register_atfork (prepare, parent, child, __dso_handle)
+  atfork_mem.prepare_handler = prepare;					      \
+  atfork_mem.parent_handler = parent;					      \
+  atfork_mem.child_handler = child;					      \
+  atfork_mem.dso_handle = __dso_handle;					      \
+  atfork_mem.refcntr = 1;						      \
+  __linkin_atfork (&atfork_mem)
 #else
 # define thread_atfork(prepare, parent, child) \
-   __register_atfork (prepare, parent, child,				      \
-		      &__dso_handle == NULL ? NULL : __dso_handle)
+  atfork_mem.prepare_handler = prepare;					      \
+  atfork_mem.parent_handler = parent;					      \
+  atfork_mem.child_handler = child;					      \
+  atfork_mem.dso_handle = &__dso_handle == NULL ? NULL : __dso_handle;	      \
+  atfork_mem.refcntr = 1;						      \
+  __linkin_atfork (&atfork_mem)
 #endif
 
 /* thread specific data for glibc */
@@ -52,10 +63,10 @@ extern void *__dso_handle __attribute__ ((__weak__));
 #include <bits/libc-tsd.h>
 
 typedef int tsd_key_t[1];	/* no key data structure, libc magic does it */
-__libc_tsd_define (static, MALLOC)	/* declaration/common definition */
+__libc_tsd_define (static, void *, MALLOC)	/* declaration/common definition */
 #define tsd_key_create(key, destr)	((void) (key))
-#define tsd_setspecific(key, data)	__libc_tsd_set (MALLOC, (data))
-#define tsd_getspecific(key, vptr)	((vptr) = __libc_tsd_get (MALLOC))
+#define tsd_setspecific(key, data)	__libc_tsd_set (void *, MALLOC, (data))
+#define tsd_getspecific(key, vptr)	((vptr) = __libc_tsd_get (void *, MALLOC))
 
 #include <sysdeps/generic/malloc-machine.h>
 

+ 2 - 2
libpthread/nptl/sysdeps/pthread/pt-initfini.c

@@ -72,7 +72,7 @@ call_initialize_minimal (void)
 }
 
 SECTION (".init");
-extern void _init (void);
+extern void __attribute__ ((section (".init"))) _init (void);
 void
 _init (void)
 {
@@ -93,7 +93,7 @@ asm ("\n/*@_init_EPILOG_ENDS*/");
 asm ("\n/*@_fini_PROLOG_BEGINS*/");
 
 SECTION (".fini");
-extern void _fini (void);
+extern void __attribute__ ((section (".fini"))) _fini (void);
 void
 _fini (void)
 {

+ 0 - 2
libpthread/nptl/sysdeps/pthread/pt-longjmp.c

@@ -21,8 +21,6 @@
 #include <stdlib.h>
 #include "pthreadP.h"
 
-extern void __libc_longjmp (sigjmp_buf env, int val)
-	__attribute__ ((noreturn));
 void
 longjmp (jmp_buf env, int val)
 {

+ 15 - 5
libpthread/nptl/sysdeps/pthread/pthread-functions.h

@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -23,6 +23,7 @@
 #include <pthread.h>
 #include <setjmp.h>
 #include <internaltypes.h>
+#include <sysdep.h>
 
 struct xid_command;
 
@@ -72,12 +73,8 @@ struct pthread_functions
   int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *);
   int (*ptr_pthread_mutex_init) (pthread_mutex_t *,
 				 const pthread_mutexattr_t *);
-  int (*ptr_pthread_mutex_trylock) (pthread_mutex_t *);
   int (*ptr_pthread_mutex_lock) (pthread_mutex_t *);
   int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *);
-  int (*ptr_pthread_mutexattr_init) (pthread_mutexattr_t *attr);
-  int (*ptr_pthread_mutexattr_destroy) (pthread_mutexattr_t *attr);
-  int (*ptr_pthread_mutexattr_settype) (pthread_mutexattr_t *attr, int kind);
   pthread_t (*ptr_pthread_self) (void);
   int (*ptr_pthread_setcancelstate) (int, int *);
   int (*ptr_pthread_setcanceltype) (int, int *);
@@ -99,9 +96,22 @@ struct pthread_functions
        __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.  */
 extern struct pthread_functions __libc_pthread_functions attribute_hidden;
+extern int __libc_pthread_functions_init attribute_hidden;
+
+#ifdef PTR_DEMANGLE
+# define PTHFCT_CALL(fct, params) \
+  ({ __typeof (__libc_pthread_functions.fct) __p;			      \
+     __p = __libc_pthread_functions.fct;				      \
+     PTR_DEMANGLE (__p);						      \
+     __p params; })
+#else
+# define PTHFCT_CALL(fct, params) \
+  __libc_pthread_functions.fct params
+#endif
 
 #endif	/* pthread-functions.h */

+ 268 - 106
libpthread/nptl/sysdeps/pthread/pthread.h

@@ -1,4 +1,5 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   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 +21,7 @@
 #define _PTHREAD_H	1
 
 #include <features.h>
+#include <endian.h>
 #include <sched.h>
 #include <time.h>
 
@@ -50,7 +52,7 @@ enum
   PTHREAD_MUTEX_RECURSIVE_NP,
   PTHREAD_MUTEX_ERRORCHECK_NP,
   PTHREAD_MUTEX_ADAPTIVE_NP
-#ifdef __USE_UNIX98
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
   ,
   PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
   PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
@@ -63,6 +65,30 @@ enum
 #endif
 };
 
+
+#ifdef __USE_XOPEN2K
+/* Robust mutex or not flags.  */
+enum
+{
+  PTHREAD_MUTEX_STALLED,
+  PTHREAD_MUTEX_STALLED_NP = PTHREAD_MUTEX_STALLED,
+  PTHREAD_MUTEX_ROBUST,
+  PTHREAD_MUTEX_ROBUST_NP = PTHREAD_MUTEX_ROBUST
+};
+#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 \
@@ -88,6 +114,7 @@ enum
 # endif
 #endif
 
+
 /* Read-write lock types.  */
 #if defined __USE_UNIX98 || defined __USE_XOPEN2K
 enum
@@ -99,21 +126,23 @@ enum
 };
 
 /* Read-write lock initializers.  */
-# if __WORDSIZE == 64
-#  define PTHREAD_RWLOCK_INITIALIZER \
+# define PTHREAD_RWLOCK_INITIALIZER \
   { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
-# else
-#  define PTHREAD_RWLOCK_INITIALIZER \
-  { { 0, 0, 0, 0, 0, 0, 0, 0 } }
-# endif
 # ifdef __USE_GNU
 #  if __WORDSIZE == 64
 #   define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
   { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,					      \
-      PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
+	PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
 #  else
-#   define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
-  { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 0 } }
+#   if __BYTE_ORDER == __LITTLE_ENDIAN
+#    define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+  { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, \
+      0, 0, 0, 0 } }
+#   else
+#    define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+  { { 0, 0, 0, 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,\
+      0 } }
+#   endif
 #  endif
 # endif
 #endif  /* Unix98 or XOpen2K */
@@ -201,7 +230,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.
 
@@ -251,71 +280,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
@@ -323,30 +359,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
@@ -354,19 +392,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
+   already running thread TH.  It shall be called on uninitialized 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
 
 
@@ -376,13 +417,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)
@@ -408,11 +449,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
 
 
@@ -426,7 +469,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.
@@ -538,9 +581,6 @@ 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
-__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame);
-
 __extern_inline void
 __pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
 {
@@ -603,7 +643,7 @@ __pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
     __pthread_unwind_buf_t __cancel_buf;				      \
     void (*__cancel_routine) (void *) = (routine);			      \
     void *__cancel_arg = (arg);						      \
-    int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *)		      \
+    int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *)	      \
 				      __cancel_buf.__cancel_jmp_buf, 0);      \
     if (__builtin_expect (not_first_call, 0))				      \
       {									      \
@@ -620,6 +660,7 @@ extern void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
 /* Remove a cleanup handler installed by the matching pthread_cleanup_push.
    If EXECUTE is non-zero, the handler function is called. */
 # define pthread_cleanup_pop(execute) \
+      do { } while (0);/* Empty to allow label before pthread_cleanup_pop.  */\
     } while (0);							      \
     __pthread_unregister_cancel (&__cancel_buf);			      \
     if (execute)							      \
@@ -637,7 +678,7 @@ extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
     __pthread_unwind_buf_t __cancel_buf;				      \
     void (*__cancel_routine) (void *) = (routine);			      \
     void *__cancel_arg = (arg);						      \
-    int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *)		      \
+    int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *)	      \
 				      __cancel_buf.__cancel_jmp_buf, 0);      \
     if (__builtin_expect (not_first_call, 0))				      \
       {									      \
@@ -655,6 +696,7 @@ extern void __pthread_register_cancel_defer (__pthread_unwind_buf_t *__buf)
    restores the cancellation type that was in effect when the matching
    pthread_cleanup_push_defer was called.  */
 #  define pthread_cleanup_pop_restore_np(execute) \
+      do { } while (0);/* Empty to allow label before pthread_cleanup_pop.  */\
     } while (0);							      \
     __pthread_unregister_cancel_restore (&__cancel_buf);		      \
     if (execute)							      \
@@ -666,9 +708,9 @@ 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
@@ -683,56 +725,135 @@ extern int __sigsetjmp (struct __jmp_buf_tag *__env, 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;
+				    __const struct timespec *__restrict
+				    __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));
+
+
+/* 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));
+
+
+#ifdef __USE_XOPEN2K8
+/* Declare the state protected by MUTEX as consistent.  */
+extern int pthread_mutex_consistent (pthread_mutex_t *__mutex)
+     __THROW __nonnull ((1));
+# ifdef __USE_GNU
+extern int pthread_mutex_consistent_np (pthread_mutex_t *__mutex)
+     __THROW __nonnull ((1));
+# endif
+#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
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
 /* 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));
+#endif
+
+/* 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));
+
+#ifdef __USE_XOPEN2K
+/* Get the robustness flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_getrobust (__const pthread_mutexattr_t *__attr,
+					int *__robustness)
+     __THROW __nonnull ((1, 2));
+# ifdef __USE_GNU
+extern int pthread_mutexattr_getrobust_np (__const pthread_mutexattr_t *__attr,
+					   int *__robustness)
+     __THROW __nonnull ((1, 2));
+# endif
+
+/* Set the robustness flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr,
+					int __robustness)
+     __THROW __nonnull ((1));
+# ifdef __USE_GNU
+extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
+					   int __robustness)
+     __THROW __nonnull ((1));
+# endif
 #endif
 
 
@@ -743,66 +864,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
 
 
@@ -812,16 +944,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.
@@ -829,7 +964,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
@@ -841,36 +977,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;
+					__restrict __attr,
+					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
 
 
@@ -880,19 +1019,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.  */
@@ -901,29 +1044,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
 
 
@@ -936,7 +1086,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;
@@ -946,13 +1097,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
 
 
@@ -971,6 +1123,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 */

+ 10 - 7
libpthread/nptl/sysdeps/pthread/pthread_barrier_wait.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -25,13 +25,14 @@
 
 /* Wait on barrier.  */
 int
-pthread_barrier_wait (pthread_barrier_t *barrier)
+pthread_barrier_wait (
+     pthread_barrier_t *barrier)
 {
   struct pthread_barrier *ibarrier = (struct pthread_barrier *) barrier;
   int result = 0;
 
   /* Make sure we are alone.  */
-  lll_lock (ibarrier->lock);
+  lll_lock (ibarrier->lock, ibarrier->private ^ FUTEX_PRIVATE_FLAG);
 
   /* One more arrival.  */
   --ibarrier->left;
@@ -44,7 +45,8 @@ pthread_barrier_wait (pthread_barrier_t *barrier)
       ++ibarrier->curr_event;
 
       /* Wake up everybody.  */
-      lll_futex_wake (&ibarrier->curr_event, INT_MAX);
+      lll_futex_wake (&ibarrier->curr_event, INT_MAX,
+		      ibarrier->private ^ FUTEX_PRIVATE_FLAG);
 
       /* This is the thread which finished the serialization.  */
       result = PTHREAD_BARRIER_SERIAL_THREAD;
@@ -56,11 +58,12 @@ pthread_barrier_wait (pthread_barrier_t *barrier)
       unsigned int event = ibarrier->curr_event;
 
       /* Before suspending, make the barrier available to others.  */
-      lll_unlock (ibarrier->lock);
+      lll_unlock (ibarrier->lock, ibarrier->private ^ FUTEX_PRIVATE_FLAG);
 
       /* Wait for the event counter of the barrier to change.  */
       do
-	lll_futex_wait (&ibarrier->curr_event, event);
+	lll_futex_wait (&ibarrier->curr_event, event,
+			ibarrier->private ^ FUTEX_PRIVATE_FLAG);
       while (event == ibarrier->curr_event);
     }
 
@@ -70,7 +73,7 @@ pthread_barrier_wait (pthread_barrier_t *barrier)
   /* If this was the last woken thread, unlock.  */
   if (atomic_increment_val (&ibarrier->left) == init_count)
     /* We are done.  */
-    lll_unlock (ibarrier->lock);
+    lll_unlock (ibarrier->lock, ibarrier->private ^ FUTEX_PRIVATE_FLAG);
 
   return result;
 }

+ 21 - 7
libpthread/nptl/sysdeps/pthread/pthread_cond_broadcast.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -23,14 +23,18 @@
 #include <lowlevellock.h>
 #include <pthread.h>
 #include <pthreadP.h>
+
 #include <bits/kernel-features.h>
 
 
 int
-__pthread_cond_broadcast (pthread_cond_t *cond)
+__pthread_cond_broadcast (
+     pthread_cond_t *cond)
 {
+  int pshared = (cond->__data.__mutex == (void *) ~0l)
+		? LLL_SHARED : LLL_PRIVATE;
   /* Make sure we are alone.  */
-  lll_mutex_lock (cond->__data.__lock);
+  lll_lock (cond->__data.__lock, pshared);
 
   /* Are there any waiters to be woken?  */
   if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
@@ -44,7 +48,7 @@ __pthread_cond_broadcast (pthread_cond_t *cond)
       ++cond->__data.__broadcast_seq;
 
       /* We are done.  */
-      lll_mutex_unlock (cond->__data.__lock);
+      lll_unlock (cond->__data.__lock, pshared);
 
       /* Do not use requeue for pshared condvars.  */
       if (cond->__data.__mutex == (void *) ~0l)
@@ -52,15 +56,24 @@ __pthread_cond_broadcast (pthread_cond_t *cond)
 
       /* Wake everybody.  */
       pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
+
+      /* XXX: Kernel so far doesn't support requeue to PI futex.  */
+      /* XXX: Kernel so far can only requeue to the same type of futex,
+	 in this case private (we don't requeue for pshared condvars).  */
+      if (__builtin_expect (mut->__data.__kind
+			    & (PTHREAD_MUTEX_PRIO_INHERIT_NP
+			       | PTHREAD_MUTEX_PSHARED_BIT), 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))
+					       futex_val, LLL_PRIVATE), 0))
 	{
 	  /* The requeue functionality is not available.  */
 	wake_all:
-	  lll_futex_wake (&cond->__data.__futex, INT_MAX);
+	  lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
 	}
 
       /* That's all.  */
@@ -68,8 +81,9 @@ __pthread_cond_broadcast (pthread_cond_t *cond)
     }
 
   /* We are done.  */
-  lll_mutex_unlock (cond->__data.__lock);
+  lll_unlock (cond->__data.__lock, pshared);
 
   return 0;
 }
+
 weak_alias(__pthread_cond_broadcast, pthread_cond_broadcast)

+ 16 - 5
libpthread/nptl/sysdeps/pthread/pthread_cond_signal.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -23,14 +23,19 @@
 #include <lowlevellock.h>
 #include <pthread.h>
 #include <pthreadP.h>
+
 #include <bits/kernel-features.h>
 
 
 int
-__pthread_cond_signal (pthread_cond_t *cond)
+__pthread_cond_signal (
+     pthread_cond_t *cond)
 {
+  int pshared = (cond->__data.__mutex == (void *) ~0l)
+		? LLL_SHARED : LLL_PRIVATE;
+
   /* Make sure we are alone.  */
-  lll_mutex_lock (cond->__data.__lock);
+  lll_lock (cond->__data.__lock, pshared);
 
   /* Are there any waiters to be woken?  */
   if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
@@ -40,12 +45,18 @@ __pthread_cond_signal (pthread_cond_t *cond)
       ++cond->__data.__futex;
 
       /* Wake one.  */
-      lll_futex_wake (&cond->__data.__futex, 1);
+      if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
+						     1, &cond->__data.__lock,
+						     pshared), 0))
+	return 0;
+
+      lll_futex_wake (&cond->__data.__futex, 1, pshared);
     }
 
   /* We are done.  */
-  lll_mutex_unlock (cond->__data.__lock);
+  lll_unlock (cond->__data.__lock, pshared);
 
   return 0;
 }
+
 weak_alias(__pthread_cond_signal, pthread_cond_signal)

+ 17 - 12
libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c

@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -23,6 +23,7 @@
 #include <lowlevellock.h>
 #include <pthread.h>
 #include <pthreadP.h>
+#include <bits/kernel-features.h>
 
 
 /* Cleanup handler, defined in pthread_cond_wait.c.  */
@@ -51,21 +52,24 @@ __pthread_cond_timedwait (
   if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
     return EINVAL;
 
+  int pshared = (cond->__data.__mutex == (void *) ~0l)
+		? LLL_SHARED : LLL_PRIVATE;
+
   /* Make sure we are along.  */
-  lll_mutex_lock (cond->__data.__lock);
+  lll_lock (cond->__data.__lock, pshared);
 
   /* Now we can release the mutex.  */
   int err = __pthread_mutex_unlock_usercnt (mutex, 0);
   if (err)
     {
-      lll_mutex_unlock (cond->__data.__lock);
+      lll_unlock (cond->__data.__lock, pshared);
       return err;
     }
 
   /* We have one new user of the condvar.  */
   ++cond->__data.__total_seq;
   ++cond->__data.__futex;
-  cond->__data.__nwaiters += 1 << COND_CLOCK_BITS;
+  cond->__data.__nwaiters += 1 << COND_NWAITERS_SHIFT;
 
   /* Remember the mutex we are using here.  If there is already a
      different address store this is a bad user bug.  Do not store
@@ -98,7 +102,7 @@ __pthread_cond_timedwait (
 	int ret;
 	ret = INTERNAL_SYSCALL (clock_gettime, err, 2,
 				(cond->__data.__nwaiters
-				 & ((1 << COND_CLOCK_BITS) - 1)),
+				 & ((1 << COND_NWAITERS_SHIFT) - 1)),
 				&rt);
 # ifndef __ASSUME_POSIX_TIMERS
 	if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (ret, err), 0))
@@ -144,20 +148,20 @@ __pthread_cond_timedwait (
       unsigned int futex_val = cond->__data.__futex;
 
       /* Prepare to wait.  Release the condvar futex.  */
-      lll_mutex_unlock (cond->__data.__lock);
+      lll_unlock (cond->__data.__lock, pshared);
 
       /* 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);
+				  futex_val, &rt, pshared);
 
       /* 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);
+      lll_lock (cond->__data.__lock, pshared);
 
       /* If a broadcast happened, we are done.  */
       if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
@@ -187,17 +191,17 @@ __pthread_cond_timedwait (
 
  bc_out:
 
-  cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;
+  cond->__data.__nwaiters -= 1 << COND_NWAITERS_SHIFT;
 
   /* If pthread_cond_destroy was called on this variable already,
      notify the pthread_cond_destroy caller all waiters have left
      and it can be successfully destroyed.  */
   if (cond->__data.__total_seq == -1ULL
-      && cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
-    lll_futex_wake (&cond->__data.__nwaiters, 1);
+      && cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
+    lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
 
   /* We are done with the condvar.  */
-  lll_mutex_unlock (cond->__data.__lock);
+  lll_unlock (cond->__data.__lock, pshared);
 
   /* The cancellation handling is back to normal, remove the handler.  */
   __pthread_cleanup_pop (&buffer, 0);
@@ -207,4 +211,5 @@ __pthread_cond_timedwait (
 
   return err ?: result;
 }
+
 weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait)

Some files were not shown because too many files changed in this diff