1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

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.
This commit is contained in:
Ulrich Drepper
2006-07-29 04:42:09 +00:00
parent 6822f05652
commit df47504c78
49 changed files with 1083 additions and 89 deletions

View 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> 2006-07-01 Ulrich Drepper <drepper@redhat.com>
* pthread_mutex_init.c (__pthread_mutex_init): Move some * pthread_mutex_init.c (__pthread_mutex_init): Move some

View File

@ -200,6 +200,9 @@ tests = tst-typesizes \
tst-attr1 tst-attr2 tst-attr3 \ tst-attr1 tst-attr2 tst-attr3 \
tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \ tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a \ 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-spin1 tst-spin2 tst-spin3 \
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ 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 \ tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
@ -207,6 +210,8 @@ tests = tst-typesizes \
tst-cond20 tst-cond21 \ tst-cond20 tst-cond21 \
tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \ tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
tst-robust6 tst-robust7 tst-robust8 \ 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-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \ tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \ tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \

View File

@ -155,23 +155,28 @@ struct pthread
first. */ first. */
# define QUEUE_PTR_ADJUST (offsetof (__pthread_list_t, __next)) # define QUEUE_PTR_ADJUST (offsetof (__pthread_list_t, __next))
# define ENQUEUE_MUTEX(mutex) \ # define ENQUEUE_MUTEX_BOTH(mutex, val) \
do { \ do { \
__pthread_list_t *next = (THREAD_GETMEM (THREAD_SELF, robust_head.list) \ __pthread_list_t *next = (__pthread_list_t *) \
((((uintptr_t) THREAD_GETMEM (THREAD_SELF, robust_head.list)) & ~1ul) \
- QUEUE_PTR_ADJUST); \ - QUEUE_PTR_ADJUST); \
next->__prev = (void *) &mutex->__data.__list.__next; \ 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; \ mutex->__data.__list.__prev = (void *) &THREAD_SELF->robust_head; \
THREAD_SETMEM (THREAD_SELF, robust_head.list, \ THREAD_SETMEM (THREAD_SELF, robust_head.list, \
&mutex->__data.__list.__next); \ (void *) (((uintptr_t) &mutex->__data.__list.__next) \
| val)); \
} while (0) } while (0)
# define DEQUEUE_MUTEX(mutex) \ # define DEQUEUE_MUTEX(mutex) \
do { \ do { \
__pthread_list_t *next = (__pthread_list_t *) \ __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; \ next->__prev = mutex->__data.__list.__prev; \
__pthread_list_t *prev = (__pthread_list_t *) \ __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; \ prev->__next = mutex->__data.__list.__next; \
mutex->__data.__list.__prev = NULL; \ mutex->__data.__list.__prev = NULL; \
mutex->__data.__list.__next = NULL; \ mutex->__data.__list.__next = NULL; \
@ -183,27 +188,36 @@ struct pthread
struct robust_list_head robust_head; struct robust_list_head robust_head;
}; };
# define ENQUEUE_MUTEX(mutex) \ # define ENQUEUE_MUTEX_BOTH(mutex, val) \
do { \ do { \
mutex->__data.__list.__next \ mutex->__data.__list.__next \
= THREAD_GETMEM (THREAD_SELF, robust_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) } while (0)
# define DEQUEUE_MUTEX(mutex) \ # define DEQUEUE_MUTEX(mutex) \
do { \ 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) \ if (runp == &mutex->__data.__list) \
THREAD_SETMEM (THREAD_SELF, robust_list.__next, runp->__next); \ THREAD_SETMEM (THREAD_SELF, robust_list.__next, runp->__next); \
else \ else \
{ \ { \
while (runp->__next != &mutex->__data.__list) \ __pthread_slist_t *next = (__pthread_slist_t *) \
runp = runp->__next; \ (((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; \ mutex->__data.__list.__next = NULL; \
} \ } \
} while (0) } while (0)
#endif #endif
#define ENQUEUE_MUTEX(mutex) ENQUEUE_MUTEX_BOTH (mutex, 0)
#define ENQUEUE_MUTEX_PI(mutex) ENQUEUE_MUTEX_BOTH (mutex, 1)
/* List of cleanup buffers. */ /* List of cleanup buffers. */
struct _pthread_cleanup_buffer *cleanup; struct _pthread_cleanup_buffer *cleanup;

View File

@ -61,6 +61,7 @@
/* Internal mutex type value. */ /* Internal mutex type value. */
enum enum
{ {
PTHREAD_MUTEX_KIND_MASK_NP = 3,
PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16, PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16,
PTHREAD_MUTEX_ROBUST_RECURSIVE_NP PTHREAD_MUTEX_ROBUST_RECURSIVE_NP
= PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_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_NORMAL_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP
= PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ADAPTIVE_NP, = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
PTHREAD_MUTEX_PRIO_INHERIT_PRIVATE_NP = 32, PTHREAD_MUTEX_PRIO_INHERIT_NP = 32,
PTHREAD_MUTEX_PRIO_PROTECT_PRIVATE_NP = 64 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_SHIFT 16
#define PTHREAD_MUTEX_PRIO_CEILING_MASK 0x00ff0000 #define PTHREAD_MUTEX_PRIO_CEILING_MASK 0x00ff0000

View File

@ -330,9 +330,11 @@ start_thread (void *arg)
# else # else
__pthread_slist_t *robust = pd->robust_list.__next; __pthread_slist_t *robust = pd->robust_list.__next;
# endif # 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 if (__set_robust_list_avail < 0
&& __builtin_expect (robust != &pd->robust_head, 0)) && __builtin_expect (robust != (void *) &pd->robust_head, 0))
{ {
do do
{ {
@ -348,7 +350,7 @@ start_thread (void *arg)
lll_robust_mutex_dead (this->__lock); lll_robust_mutex_dead (this->__lock);
} }
while (robust != &pd->robust_head); while (robust != (void *) &pd->robust_head);
} }
#endif #endif

View File

@ -30,7 +30,6 @@ __pthread_mutex_destroy (mutex)
return EBUSY; return EBUSY;
/* Set to an invalid value. */ /* Set to an invalid value. */
dead_robust_mutex:
mutex->__data.__kind = -1; mutex->__data.__kind = -1;
return 0; return 0;

View File

@ -29,6 +29,11 @@ static const struct pthread_mutexattr default_attr =
}; };
#ifndef __ASSUME_FUTEX_LOCK_PI
static int tpi_supported;
#endif
int int
__pthread_mutex_init (mutex, mutexattr) __pthread_mutex_init (mutex, mutexattr)
pthread_mutex_t *mutex; pthread_mutex_t *mutex;
@ -41,8 +46,7 @@ __pthread_mutex_init (mutex, mutexattr)
imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr; imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr;
/* Sanity checks. */ /* Sanity checks. */
// XXX For now we don't support priority inherited or priority protected // XXX For now we don't support priority protected mutexes.
// XXX mutexes.
switch (__builtin_expect (imutexattr->mutexkind switch (__builtin_expect (imutexattr->mutexkind
& PTHREAD_MUTEXATTR_PROTOCOL_MASK, & PTHREAD_MUTEXATTR_PROTOCOL_MASK,
PTHREAD_PRIO_NONE PTHREAD_PRIO_NONE
@ -51,6 +55,22 @@ __pthread_mutex_init (mutex, mutexattr)
case PTHREAD_PRIO_NONE << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: case PTHREAD_PRIO_NONE << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
break; 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: default:
return ENOTSUP; return ENOTSUP;
} }
@ -75,11 +95,11 @@ __pthread_mutex_init (mutex, mutexattr)
switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK) switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
{ {
case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: 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; break;
case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: 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 if (PTHREAD_MUTEX_PRIO_CEILING_MASK
== PTHREAD_MUTEXATTR_PRIO_CEILING_MASK) == PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
mutex->__data.__kind |= (imutexattr->mutexkind mutex->__data.__kind |= (imutexattr->mutexkind

View File

@ -20,6 +20,7 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include "pthreadP.h" #include "pthreadP.h"
#include <lowlevellock.h> #include <lowlevellock.h>
@ -205,6 +206,134 @@ __pthread_mutex_lock (mutex)
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
break; 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: default:
/* Correct code cannot set any other type. */ /* Correct code cannot set any other type. */
return EINVAL; return EINVAL;

View 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, /* The low bits of __kind aren't ever changed after pthread_mutex_init,
so we don't need a lock yet. */ 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; return EINVAL;
if (prioceiling < 0 || __builtin_expect (prioceiling > 255, 0)) if (prioceiling < 0 || __builtin_expect (prioceiling > 255, 0))

View File

@ -35,7 +35,7 @@ pthread_mutex_timedlock (mutex, abstime)
/* We must not check ABSTIME here. If the thread does not block /* We must not check ABSTIME here. If the thread does not block
abstime must not be checked for a valid value. */ 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. */ /* Recursive mutex. */
case PTHREAD_MUTEX_RECURSIVE_NP: case PTHREAD_MUTEX_RECURSIVE_NP:
@ -65,7 +65,7 @@ pthread_mutex_timedlock (mutex, abstime)
/* Error checking mutex. */ /* Error checking mutex. */
case PTHREAD_MUTEX_ERRORCHECK_NP: case PTHREAD_MUTEX_ERRORCHECK_NP:
/* Check whether we already hold the mutex. */ /* Check whether we already hold the mutex. */
if (mutex->__data.__owner == id) if (__builtin_expect (mutex->__data.__owner == id, 0))
return EDEADLK; return EDEADLK;
/* FALLTHROUGH */ /* FALLTHROUGH */
@ -134,7 +134,7 @@ pthread_mutex_timedlock (mutex, abstime)
ENQUEUE_MUTEX (mutex); ENQUEUE_MUTEX (mutex);
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); 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 through to the end of the function __nusers would be
incremented which is not correct because the old incremented which is not correct because the old
owner has to be discounted. */ owner has to be discounted. */
@ -194,6 +194,150 @@ pthread_mutex_timedlock (mutex, abstime)
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
break; 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: default:
/* Correct code cannot set any other type. */ /* Correct code cannot set any other type. */
return EINVAL; return EINVAL;

View File

@ -152,7 +152,6 @@ __pthread_mutex_trylock (mutex)
return EBUSY; return EBUSY;
} }
robust:
if (__builtin_expect (mutex->__data.__owner if (__builtin_expect (mutex->__data.__owner
== PTHREAD_MUTEX_NOTRECOVERABLE, 0)) == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
{ {
@ -175,6 +174,129 @@ __pthread_mutex_trylock (mutex)
return 0; 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: default:
/* Correct code cannot set any other type. */ /* Correct code cannot set any other type. */
return EINVAL; return EINVAL;

View File

@ -119,6 +119,89 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
break; 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: default:
/* Correct code cannot set any other type. */ /* Correct code cannot set any other type. */
return EINVAL; return EINVAL;

View 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. This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@ -55,6 +55,12 @@ __pthread_cond_broadcast (cond)
/* Wake everybody. */ /* Wake everybody. */
pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex; 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 /* lll_futex_requeue returns 0 for success and non-zero
for errors. */ for errors. */
if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1, if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1,

View File

@ -25,7 +25,7 @@ libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock
gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \ gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
lowlevelbarrier.sym unwindbuf.sym \ lowlevelbarrier.sym unwindbuf.sym \
lowlevelrobustlock.sym lowlevelrobustlock.sym pthread-pi-defines.sym
endif endif
ifeq ($(subdir),posix) ifeq ($(subdir),posix)

View File

@ -1,5 +1,5 @@
/* Define POSIX options for Linux. /* 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -79,6 +79,9 @@
/* We support user-defined stacks. */ /* We support user-defined stacks. */
#define _POSIX_THREAD_ATTR_STACKADDR 200112L #define _POSIX_THREAD_ATTR_STACKADDR 200112L
/* We support priority inheritence. */
#define _POSIX_THREAD_PRIO_INHERIT 200112L
/* We support POSIX.1b semaphores. */ /* We support POSIX.1b semaphores. */
#define _POSIX_SEMAPHORES 200112L #define _POSIX_SEMAPHORES 200112L
@ -171,8 +174,7 @@
/* Typed memory objects are not available. */ /* Typed memory objects are not available. */
#define _POSIX_TYPED_MEMORY_OBJECTS -1 #define _POSIX_TYPED_MEMORY_OBJECTS -1
/* No support for priority inheritance or protection so far. */ /* No support for priority protection so far. */
#define _POSIX_THREAD_PRIO_INHERIT -1
#define _POSIX_THREAD_PRIO_PROTECT -1 #define _POSIX_THREAD_PRIO_PROTECT -1
#endif /* posix_opt.h */ #endif /* posix_opt.h */

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -21,6 +21,7 @@
#include <shlib-compat.h> #include <shlib-compat.h>
#include <lowlevelcond.h> #include <lowlevelcond.h>
#include <kernel-features.h> #include <kernel-features.h>
#include <pthread-pi-defines.h>
#ifdef UP #ifdef UP
# define LOCK # define LOCK
@ -94,6 +95,10 @@ __pthread_cond_broadcast:
8: cmpl $-1, %edi 8: cmpl $-1, %edi
je 9f 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. */ /* Wake up all threads. */
movl $FUTEX_CMP_REQUEUE, %ecx movl $FUTEX_CMP_REQUEUE, %ecx
movl $SYS_futex, %eax movl $SYS_futex, %eax

View File

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

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -21,6 +21,7 @@
#include <shlib-compat.h> #include <shlib-compat.h>
#include <lowlevelcond.h> #include <lowlevelcond.h>
#include <kernel-features.h> #include <kernel-features.h>
#include <pthread-pi-defines.h>
#ifdef UP #ifdef UP
# define LOCK # define LOCK
@ -80,6 +81,10 @@ __pthread_cond_broadcast:
8: cmpq $-1, %r8 8: cmpq $-1, %r8
je 9f 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. */ /* Wake up all threads. */
movl $FUTEX_CMP_REQUEUE, %esi movl $FUTEX_CMP_REQUEUE, %esi
movl $SYS_futex, %eax movl $SYS_futex, %eax

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -19,6 +19,12 @@
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h>
#ifndef ATTR
# define ATTR NULL
#endif
static int static int
@ -26,12 +32,24 @@ do_test (void)
{ {
pthread_mutex_t m; 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"); puts ("mutex_init failed");
return 1; return 1;
} }
if (ATTR != NULL && pthread_mutexattr_destroy (ATTR) != 0)
{
puts ("mutexattr_destroy failed");
return 1;
}
if (pthread_mutex_lock (&m) != 0) if (pthread_mutex_lock (&m) != 0)
{ {
puts ("mutex_lock failed"); puts ("mutex_lock failed");

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -105,115 +105,134 @@ do_test (void)
if (pthread_mutexattr_init (&a) != 0) if (pthread_mutexattr_init (&a) != 0)
{ {
puts ("mutexattr_init failed"); puts ("mutexattr_init failed");
exit (1); return 1;
} }
if (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_ERRORCHECK) != 0) if (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_ERRORCHECK) != 0)
{ {
puts ("mutexattr_settype failed"); 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"); puts ("mutex_init failed");
exit (1); return 1;
} }
if (pthread_barrier_init (&b, NULL, 2) != 0) if (pthread_barrier_init (&b, NULL, 2) != 0)
{ {
puts ("barrier_init failed"); 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"); puts ("1st mutex_unlock succeeded");
exit (1); return 1;
} }
else if (e != EPERM) else if (e != EPERM)
{ {
puts ("1st mutex_unlock error != EPERM"); puts ("1st mutex_unlock error != EPERM");
exit (1); return 1;
} }
if (pthread_mutex_lock (&m) != 0) if (pthread_mutex_lock (&m) != 0)
{ {
puts ("mutex_lock failed"); 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"); puts ("2nd mutex_lock succeeded");
exit (1); return 1;
} }
else if (e != EDEADLK) else if (e != EDEADLK)
{ {
puts ("2nd mutex_lock error != EDEADLK"); puts ("2nd mutex_lock error != EDEADLK");
exit (1); return 1;
} }
pthread_t th; pthread_t th;
if (pthread_create (&th, NULL, tf, NULL) != 0) if (pthread_create (&th, NULL, tf, NULL) != 0)
{ {
puts ("create failed"); puts ("create failed");
exit (1); return 1;
} }
e = pthread_barrier_wait (&b); e = pthread_barrier_wait (&b);
if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
{ {
puts ("1st barrier_wait failed"); puts ("1st barrier_wait failed");
exit (1); return 1;
} }
if (pthread_mutex_unlock (&m) != 0) if (pthread_mutex_unlock (&m) != 0)
{ {
puts ("2nd mutex_unlock failed"); 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"); puts ("3rd mutex_unlock succeeded");
exit (1); return 1;
} }
else if (e != EPERM) else if (e != EPERM)
{ {
puts ("3rd mutex_unlock error != EPERM"); puts ("3rd mutex_unlock error != EPERM");
exit (1); return 1;
} }
e = pthread_barrier_wait (&b); e = pthread_barrier_wait (&b);
if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
{ {
puts ("2nd barrier_wait failed"); puts ("2nd barrier_wait failed");
exit (1); return 1;
} }
if (pthread_join (th, NULL) != 0) if (pthread_join (th, NULL) != 0)
{ {
puts ("join failed"); puts ("join failed");
exit (1); return 1;
} }
if (pthread_mutex_destroy (&m) != 0) if (pthread_mutex_destroy (&m) != 0)
{ {
puts ("mutex_destroy failed"); puts ("mutex_destroy failed");
exit (1); return 1;
} }
if (pthread_barrier_destroy (&b) != 0) if (pthread_barrier_destroy (&b) != 0)
{ {
puts ("barrier_destroy failed"); puts ("barrier_destroy failed");
exit (1); return 1;
} }
if (pthread_mutexattr_destroy (&a) != 0) if (pthread_mutexattr_destroy (&a) != 0)
{ {
puts ("mutexattr_destroy failed"); puts ("mutexattr_destroy failed");
exit (1); return 1;
} }
return 0; return 0;

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -113,8 +113,25 @@ do_test (void)
return 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
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"); puts ("mutex_init failed");
return 1; return 1;
} }
@ -162,7 +179,7 @@ do_test (void)
return 1; return 1;
} }
int e = pthread_barrier_wait (&b); e = pthread_barrier_wait (&b);
if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
{ {
puts ("barrier_wait failed"); puts ("barrier_wait failed");

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -42,6 +42,8 @@ do_test (void)
char *p; char *p;
int err; int err;
int s; int s;
pthread_barrier_t *b;
pthread_barrierattr_t ba;
fd = mkstemp (tmpfname); fd = mkstemp (tmpfname);
if (fd == -1) if (fd == -1)
@ -70,9 +72,12 @@ do_test (void)
return 1; 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)); & ~(__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) if (pthread_mutexattr_init (&a) != 0)
{ {
@ -110,8 +115,23 @@ do_test (void)
return 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
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"); puts ("mutex_init failed");
return 1; return 1;
} }
@ -128,6 +148,30 @@ do_test (void)
return 1; 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); err = pthread_mutex_trylock (m);
if (err == 0) if (err == 0)
{ {
@ -142,6 +186,12 @@ do_test (void)
*p = 0; *p = 0;
if (pthread_mutex_unlock (m) != 0)
{
puts ("parent: 1st mutex_unlock failed");
return 1;
}
puts ("going to fork now"); puts ("going to fork now");
pid = fork (); pid = fork ();
if (pid == -1) if (pid == -1)
@ -151,7 +201,19 @@ do_test (void)
} }
else if (pid == 0) 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) if ((*p)++ != 0)
{ {
puts ("child: *p != 0"); puts ("child: *p != 0");
@ -160,7 +222,7 @@ do_test (void)
if (pthread_mutex_unlock (m) != 0) if (pthread_mutex_unlock (m) != 0)
{ {
puts ("child: 1st mutex_unlock failed"); puts ("child: mutex_unlock failed");
return 1; return 1;
} }
@ -168,6 +230,13 @@ do_test (void)
} }
else 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) if (pthread_mutex_lock (m) != 0)
{ {
puts ("parent: 2nd mutex_lock failed"); puts ("parent: 2nd mutex_lock failed");
@ -180,6 +249,24 @@ do_test (void)
return 1; 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"); puts ("parent done");
} }

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -52,8 +52,24 @@ do_test (void)
return 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
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"); puts ("mutex_init failed");
return 1; return 1;
} }

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -21,6 +21,12 @@
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#ifndef ATTR
# define ATTR NULL
#endif
static int static int
@ -28,12 +34,24 @@ do_test (void)
{ {
pthread_mutex_t m; 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"); puts ("mutex_init failed");
return 1; return 1;
} }
if (ATTR != NULL && pthread_mutexattr_destroy (ATTR) != 0)
{
puts ("mutexattr_destroy failed");
return 1;
}
if (pthread_mutex_lock (&m) != 0) if (pthread_mutex_lock (&m) != 0)
{ {
puts ("1st mutex_lock failed"); puts ("1st mutex_lock failed");

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -17,17 +17,19 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA. */
#include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <time.h> #include <time.h>
#ifndef INIT #ifndef TYPE
# define INIT PTHREAD_MUTEX_INITIALIZER # define TYPE PTHREAD_MUTEX_DEFAULT
#endif #endif
static pthread_mutex_t lock = INIT; static pthread_mutex_t lock;
#define ROUNDS 1000 #define ROUNDS 1000
@ -65,6 +67,48 @@ tf (void *arg)
static int static int
do_test (void) 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_attr_t at;
pthread_t th[N]; pthread_t th[N];
int cnt; int cnt;

View File

@ -1,2 +1,2 @@
#define INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP #define TYPE PTHREAD_MUTEX_ADAPTIVE_NP
#include "tst-mutex7.c" #include "tst-mutex7.c"

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
@ -88,8 +88,24 @@ do_test (void)
return 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
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"); puts ("mutex_init failed");
return 1; return 1;
} }
@ -138,7 +154,7 @@ do_test (void)
ts.tv_nsec -= 1000000000; ts.tv_nsec -= 1000000000;
} }
int e = pthread_mutex_timedlock (m, &ts); e = pthread_mutex_timedlock (m, &ts);
if (e == 0) if (e == 0)
{ {
puts ("child: mutex_timedlock succeeded"); puts ("child: mutex_timedlock succeeded");

27
nptl/tst-mutexpi1.c Normal file
View File

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

2
nptl/tst-mutexpi2.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-mutex2.c"

2
nptl/tst-mutexpi3.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-mutex3.c"

2
nptl/tst-mutexpi4.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-mutex4.c"

2
nptl/tst-mutexpi5.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-mutex5.c"

2
nptl/tst-mutexpi5a.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-mutex5a.c"

27
nptl/tst-mutexpi6.c Normal file
View File

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

2
nptl/tst-mutexpi7.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-mutex7.c"

2
nptl/tst-mutexpi7a.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-mutex7a.c"

2
nptl/tst-mutexpi8.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-mutex8.c"

2
nptl/tst-mutexpi9.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-mutex9.c"

View File

@ -97,6 +97,30 @@ do_test (void)
puts ("mutexattr_setrobust failed"); puts ("mutexattr_setrobust failed");
return 1; 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 #ifndef NOT_CONSISTENT
if (pthread_mutex_init (&m1, &a) != 0) if (pthread_mutex_init (&m1, &a) != 0)
{ {
@ -236,14 +260,14 @@ do_test (void)
e = pthread_mutex_unlock (&m1); e = pthread_mutex_unlock (&m1);
if (e != 0) if (e != 0)
{ {
printf ("%ld: mutex_unlock m1 failed\n", round); printf ("%ld: mutex_unlock m1 failed with %d\n", round, e);
return 1; return 1;
} }
e = pthread_mutex_unlock (&m2); e = pthread_mutex_unlock (&m2);
if (e != 0) if (e != 0)
{ {
printf ("%ld: mutex_unlock m2 failed\n", round); printf ("%ld: mutex_unlock m2 failed with %d\n", round, e);
return 1; return 1;
} }

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2005. Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
@ -95,8 +95,25 @@ do_test (void)
return 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
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"); puts ("mutex_init failed");
return 1; return 1;
} }
@ -123,7 +140,7 @@ do_test (void)
return 1; return 1;
} }
int e = pthread_barrier_wait (&b); e = pthread_barrier_wait (&b);
if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
{ {
printf ("parent: barrier_wait failed in round %ld\n", n + 1); 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) if (e == 0)
{ {
puts ("parent: 2nd mutex_lock succeeded"); puts ("parent: 2nd mutex_lock succeeded");

View File

@ -15,7 +15,7 @@ static void prepare (void);
#define PREPARE(argc, argv) prepare () #define PREPARE(argc, argv) prepare ()
static int do_test (void); static int do_test (void);
#define TEST_FUNCTION do_test () #define TEST_FUNCTION do_test ()
#define TIMEOUT 3 #define TIMEOUT 5
#include "../test-skeleton.c" #include "../test-skeleton.c"
@ -173,6 +173,13 @@ do_test (void)
puts ("mutexattr_setpshared failed"); puts ("mutexattr_setpshared failed");
return 1; 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) for (int round = 1; round <= ROUNDS; ++round)
{ {
@ -181,7 +188,11 @@ do_test (void)
int e = pthread_mutex_init (&map[n], &ma); int e = pthread_mutex_init (&map[n], &ma);
if (e == ENOTSUP) if (e == ENOTSUP)
{ {
#ifdef ENABLE_PI
puts ("cannot support pshared robust PI mutexes");
#else
puts ("cannot support pshared robust mutexes"); puts ("cannot support pshared robust mutexes");
#endif
return 0; return 0;
} }
if (e != 0) if (e != 0)

2
nptl/tst-robustpi1.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-robust1.c"

2
nptl/tst-robustpi2.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-robust2.c"

2
nptl/tst-robustpi3.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-robust3.c"

2
nptl/tst-robustpi4.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-robust4.c"

2
nptl/tst-robustpi5.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-robust5.c"

2
nptl/tst-robustpi6.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-robust6.c"

2
nptl/tst-robustpi7.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-robust7.c"

2
nptl/tst-robustpi8.c Normal file
View File

@ -0,0 +1,2 @@
#define ENABLE_PI 1
#include "tst-robust8.c"