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:
@ -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
|
||||||
|
@ -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 \
|
||||||
|
38
nptl/descr.h
38
nptl/descr.h
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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))
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
6
nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
Normal file
6
nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
Normal 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
|
@ -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
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
|
@ -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");
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
@ -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
27
nptl/tst-mutexpi1.c
Normal 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
2
nptl/tst-mutexpi2.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-mutex2.c"
|
2
nptl/tst-mutexpi3.c
Normal file
2
nptl/tst-mutexpi3.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-mutex3.c"
|
2
nptl/tst-mutexpi4.c
Normal file
2
nptl/tst-mutexpi4.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-mutex4.c"
|
2
nptl/tst-mutexpi5.c
Normal file
2
nptl/tst-mutexpi5.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-mutex5.c"
|
2
nptl/tst-mutexpi5a.c
Normal file
2
nptl/tst-mutexpi5a.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-mutex5a.c"
|
27
nptl/tst-mutexpi6.c
Normal file
27
nptl/tst-mutexpi6.c
Normal 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
2
nptl/tst-mutexpi7.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-mutex7.c"
|
2
nptl/tst-mutexpi7a.c
Normal file
2
nptl/tst-mutexpi7a.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-mutex7a.c"
|
2
nptl/tst-mutexpi8.c
Normal file
2
nptl/tst-mutexpi8.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-mutex8.c"
|
2
nptl/tst-mutexpi9.c
Normal file
2
nptl/tst-mutexpi9.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-mutex9.c"
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
@ -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
2
nptl/tst-robustpi1.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-robust1.c"
|
2
nptl/tst-robustpi2.c
Normal file
2
nptl/tst-robustpi2.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-robust2.c"
|
2
nptl/tst-robustpi3.c
Normal file
2
nptl/tst-robustpi3.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-robust3.c"
|
2
nptl/tst-robustpi4.c
Normal file
2
nptl/tst-robustpi4.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-robust4.c"
|
2
nptl/tst-robustpi5.c
Normal file
2
nptl/tst-robustpi5.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-robust5.c"
|
2
nptl/tst-robustpi6.c
Normal file
2
nptl/tst-robustpi6.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-robust6.c"
|
2
nptl/tst-robustpi7.c
Normal file
2
nptl/tst-robustpi7.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-robust7.c"
|
2
nptl/tst-robustpi8.c
Normal file
2
nptl/tst-robustpi8.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define ENABLE_PI 1
|
||||||
|
#include "tst-robust8.c"
|
Reference in New Issue
Block a user