2006-07-28 Ulrich Drepper <drepper@redhat.com>
authorUlrich Drepper <drepper@redhat.com>
Sat, 29 Jul 2006 04:42:09 +0000 (04:42 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 29 Jul 2006 04:42:09 +0000 (04:42 +0000)
    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/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.

49 files changed:
nptl/ChangeLog
nptl/Makefile
nptl/descr.h
nptl/pthreadP.h
nptl/pthread_create.c
nptl/pthread_mutex_destroy.c
nptl/pthread_mutex_init.c
nptl/pthread_mutex_lock.c
nptl/pthread_mutex_setprioceiling.c
nptl/pthread_mutex_timedlock.c
nptl/pthread_mutex_trylock.c
nptl/pthread_mutex_unlock.c
nptl/sysdeps/pthread/pthread_cond_broadcast.c
nptl/sysdeps/unix/sysv/linux/Makefile
nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
nptl/tst-mutex1.c
nptl/tst-mutex2.c
nptl/tst-mutex3.c
nptl/tst-mutex4.c
nptl/tst-mutex5.c
nptl/tst-mutex6.c
nptl/tst-mutex7.c
nptl/tst-mutex7a.c
nptl/tst-mutex9.c
nptl/tst-mutexpi1.c [new file with mode: 0644]
nptl/tst-mutexpi2.c [new file with mode: 0644]
nptl/tst-mutexpi3.c [new file with mode: 0644]
nptl/tst-mutexpi4.c [new file with mode: 0644]
nptl/tst-mutexpi5.c [new file with mode: 0644]
nptl/tst-mutexpi5a.c [new file with mode: 0644]
nptl/tst-mutexpi6.c [new file with mode: 0644]
nptl/tst-mutexpi7.c [new file with mode: 0644]
nptl/tst-mutexpi7a.c [new file with mode: 0644]
nptl/tst-mutexpi8.c [new file with mode: 0644]
nptl/tst-mutexpi9.c [new file with mode: 0644]
nptl/tst-robust1.c
nptl/tst-robust7.c
nptl/tst-robust8.c
nptl/tst-robustpi1.c [new file with mode: 0644]
nptl/tst-robustpi2.c [new file with mode: 0644]
nptl/tst-robustpi3.c [new file with mode: 0644]
nptl/tst-robustpi4.c [new file with mode: 0644]
nptl/tst-robustpi5.c [new file with mode: 0644]
nptl/tst-robustpi6.c [new file with mode: 0644]
nptl/tst-robustpi7.c [new file with mode: 0644]
nptl/tst-robustpi8.c [new file with mode: 0644]

index 701b429..073106c 100644 (file)
@@ -1,3 +1,63 @@
+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/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
index 8229486..a4c6174 100644 (file)
@@ -200,6 +200,9 @@ tests = tst-typesizes \
        tst-attr1 tst-attr2 tst-attr3 \
        tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
        tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a \
+       tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
+       tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \
+       tst-mutexpi9 \
        tst-spin1 tst-spin2 tst-spin3 \
        tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
        tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
@@ -207,6 +210,8 @@ tests = tst-typesizes \
        tst-cond20 tst-cond21 \
        tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
        tst-robust6 tst-robust7 tst-robust8 \
+       tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 \
+       tst-robustpi5 tst-robustpi6 tst-robustpi7 tst-robustpi8 \
        tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
        tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
        tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
index f89d324..607aa9f 100644 (file)
@@ -155,23 +155,28 @@ struct pthread
      first.  */
 # define QUEUE_PTR_ADJUST (offsetof (__pthread_list_t, __next))
 
-# define ENQUEUE_MUTEX(mutex) \
+# define ENQUEUE_MUTEX_BOTH(mutex, val)                                              \
   do {                                                                       \
-    __pthread_list_t *next = (THREAD_GETMEM (THREAD_SELF, robust_head.list)   \
-                             - QUEUE_PTR_ADJUST);                            \
+    __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 = (void *) &next->__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,                            \
-                  &mutex->__data.__list.__next);                             \
+                  (void *) (((uintptr_t) &mutex->__data.__list.__next)       \
+                            | val));                                         \
   } while (0)
 # define DEQUEUE_MUTEX(mutex) \
   do {                                                                       \
     __pthread_list_t *next = (__pthread_list_t *)                            \
-      ((char *) mutex->__data.__list.__next - QUEUE_PTR_ADJUST);             \
+      ((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 *) mutex->__data.__list.__prev - QUEUE_PTR_ADJUST);             \
+      ((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;                                              \
@@ -183,27 +188,36 @@ struct pthread
     struct robust_list_head robust_head;
   };
 
-# define ENQUEUE_MUTEX(mutex) \
+# 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, &mutex->__data.__list);   \
+    THREAD_SETMEM (THREAD_SELF, robust_list.__next,                          \
+                  ((uintptr_t) &mutex->__data.__list) | val);                \
   } while (0)
 # define DEQUEUE_MUTEX(mutex) \
   do {                                                                       \
-    __pthread_slist_t *runp = THREAD_GETMEM (THREAD_SELF, robust_list.__next);\
+    __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                                                                     \
       {                                                                              \
-       while (runp->__next != &mutex->__data.__list)                         \
-         runp = runp->__next;                                                \
+       __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 = runp->__next->__next;                                  \
+       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;
index c7f57e2..dc98bb1 100644 (file)
@@ -61,6 +61,7 @@
 /* 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,
@@ -68,8 +69,24 @@ enum
   = 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_PRIVATE_NP = 32,
-  PTHREAD_MUTEX_PRIO_PROTECT_PRIVATE_NP = 64
+  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
 };
 #define PTHREAD_MUTEX_PRIO_CEILING_SHIFT       16
 #define PTHREAD_MUTEX_PRIO_CEILING_MASK                0x00ff0000
index 71365a1..c1ac199 100644 (file)
@@ -330,9 +330,11 @@ start_thread (void *arg)
 # else
   __pthread_slist_t *robust = pd->robust_list.__next;
 # endif
-/* We let the kernel do the notification if it is able to do so.  */
+  /* 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 != &pd->robust_head, 0))
+      && __builtin_expect (robust != (void *) &pd->robust_head, 0))
     {
       do
        {
@@ -348,7 +350,7 @@ start_thread (void *arg)
 
          lll_robust_mutex_dead (this->__lock);
        }
-      while (robust != &pd->robust_head);
+      while (robust != (void *) &pd->robust_head);
     }
 #endif
 
index 7829979..e2c9f8a 100644 (file)
@@ -30,7 +30,6 @@ __pthread_mutex_destroy (mutex)
     return EBUSY;
 
   /* Set to an invalid value.  */
- dead_robust_mutex:
   mutex->__data.__kind = -1;
 
   return 0;
index c3f9c2d..6ceca86 100644 (file)
@@ -29,6 +29,11 @@ static const struct pthread_mutexattr default_attr =
   };
 
 
+#ifndef __ASSUME_FUTEX_LOCK_PI
+static int tpi_supported;
+#endif
+
+
 int
 __pthread_mutex_init (mutex, mutexattr)
      pthread_mutex_t *mutex;
@@ -41,8 +46,7 @@ __pthread_mutex_init (mutex, mutexattr)
   imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr;
 
   /* Sanity checks.  */
-  // XXX For now we don't support priority inherited or priority protected
-  // XXX mutexes.
+  // XXX For now we don't support priority protected mutexes.
   switch (__builtin_expect (imutexattr->mutexkind
                            & PTHREAD_MUTEXATTR_PROTOCOL_MASK,
                            PTHREAD_PRIO_NONE
@@ -51,6 +55,22 @@ __pthread_mutex_init (mutex, mutexattr)
     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:
       return ENOTSUP;
     }
@@ -75,11 +95,11 @@ __pthread_mutex_init (mutex, mutexattr)
   switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
     {
     case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
-      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_PRIVATE_NP;
+      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP;
       break;
 
     case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
-      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_PRIVATE_NP;
+      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP;
       if (PTHREAD_MUTEX_PRIO_CEILING_MASK
          == PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
        mutex->__data.__kind |= (imutexattr->mutexkind
index 06eef49..5345766 100644 (file)
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include "pthreadP.h"
 #include <lowlevellock.h>
 
@@ -205,6 +206,134 @@ __pthread_mutex_lock (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.  */
+           INTERNAL_SYSCALL_DECL (__err);
+           int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                                     FUTEX_LOCK_PI, 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_nocancel ();
+             }
+
+           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,
+                             FUTEX_UNLOCK_PI, 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;
+
     default:
       /* Correct code cannot set any other type.  */
       return EINVAL;
index 999b635..3271f88 100644 (file)
@@ -30,7 +30,7 @@ pthread_mutex_setprioceiling (mutex, prioceiling, 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_PRIVATE_NP) == 0)
+  if ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0)
     return EINVAL;
 
   if (prioceiling < 0 || __builtin_expect (prioceiling > 255, 0))
index 7c48c7c..12f6c99 100644 (file)
@@ -35,7 +35,7 @@ pthread_mutex_timedlock (mutex, abstime)
   /* We must not check ABSTIME here.  If the thread does not block
      abstime must not be checked for a valid value.  */
 
-  switch (mutex->__data.__kind)
+  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
     {
       /* Recursive mutex.  */
     case PTHREAD_MUTEX_RECURSIVE_NP:
@@ -65,7 +65,7 @@ pthread_mutex_timedlock (mutex, abstime)
       /* 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 */
@@ -134,7 +134,7 @@ pthread_mutex_timedlock (mutex, abstime)
              ENQUEUE_MUTEX (mutex);
              THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 
-             /* Note that we deliberately exist here.  If we fall
+             /* 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.  */
@@ -194,6 +194,150 @@ pthread_mutex_timedlock (mutex, abstime)
       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.  */
+           INTERNAL_SYSCALL_DECL (__err);
+
+           int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                                     FUTEX_LOCK_PI, 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_nocancel (&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,
+                             FUTEX_UNLOCK_PI, 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;
+
     default:
       /* Correct code cannot set any other type.  */
       return EINVAL;
index 148a6e9..f3a1856 100644 (file)
@@ -152,7 +152,6 @@ __pthread_mutex_trylock (mutex)
              return EBUSY;
            }
 
-       robust:
          if (__builtin_expect (mutex->__data.__owner
                                == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
            {
@@ -175,6 +174,129 @@ __pthread_mutex_trylock (mutex)
 
       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.  */
+           INTERNAL_SYSCALL_DECL (__err);
+           int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                                     FUTEX_TRYLOCK_PI, 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,
+                             FUTEX_UNLOCK_PI, 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;
+      }
+
     default:
       /* Correct code cannot set any other type.  */
       return EINVAL;
index bf9aa76..2b5064f 100644 (file)
@@ -119,6 +119,89 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
 
+    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;
+
+    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;
+
+    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_mutex_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;
+
+    continue_pi:
+      if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
+       {
+         /* 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);
+       }
+
+      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_acq (&mutex->__data.__lock, 0,
+                                                  THREAD_GETMEM (THREAD_SELF,
+                                                                 tid)))
+       {
+         INTERNAL_SYSCALL_DECL (__err);
+         INTERNAL_SYSCALL (futex, __err, 2, &mutex->__data.__lock,
+                           FUTEX_UNLOCK_PI);
+       }
+
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+      break;
+
     default:
       /* Correct code cannot set any other type.  */
       return EINVAL;
index 1eac8ec..2b8b546 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -55,6 +55,12 @@ __pthread_cond_broadcast (cond)
 
       /* Wake everybody.  */
       pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
+
+      /* XXX: Kernel so far doesn't support requeue to PI futex.  */
+      if (__builtin_expect (mut->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP,
+                           0))
+       goto wake_all;
+
       /* lll_futex_requeue returns 0 for success and non-zero
         for errors.  */
       if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1,
index 88dce1a..cfcdb6d 100644 (file)
@@ -25,7 +25,7 @@ libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock
 
 gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
                        lowlevelbarrier.sym unwindbuf.sym \
-                       lowlevelrobustlock.sym
+                       lowlevelrobustlock.sym pthread-pi-defines.sym
 endif
 
 ifeq ($(subdir),posix)
index 92c2d32..d8eced1 100644 (file)
@@ -1,5 +1,5 @@
 /* Define POSIX options for Linux.
-   Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -79,6 +79,9 @@
 /* We support user-defined stacks.  */
 #define _POSIX_THREAD_ATTR_STACKADDR   200112L
 
+/* We support priority inheritence.  */
+#define _POSIX_THREAD_PRIO_INHERIT     200112L
+
 /* We support POSIX.1b semaphores.  */
 #define _POSIX_SEMAPHORES      200112L
 
 /* Typed memory objects are not available.  */
 #define _POSIX_TYPED_MEMORY_OBJECTS    -1
 
-/* No support for priority inheritance or protection so far.  */
-#define _POSIX_THREAD_PRIO_INHERIT     -1
+/* No support for priority protection so far.  */
 #define _POSIX_THREAD_PRIO_PROTECT     -1
 
 #endif /* posix_opt.h */
index 5471c1c..56f7be8 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -21,6 +21,7 @@
 #include <shlib-compat.h>
 #include <lowlevelcond.h>
 #include <kernel-features.h>
+#include <pthread-pi-defines.h>
 
 #ifdef UP
 # define LOCK
@@ -94,6 +95,10 @@ __pthread_cond_broadcast:
 8:     cmpl    $-1, %edi
        je      9f
 
+       /* XXX: The kernel so far doesn't support requeue to PI futex.  */
+       testl   $PI_BIT, MUTEX_KIND(%edi)
+       jne     9f
+
        /* Wake up all threads.  */
        movl    $FUTEX_CMP_REQUEUE, %ecx
        movl    $SYS_futex, %eax
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym b/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
new file mode 100644 (file)
index 0000000..a1b6794
--- /dev/null
@@ -0,0 +1,6 @@
+#include <pthreadP.h>
+
+-- These PI macros are used by assembly code.
+
+MUTEX_KIND     offsetof (pthread_mutex_t, __data.__kind)
+PI_BIT         PTHREAD_MUTEX_PRIO_INHERIT_NP
index 72e7bc5..006de26 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -21,6 +21,7 @@
 #include <shlib-compat.h>
 #include <lowlevelcond.h>
 #include <kernel-features.h>
+#include <pthread-pi-defines.h>
 
 #ifdef UP
 # define LOCK
@@ -80,6 +81,10 @@ __pthread_cond_broadcast:
 8:     cmpq    $-1, %r8
        je      9f
 
+       /* XXX: The kernel so far doesn't support requeue to PI futex.  */
+       testl   $PI_BIT, MUTEX_KIND(%r8)
+       jne     9f
+
        /* Wake up all threads.  */
        movl    $FUTEX_CMP_REQUEUE, %esi
        movl    $SYS_futex, %eax
index 50b5cca..c3ef5b2 100644 (file)
@@ -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.
 
 
 #include <pthread.h>
 #include <stdio.h>
+#include <errno.h>
+
+
+#ifndef ATTR
+# define ATTR NULL
+#endif
 
 
 static int
@@ -26,12 +32,24 @@ do_test (void)
 {
   pthread_mutex_t m;
 
-  if (pthread_mutex_init (&m, NULL) != 0)
+  int e = pthread_mutex_init (&m, ATTR);
+  if (ATTR != NULL && e == ENOTSUP)
+    {
+      puts ("cannot support selected type of mutexes");
+      return 0;
+    }
+  else if (e != 0)
     {
       puts ("mutex_init failed");
       return 1;
     }
 
+  if (ATTR != NULL && pthread_mutexattr_destroy (ATTR) != 0)
+    {
+      puts ("mutexattr_destroy failed");
+      return 1;
+    }
+
   if (pthread_mutex_lock (&m) != 0)
     {
       puts ("mutex_lock failed");
index f589a1e..b09f569 100644 (file)
@@ -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.
 
@@ -105,115 +105,134 @@ do_test (void)
   if (pthread_mutexattr_init (&a) != 0)
     {
       puts ("mutexattr_init failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_ERRORCHECK) != 0)
     {
       puts ("mutexattr_settype failed");
-      exit (1);
+      return 1;
     }
 
-  if (pthread_mutex_init (&m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  e = pthread_mutex_init (&m, &a);
+  if (e != 0)
+    {
+#ifdef ENABLE_PI
+      if (e == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_barrier_init (&b, NULL, 2) != 0)
     {
       puts ("barrier_init failed");
-      exit (1);
+      return 1;
     }
 
-  if ((e = pthread_mutex_unlock (&m)) == 0)
+  e = pthread_mutex_unlock (&m);
+  if (e == 0)
     {
       puts ("1st mutex_unlock succeeded");
-      exit (1);
+      return 1;
     }
   else if (e != EPERM)
     {
       puts ("1st mutex_unlock error != EPERM");
-      exit (1);
+      return 1;
     }
 
   if (pthread_mutex_lock (&m) != 0)
     {
       puts ("mutex_lock failed");
-      exit (1);
+      return 1;
     }
 
-  if ((e = pthread_mutex_lock (&m)) == 0)
+  e = pthread_mutex_lock (&m);
+  if (e == 0)
     {
       puts ("2nd mutex_lock succeeded");
-      exit (1);
+      return 1;
     }
   else if (e != EDEADLK)
     {
       puts ("2nd mutex_lock error != EDEADLK");
-      exit (1);
+      return 1;
     }
 
   pthread_t th;
   if (pthread_create (&th, NULL, tf, NULL) != 0)
     {
       puts ("create failed");
-      exit (1);
+      return 1;
     }
 
   e = pthread_barrier_wait (&b);
   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
     {
       puts ("1st barrier_wait failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_mutex_unlock (&m) != 0)
     {
       puts ("2nd mutex_unlock failed");
-      exit (1);
+      return 1;
     }
 
-  if ((e = pthread_mutex_unlock (&m)) == 0)
+  e = pthread_mutex_unlock (&m);
+  if (e == 0)
     {
       puts ("3rd mutex_unlock succeeded");
-      exit (1);
+      return 1;
     }
   else if (e != EPERM)
     {
       puts ("3rd mutex_unlock error != EPERM");
-      exit (1);
+      return 1;
     }
 
   e = pthread_barrier_wait (&b);
   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
     {
       puts ("2nd barrier_wait failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_join (th, NULL) != 0)
     {
       puts ("join failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_mutex_destroy (&m) != 0)
     {
       puts ("mutex_destroy failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_barrier_destroy (&b) != 0)
     {
       puts ("barrier_destroy failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_mutexattr_destroy (&a) != 0)
     {
       puts ("mutexattr_destroy failed");
-      exit (1);
+      return 1;
     }
 
   return 0;
index 8e57924..2848096 100644 (file)
@@ -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.
 
@@ -113,8 +113,25 @@ do_test (void)
       return 1;
     }
 
-  if (pthread_mutex_init (&m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  int e;
+  e = pthread_mutex_init (&m, &a);
+  if (e != 0)
+    {
+#ifdef ENABLE_PI
+      if (e == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
       return 1;
     }
@@ -162,7 +179,7 @@ do_test (void)
       return 1;
     }
 
-  int e = pthread_barrier_wait (&b);
+  e = pthread_barrier_wait (&b);
   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
     {
       puts ("barrier_wait failed");
index 0ce7313..9699c2d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -42,6 +42,8 @@ do_test (void)
   char *p;
   int err;
   int s;
+  pthread_barrier_t *b;
+  pthread_barrierattr_t ba;
 
   fd = mkstemp (tmpfname);
   if (fd == -1)
@@ -70,9 +72,12 @@ do_test (void)
       return 1;
     }
 
-  m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t))
+  m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t) - 1)
                           & ~(__alignof (pthread_mutex_t) - 1));
-  p = (char *) (m + 1);
+  b = (pthread_barrier_t *) (((uintptr_t) (m + 1)
+                             + __alignof (pthread_barrier_t) - 1)
+                            & ~(__alignof (pthread_barrier_t) - 1));
+  p = (char *) (b + 1);
 
   if (pthread_mutexattr_init (&a) != 0)
     {
@@ -110,8 +115,23 @@ do_test (void)
       return 1;
     }
 
-  if (pthread_mutex_init (m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  if ((err = pthread_mutex_init (m, &a)) != 0)
+    {
+#ifdef ENABLE_PI
+      if (err == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
       return 1;
     }
@@ -128,6 +148,30 @@ do_test (void)
       return 1;
     }
 
+  if (pthread_barrierattr_init (&ba) != 0)
+    {
+      puts ("barrierattr_init failed");
+      return 1;
+    }
+
+  if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0)
+    {
+      puts ("barrierattr_setpshared failed");
+      return 1;
+    }
+
+  if (pthread_barrier_init (b, &ba, 2) != 0)
+    {
+      puts ("barrier_init failed");
+      return 1;
+    }
+
+  if (pthread_barrierattr_destroy (&ba) != 0)
+    {
+      puts ("barrierattr_destroy failed");
+      return 1;
+    }
+
   err = pthread_mutex_trylock (m);
   if (err == 0)
     {
@@ -142,6 +186,12 @@ do_test (void)
 
   *p = 0;
 
+  if (pthread_mutex_unlock (m) != 0)
+    {
+      puts ("parent: 1st mutex_unlock failed");
+      return 1;
+    }
+
   puts ("going to fork now");
   pid = fork ();
   if (pid == -1)
@@ -151,7 +201,19 @@ do_test (void)
     }
   else if (pid == 0)
     {
-      /* Play some lock ping-pong.  It's our turn to unlock first.  */
+      if (pthread_mutex_lock (m) != 0)
+       {
+         puts ("child: mutex_lock failed");
+         return 1;
+       }
+
+      int e = pthread_barrier_wait (b);
+      if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+       {
+         puts ("child: barrier_wait failed");
+         return 1;
+       }
+
       if ((*p)++ != 0)
        {
          puts ("child: *p != 0");
@@ -160,7 +222,7 @@ do_test (void)
 
       if (pthread_mutex_unlock (m) != 0)
        {
-         puts ("child: 1st mutex_unlock failed");
+         puts ("child: mutex_unlock failed");
          return 1;
        }
 
@@ -168,6 +230,13 @@ do_test (void)
     }
   else
     {
+      int e = pthread_barrier_wait (b);
+      if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+       {
+         puts ("parent: barrier_wait failed");
+         return 1;
+       }
+
       if (pthread_mutex_lock (m) != 0)
        {
          puts ("parent: 2nd mutex_lock failed");
@@ -180,6 +249,24 @@ do_test (void)
          return 1;
        }
 
+      if (pthread_mutex_unlock (m) != 0)
+       {
+         puts ("parent: 2nd mutex_unlock failed");
+         return 1;
+       }
+
+      if (pthread_mutex_destroy (m) != 0)
+       {
+         puts ("mutex_destroy failed");
+         return 1;
+       }
+
+      if (pthread_barrier_destroy (b) != 0)
+       {
+         puts ("barrier_destroy failed");
+         return 1;
+       }
+
       puts ("parent done");
     }
 
index eb35b78..291274f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -52,8 +52,24 @@ do_test (void)
       return 1;
     }
 
-  if (pthread_mutex_init (&m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  err = pthread_mutex_init (&m, &a);
+  if (err != 0)
+    {
+#ifdef ENABLE_PI
+      if (err == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
       return 1;
     }
index f066c62..e5698c3 100644 (file)
@@ -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.
 
 #include <signal.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <errno.h>
+
+
+#ifndef ATTR
+# define ATTR NULL
+#endif
 
 
 static int
@@ -28,12 +34,24 @@ do_test (void)
 {
   pthread_mutex_t m;
 
-  if (pthread_mutex_init (&m, NULL) != 0)
+  int e = pthread_mutex_init (&m, ATTR);
+  if (ATTR != NULL && e == ENOTSUP)
+    {
+      puts ("cannot support selected type of mutexes");
+      e = pthread_mutex_init (&m, NULL);
+    }
+  if (e != 0)
     {
       puts ("mutex_init failed");
       return 1;
     }
 
+  if (ATTR != NULL && pthread_mutexattr_destroy (ATTR) != 0)
+    {
+      puts ("mutexattr_destroy failed");
+      return 1;
+    }
+
   if (pthread_mutex_lock (&m) != 0)
     {
       puts ("1st mutex_lock failed");
index a9b9f31..27e5d8e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <errno.h>
 #include <pthread.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <time.h>
 
 
-#ifndef INIT
-# define INIT PTHREAD_MUTEX_INITIALIZER
+#ifndef TYPE
+# define TYPE PTHREAD_MUTEX_DEFAULT
 #endif
 
 
-static pthread_mutex_t lock = INIT;
+static pthread_mutex_t lock;
 
 
 #define ROUNDS 1000
@@ -65,6 +67,48 @@ tf (void *arg)
 static int
 do_test (void)
 {
+  pthread_mutexattr_t a;
+
+  if (pthread_mutexattr_init (&a) != 0)
+    {
+      puts ("mutexattr_init failed");
+      exit (1);
+    }
+
+  if (pthread_mutexattr_settype (&a, TYPE) != 0)
+    {
+      puts ("mutexattr_settype failed");
+      exit (1);
+    }
+
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  int e = pthread_mutex_init (&lock, &a);
+  if (e != 0)
+    {
+#ifdef ENABLE_PI
+      if (e == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
+      puts ("mutex_init failed");
+      return 1;
+    }
+
+  if (pthread_mutexattr_destroy (&a) != 0)
+    {
+      puts ("mutexattr_destroy failed");
+      return 1;
+    }
+
   pthread_attr_t at;
   pthread_t th[N];
   int cnt;
index f08799a..30d46b8 100644 (file)
@@ -1,2 +1,2 @@
-#define INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+#define TYPE PTHREAD_MUTEX_ADAPTIVE_NP
 #include "tst-mutex7.c"
index 5ea2f0a..f9d3793 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -88,8 +88,24 @@ do_test (void)
       return 1;
     }
 
-  if (pthread_mutex_init (m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  int e;
+  if ((e = pthread_mutex_init (m, &a)) != 0)
+    {
+#ifdef ENABLE_PI
+      if (e == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
       return 1;
     }
@@ -138,7 +154,7 @@ do_test (void)
          ts.tv_nsec -= 1000000000;
        }
 
-      int e = pthread_mutex_timedlock (m, &ts);
+      e = pthread_mutex_timedlock (m, &ts);
       if (e == 0)
        {
          puts ("child: mutex_timedlock succeeded");
diff --git a/nptl/tst-mutexpi1.c b/nptl/tst-mutexpi1.c
new file mode 100644 (file)
index 0000000..623ede9
--- /dev/null
@@ -0,0 +1,27 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_mutexattr_t a;
+
+static void
+prepare (void)
+{
+  if (pthread_mutexattr_init (&a) != 0)
+    {
+      puts ("mutexattr_init failed");
+      exit (1);
+    }
+
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("mutexattr_setprotocol failed");
+      exit (1);
+    }
+}
+#define PREPARE(argc, argv) prepare ()
+
+
+#define ATTR &a
+#include "tst-mutex1.c"
diff --git a/nptl/tst-mutexpi2.c b/nptl/tst-mutexpi2.c
new file mode 100644 (file)
index 0000000..fbe4871
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex2.c"
diff --git a/nptl/tst-mutexpi3.c b/nptl/tst-mutexpi3.c
new file mode 100644 (file)
index 0000000..e338ebf
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex3.c"
diff --git a/nptl/tst-mutexpi4.c b/nptl/tst-mutexpi4.c
new file mode 100644 (file)
index 0000000..177b17b
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex4.c"
diff --git a/nptl/tst-mutexpi5.c b/nptl/tst-mutexpi5.c
new file mode 100644 (file)
index 0000000..287465c
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex5.c"
diff --git a/nptl/tst-mutexpi5a.c b/nptl/tst-mutexpi5a.c
new file mode 100644 (file)
index 0000000..2f85c94
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex5a.c"
diff --git a/nptl/tst-mutexpi6.c b/nptl/tst-mutexpi6.c
new file mode 100644 (file)
index 0000000..42cda37
--- /dev/null
@@ -0,0 +1,27 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_mutexattr_t a;
+
+static void
+prepare (void)
+{
+  if (pthread_mutexattr_init (&a) != 0)
+    {
+      puts ("mutexattr_init failed");
+      exit (1);
+    }
+
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("mutexattr_setprotocol failed");
+      exit (1);
+    }
+}
+#define PREPARE(argc, argv) prepare ()
+
+
+#define ATTR &a
+#include "tst-mutex6.c"
diff --git a/nptl/tst-mutexpi7.c b/nptl/tst-mutexpi7.c
new file mode 100644 (file)
index 0000000..1e7e929
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex7.c"
diff --git a/nptl/tst-mutexpi7a.c b/nptl/tst-mutexpi7a.c
new file mode 100644 (file)
index 0000000..c59083c
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex7a.c"
diff --git a/nptl/tst-mutexpi8.c b/nptl/tst-mutexpi8.c
new file mode 100644 (file)
index 0000000..cea6030
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex8.c"
diff --git a/nptl/tst-mutexpi9.c b/nptl/tst-mutexpi9.c
new file mode 100644 (file)
index 0000000..3710d9e
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex9.c"
index 9806ca4..bc48700 100644 (file)
@@ -97,6 +97,30 @@ do_test (void)
       puts ("mutexattr_setrobust failed");
       return 1;
     }
+
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+  else
+    {
+      int e = pthread_mutex_init (&m1, &a);
+      if (e == ENOTSUP)
+       {
+         puts ("PI robust mutexes not supported");
+         return 0;
+       }
+      else if (e != 0)
+       {
+         puts ("mutex_init m1 failed");
+         return 1;
+       }
+      pthread_mutex_destroy (&m1);
+    }
+#endif
+
 #ifndef NOT_CONSISTENT
   if (pthread_mutex_init (&m1, &a) != 0)
     {
@@ -236,14 +260,14 @@ do_test (void)
       e = pthread_mutex_unlock (&m1);
       if (e != 0)
        {
-         printf ("%ld: mutex_unlock m1 failed\n", round);
+         printf ("%ld: mutex_unlock m1 failed with %d\n", round, e);
          return 1;
        }
 
       e = pthread_mutex_unlock (&m2);
       if (e != 0)
        {
-         printf ("%ld: mutex_unlock m2 failed\n", round);
+         printf ("%ld: mutex_unlock m2 failed with %d\n", round, e);
          return 1;
        }
 
index 2c5acb4..d0bc91c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
 
@@ -95,8 +95,25 @@ do_test (void)
       return 1;
     }
 
-  if (pthread_mutex_init (&m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  int e;
+  e = pthread_mutex_init (&m, &a);
+  if (e != 0)
+    {
+#ifdef ENABLE_PI
+      if (e == ENOTSUP)
+       {
+         puts ("PI robust mutexes not supported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
       return 1;
     }
@@ -123,7 +140,7 @@ do_test (void)
          return 1;
        }
 
-      int e = pthread_barrier_wait (&b);
+      e = pthread_barrier_wait (&b);
       if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
        {
          printf ("parent: barrier_wait failed in round %ld\n", n + 1);
@@ -164,7 +181,7 @@ do_test (void)
        }
     }
 
-  int e = pthread_mutex_lock (&m);
+  e = pthread_mutex_lock (&m);
   if (e == 0)
     {
       puts ("parent: 2nd mutex_lock succeeded");
index 19682e5..9c63625 100644 (file)
@@ -15,7 +15,7 @@ static void prepare (void);
 #define PREPARE(argc, argv) prepare ()
 static int do_test (void);
 #define TEST_FUNCTION do_test ()
-#define TIMEOUT 3
+#define TIMEOUT 5
 #include "../test-skeleton.c"
 
 
@@ -173,6 +173,13 @@ do_test (void)
       puts ("mutexattr_setpshared failed");
       return 1;
     }
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
 
   for (int round = 1; round <= ROUNDS; ++round)
     {
@@ -181,7 +188,11 @@ do_test (void)
          int e = pthread_mutex_init (&map[n], &ma);
          if (e == ENOTSUP)
            {
+#ifdef ENABLE_PI
+             puts ("cannot support pshared robust PI mutexes");
+#else
              puts ("cannot support pshared robust mutexes");
+#endif
              return 0;
            }
          if (e != 0)
diff --git a/nptl/tst-robustpi1.c b/nptl/tst-robustpi1.c
new file mode 100644 (file)
index 0000000..031291b
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust1.c"
diff --git a/nptl/tst-robustpi2.c b/nptl/tst-robustpi2.c
new file mode 100644 (file)
index 0000000..ac411c7
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust2.c"
diff --git a/nptl/tst-robustpi3.c b/nptl/tst-robustpi3.c
new file mode 100644 (file)
index 0000000..7dcf691
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust3.c"
diff --git a/nptl/tst-robustpi4.c b/nptl/tst-robustpi4.c
new file mode 100644 (file)
index 0000000..6c7b0aa
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust4.c"
diff --git a/nptl/tst-robustpi5.c b/nptl/tst-robustpi5.c
new file mode 100644 (file)
index 0000000..a494c33
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust5.c"
diff --git a/nptl/tst-robustpi6.c b/nptl/tst-robustpi6.c
new file mode 100644 (file)
index 0000000..3b1482f
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust6.c"
diff --git a/nptl/tst-robustpi7.c b/nptl/tst-robustpi7.c
new file mode 100644 (file)
index 0000000..f8892f3
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust7.c"
diff --git a/nptl/tst-robustpi8.c b/nptl/tst-robustpi8.c
new file mode 100644 (file)
index 0000000..cbea3d6
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust8.c"