summaryrefslogtreecommitdiff
path: root/nptl/pthread_mutex_unlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/pthread_mutex_unlock.c')
-rw-r--r--nptl/pthread_mutex_unlock.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
index 80939ba8b0..334ce38342 100644
--- a/nptl/pthread_mutex_unlock.c
+++ b/nptl/pthread_mutex_unlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -24,7 +24,7 @@
#include <stap-probe.h>
#ifndef lll_unlock_elision
-#define lll_unlock_elision(a,b) ({ lll_unlock (a,b); 0; })
+#define lll_unlock_elision(a,b,c) ({ lll_unlock (a,c); 0; })
#endif
static int
@@ -34,9 +34,7 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
int
internal_function attribute_hidden
-__pthread_mutex_unlock_usercnt (mutex, decr)
- pthread_mutex_t *mutex;
- int decr;
+__pthread_mutex_unlock_usercnt (pthread_mutex_t *mutex, int decr)
{
int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
if (__builtin_expect (type &
@@ -63,7 +61,7 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
else if (__glibc_likely (type == PTHREAD_MUTEX_TIMED_ELISION_NP))
{
/* Don't reset the owner/users fields for elision. */
- return lll_unlock_elision (mutex->__data.__lock,
+ return lll_unlock_elision (mutex->__data.__lock, mutex->__data.__elision,
PTHREAD_MUTEX_PSHARED (mutex));
}
else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex)
@@ -232,16 +230,18 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
/* One less user. */
--mutex->__data.__nusers;
- /* Unlock. */
+ /* Unlock. Load all necessary mutex data before releasing the mutex
+ to not violate the mutex destruction requirements (see
+ lll_unlock). */
+ int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ int private = (robust
+ ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
+ : PTHREAD_MUTEX_PSHARED (mutex));
if ((mutex->__data.__lock & FUTEX_WAITERS) != 0
|| atomic_compare_and_exchange_bool_rel (&mutex->__data.__lock, 0,
THREAD_GETMEM (THREAD_SELF,
tid)))
{
- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
- int private = (robust
- ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
- : PTHREAD_MUTEX_PSHARED (mutex));
INTERNAL_SYSCALL_DECL (__err);
INTERNAL_SYSCALL (futex, __err, 2, &mutex->__data.__lock,
__lll_private_flag (FUTEX_UNLOCK_PI, private));
@@ -309,8 +309,7 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
int
-__pthread_mutex_unlock (mutex)
- pthread_mutex_t *mutex;
+__pthread_mutex_unlock (pthread_mutex_t *mutex)
{
return __pthread_mutex_unlock_usercnt (mutex, 1);
}