summaryrefslogtreecommitdiff
path: root/nptl/pthread_mutex_trylock.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/pthread_mutex_trylock.c')
-rw-r--r--nptl/pthread_mutex_trylock.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 5a13ea6925..148a6e919f 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -77,25 +77,28 @@ __pthread_mutex_trylock (mutex)
return 0;
- case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP:
+ case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+ case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+ case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+ case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ &mutex->__data.__list.__next);
+
oldval = mutex->__data.__lock;
do
{
+ again:
if ((oldval & FUTEX_OWNER_DIED) != 0)
{
/* The previous owner died. Try locking the mutex. */
- int newval;
- while ((newval
- = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
- id, oldval))
- != oldval)
+ int newval
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+ id, oldval);
+
+ if (newval != oldval)
{
- if ((newval & FUTEX_OWNER_DIED) == 0)
- goto normal;
oldval = newval;
+ goto again;
}
/* We got the mutex. */
@@ -104,6 +107,7 @@ __pthread_mutex_trylock (mutex)
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
ENQUEUE_MUTEX (mutex);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Note that we deliberately exist here. If we fall
through to the end of the function __nusers would be
@@ -112,18 +116,23 @@ __pthread_mutex_trylock (mutex)
return EOWNERDEAD;
}
- normal:
/* Check whether we already hold the mutex. */
- if (__builtin_expect ((mutex->__data.__lock & FUTEX_TID_MASK)
- == id, 0))
+ if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
{
if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP)
- return EDEADLK;
+ == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+ {
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ NULL);
+ return EDEADLK;
+ }
if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP)
+ == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
{
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ NULL);
+
/* Just bump the counter. */
if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
/* Overflow of the counter. */
@@ -137,7 +146,11 @@ __pthread_mutex_trylock (mutex)
oldval = lll_robust_mutex_trylock (mutex->__data.__lock, id);
if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0)
- return EBUSY;
+ {
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+ return EBUSY;
+ }
robust:
if (__builtin_expect (mutex->__data.__owner
@@ -147,12 +160,14 @@ __pthread_mutex_trylock (mutex)
mutex->__data.__count = 0;
if (oldval == id)
lll_mutex_unlock (mutex->__data.__lock);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
}
while ((oldval & FUTEX_OWNER_DIED) != 0);
ENQUEUE_MUTEX (mutex);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
mutex->__data.__owner = id;
++mutex->__data.__nusers;