summaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2006-07-29 23:12:43 +0000
committerRoland McGrath <roland@gnu.org>2006-07-29 23:12:43 +0000
commitab5823b4b6e760345d347b98830ccc75aa81bff6 (patch)
treef9b25d5f9a16e7ce0318aaf3adcccec0e83fd804 /nptl
parentaa583d2ff9fca922771d88f1afa255847f2aa4ed (diff)
Updated to fedora-glibc-20060729T2255cvs/fedora-glibc-2_4_90-14
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog66
-rw-r--r--nptl/Makefile5
-rw-r--r--nptl/descr.h40
-rw-r--r--nptl/pthreadP.h21
-rw-r--r--nptl/pthread_create.c8
-rw-r--r--nptl/pthread_mutex_destroy.c1
-rw-r--r--nptl/pthread_mutex_init.c28
-rw-r--r--nptl/pthread_mutex_lock.c129
-rw-r--r--nptl/pthread_mutex_setprioceiling.c2
-rw-r--r--nptl/pthread_mutex_timedlock.c150
-rw-r--r--nptl/pthread_mutex_trylock.c124
-rw-r--r--nptl/pthread_mutex_unlock.c83
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_broadcast.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/Makefile2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S7
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S7
-rw-r--r--nptl/tst-mutex1.c22
-rw-r--r--nptl/tst-mutex2.c67
-rw-r--r--nptl/tst-mutex3.c23
-rw-r--r--nptl/tst-mutex4.c99
-rw-r--r--nptl/tst-mutex5.c20
-rw-r--r--nptl/tst-mutex6.c22
-rw-r--r--nptl/tst-mutex7.c52
-rw-r--r--nptl/tst-mutex7a.c2
-rw-r--r--nptl/tst-mutex9.c22
-rw-r--r--nptl/tst-mutexpi1.c27
-rw-r--r--nptl/tst-mutexpi2.c2
-rw-r--r--nptl/tst-mutexpi3.c2
-rw-r--r--nptl/tst-mutexpi4.c2
-rw-r--r--nptl/tst-mutexpi5.c2
-rw-r--r--nptl/tst-mutexpi5a.c2
-rw-r--r--nptl/tst-mutexpi6.c27
-rw-r--r--nptl/tst-mutexpi7.c2
-rw-r--r--nptl/tst-mutexpi7a.c2
-rw-r--r--nptl/tst-mutexpi8.c2
-rw-r--r--nptl/tst-mutexpi9.c2
-rw-r--r--nptl/tst-robust1.c28
-rw-r--r--nptl/tst-robust7.c25
-rw-r--r--nptl/tst-robust8.c13
-rw-r--r--nptl/tst-robustpi1.c2
-rw-r--r--nptl/tst-robustpi2.c2
-rw-r--r--nptl/tst-robustpi3.c2
-rw-r--r--nptl/tst-robustpi4.c2
-rw-r--r--nptl/tst-robustpi5.c2
-rw-r--r--nptl/tst-robustpi6.c2
-rw-r--r--nptl/tst-robustpi7.c2
-rw-r--r--nptl/tst-robustpi8.c2
57 files changed, 1113 insertions, 89 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 02b4c2f191..b9705ee065 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,69 @@
+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
diff --git a/nptl/Makefile b/nptl/Makefile
index e430b8d6cb..6a80bc1183 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -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 \
diff --git a/nptl/descr.h b/nptl/descr.h
index f89d3240da..607aa9fcdb 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -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;
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index c7f57e235a..dc98bb19c0 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -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
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 71365a17e8..c1ac199bb9 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -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
diff --git a/nptl/pthread_mutex_destroy.c b/nptl/pthread_mutex_destroy.c
index 7829979f35..e2c9f8a39f 100644
--- a/nptl/pthread_mutex_destroy.c
+++ b/nptl/pthread_mutex_destroy.c
@@ -30,7 +30,6 @@ __pthread_mutex_destroy (mutex)
return EBUSY;
/* Set to an invalid value. */
- dead_robust_mutex:
mutex->__data.__kind = -1;
return 0;
diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c
index c3f9c2d1c0..6ceca86052 100644
--- a/nptl/pthread_mutex_init.c
+++ b/nptl/pthread_mutex_init.c
@@ -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
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index 06eef49c71..5345766883 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.c
@@ -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;
diff --git a/nptl/pthread_mutex_setprioceiling.c b/nptl/pthread_mutex_setprioceiling.c
index 999b635ac1..3271f8833a 100644
--- a/nptl/pthread_mutex_setprioceiling.c
+++ b/nptl/pthread_mutex_setprioceiling.c
@@ -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))
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index 7c48c7ce6b..12f6c997bb 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -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;
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 148a6e919f..f3a18569a1 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -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;
diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
index bf9aa7625f..2b5064fbac 100644
--- a/nptl/pthread_mutex_unlock.c
+++ b/nptl/pthread_mutex_unlock.c
@@ -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;
diff --git a/nptl/sysdeps/pthread/pthread_cond_broadcast.c b/nptl/sysdeps/pthread/pthread_cond_broadcast.c
index 1eac8ecf83..2b8b5460f4 100644
--- a/nptl/sysdeps/pthread/pthread_cond_broadcast.c
+++ b/nptl/sysdeps/pthread/pthread_cond_broadcast.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@@ -55,6 +55,12 @@ __pthread_cond_broadcast (cond)
/* Wake everybody. */
pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
+
+ /* XXX: Kernel so far doesn't support requeue to PI futex. */
+ if (__builtin_expect (mut->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP,
+ 0))
+ goto wake_all;
+
/* lll_futex_requeue returns 0 for success and non-zero
for errors. */
if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1,
diff --git a/nptl/sysdeps/unix/sysv/linux/Makefile b/nptl/sysdeps/unix/sysv/linux/Makefile
index 88dce1a886..cfcdb6d97f 100644
--- a/nptl/sysdeps/unix/sysv/linux/Makefile
+++ b/nptl/sysdeps/unix/sysv/linux/Makefile
@@ -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)
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
index 1a2e8cbb07..58b4806eb2 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
@@ -33,6 +33,9 @@
#define FUTEX_CMP_REQUEUE 4
#define FUTEX_WAKE_OP 5
#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
diff --git a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
index 92c2d32827..d8eced1f22 100644
--- a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
+++ b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
@@ -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
@@ -171,8 +174,7 @@
/* 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 */
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
index 5471c1c927..56f7be8246 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -21,6 +21,7 @@
#include <shlib-compat.h>
#include <lowlevelcond.h>
#include <kernel-features.h>
+#include <pthread-pi-defines.h>
#ifdef UP
# define LOCK
@@ -94,6 +95,10 @@ __pthread_cond_broadcast:
8: cmpl $-1, %edi
je 9f
+ /* XXX: The kernel so far doesn't support requeue to PI futex. */
+ testl $PI_BIT, MUTEX_KIND(%edi)
+ jne 9f
+
/* Wake up all threads. */
movl $FUTEX_CMP_REQUEUE, %ecx
movl $SYS_futex, %eax
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
index e405f84f25..64088ef732 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
@@ -35,6 +35,9 @@
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
/* Initializer for compatibility lock. */
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
index ece9a7fc72..8df997a262 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
@@ -33,6 +33,9 @@
#define FUTEX_CMP_REQUEUE 4
#define FUTEX_WAKE_OP 5
#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
/* Delay in spinlock loop. */
#define BUSY_WAIT_NOP asm ("hint @pause")
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
index abd019df47..0136b97595 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
@@ -35,6 +35,9 @@
#define FUTEX_CMP_REQUEUE 4
#define FUTEX_WAKE_OP 5
#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym b/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
new file mode 100644
index 0000000000..a1b6794260
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
@@ -0,0 +1,6 @@
+#include <pthreadP.h>
+
+-- These PI macros are used by assembly code.
+
+MUTEX_KIND offsetof (pthread_mutex_t, __data.__kind)
+PI_BIT PTHREAD_MUTEX_PRIO_INHERIT_NP
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
index 6baab90f56..38d9f2ac41 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
@@ -32,6 +32,9 @@
#define FUTEX_CMP_REQUEUE 4
#define FUTEX_WAKE_OP 5
#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
index 92f93cd5f5..0eb1f0114c 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
@@ -26,6 +26,9 @@
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
/* Initializer for compatibility lock. */
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
index 77eefc546c..5013922a2f 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
@@ -32,6 +32,9 @@
#define FUTEX_CMP_REQUEUE 4
#define FUTEX_WAKE_OP 5
#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index 5047e4fe4d..7da2f12231 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
@@ -35,6 +35,9 @@
#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
/* Initializer for compatibility lock. */
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
index 72e7bc5b24..006de2696e 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 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
diff --git a/nptl/tst-mutex1.c b/nptl/tst-mutex1.c
index 50b5ccaf0e..c3ef5b2b51 100644
--- a/nptl/tst-mutex1.c
+++ b/nptl/tst-mutex1.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.
@@ -19,6 +19,12 @@
#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");
diff --git a/nptl/tst-mutex2.c b/nptl/tst-mutex2.c
index f589a1ea17..b09f569a5a 100644
--- a/nptl/tst-mutex2.c
+++ b/nptl/tst-mutex2.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.
@@ -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;
diff --git a/nptl/tst-mutex3.c b/nptl/tst-mutex3.c
index 8e57924ba6..2848096538 100644
--- a/nptl/tst-mutex3.c
+++ b/nptl/tst-mutex3.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.
@@ -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");
diff --git a/nptl/tst-mutex4.c b/nptl/tst-mutex4.c
index 0ce7313caf..9699c2db45 100644
--- a/nptl/tst-mutex4.c
+++ b/nptl/tst-mutex4.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -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");
}
diff --git a/nptl/tst-mutex5.c b/nptl/tst-mutex5.c
index eb35b78d36..291274fee5 100644
--- a/nptl/tst-mutex5.c
+++ b/nptl/tst-mutex5.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -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;
}
diff --git a/nptl/tst-mutex6.c b/nptl/tst-mutex6.c
index f066c62edc..e5698c3eb0 100644
--- a/nptl/tst-mutex6.c
+++ b/nptl/tst-mutex6.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.
@@ -21,6 +21,12 @@
#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");
diff --git a/nptl/tst-mutex7.c b/nptl/tst-mutex7.c
index a9b9f318cb..27e5d8eb28 100644
--- a/nptl/tst-mutex7.c
+++ b/nptl/tst-mutex7.c
@@ -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.
@@ -17,17 +17,19 @@
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;
diff --git a/nptl/tst-mutex7a.c b/nptl/tst-mutex7a.c
index f08799ae79..30d46b81af 100644
--- a/nptl/tst-mutex7a.c
+++ b/nptl/tst-mutex7a.c
@@ -1,2 +1,2 @@
-#define INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+#define TYPE PTHREAD_MUTEX_ADAPTIVE_NP
#include "tst-mutex7.c"
diff --git a/nptl/tst-mutex9.c b/nptl/tst-mutex9.c
index 5ea2f0ac99..f9d379343d 100644
--- a/nptl/tst-mutex9.c
+++ b/nptl/tst-mutex9.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
@@ -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
index 0000000000..623ede9fa5
--- /dev/null
+++ b/nptl/tst-mutexpi1.c
@@ -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
index 0000000000..fbe48716fd
--- /dev/null
+++ b/nptl/tst-mutexpi2.c
@@ -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
index 0000000000..e338ebfff9
--- /dev/null
+++ b/nptl/tst-mutexpi3.c
@@ -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
index 0000000000..177b17b475
--- /dev/null
+++ b/nptl/tst-mutexpi4.c
@@ -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
index 0000000000..287465c23f
--- /dev/null
+++ b/nptl/tst-mutexpi5.c
@@ -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
index 0000000000..2f85c94ff3
--- /dev/null
+++ b/nptl/tst-mutexpi5a.c
@@ -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
index 0000000000..42cda377d1
--- /dev/null
+++ b/nptl/tst-mutexpi6.c
@@ -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
index 0000000000..1e7e929380
--- /dev/null
+++ b/nptl/tst-mutexpi7.c
@@ -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
index 0000000000..c59083cf6e
--- /dev/null
+++ b/nptl/tst-mutexpi7a.c
@@ -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
index 0000000000..cea60309a8
--- /dev/null
+++ b/nptl/tst-mutexpi8.c
@@ -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
index 0000000000..3710d9e080
--- /dev/null
+++ b/nptl/tst-mutexpi9.c
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex9.c"
diff --git a/nptl/tst-robust1.c b/nptl/tst-robust1.c
index 9806ca467a..bc48700e4a 100644
--- a/nptl/tst-robust1.c
+++ b/nptl/tst-robust1.c
@@ -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;
}
diff --git a/nptl/tst-robust7.c b/nptl/tst-robust7.c
index 2c5acb44ce..d0bc91cc8e 100644
--- a/nptl/tst-robust7.c
+++ b/nptl/tst-robust7.c
@@ -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");
diff --git a/nptl/tst-robust8.c b/nptl/tst-robust8.c
index 19682e594f..9c636250d4 100644
--- a/nptl/tst-robust8.c
+++ b/nptl/tst-robust8.c
@@ -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
index 0000000000..031291b296
--- /dev/null
+++ b/nptl/tst-robustpi1.c
@@ -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
index 0000000000..ac411c7736
--- /dev/null
+++ b/nptl/tst-robustpi2.c
@@ -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
index 0000000000..7dcf691e82
--- /dev/null
+++ b/nptl/tst-robustpi3.c
@@ -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
index 0000000000..6c7b0aa7be
--- /dev/null
+++ b/nptl/tst-robustpi4.c
@@ -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
index 0000000000..a494c332f1
--- /dev/null
+++ b/nptl/tst-robustpi5.c
@@ -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
index 0000000000..3b1482fc22
--- /dev/null
+++ b/nptl/tst-robustpi6.c
@@ -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
index 0000000000..f8892f3521
--- /dev/null
+++ b/nptl/tst-robustpi7.c
@@ -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
index 0000000000..cbea3d6d77
--- /dev/null
+++ b/nptl/tst-robustpi8.c
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust8.c"