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.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
index a14c43ece7..0028c5583f 100644
--- a/nptl/pthread_mutex_unlock.c
+++ b/nptl/pthread_mutex_unlock.c
@@ -17,11 +17,16 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include "pthreadP.h"
#include <lowlevellock.h>
+static int
+internal_function
+__pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
+ __attribute_noinline__;
int
internal_function attribute_hidden
@@ -29,12 +34,26 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
pthread_mutex_t *mutex;
int decr;
{
- int newowner = 0;
+ int type = PTHREAD_MUTEX_TYPE (mutex);
+ if (__builtin_expect (type & ~PTHREAD_MUTEX_KIND_MASK_NP, 0))
+ return __pthread_mutex_unlock_full (mutex, decr);
+
+ if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP)
+ == PTHREAD_MUTEX_TIMED_NP)
+ {
+ /* Always reset the owner field. */
+ normal:
+ mutex->__data.__owner = 0;
+ if (decr)
+ /* One less user. */
+ --mutex->__data.__nusers;
- switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex),
- PTHREAD_MUTEX_TIMED_NP))
+ /* Unlock. */
+ lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex));
+ return 0;
+ }
+ else if (__builtin_expect (type == PTHREAD_MUTEX_RECURSIVE_NP, 1))
{
- case PTHREAD_MUTEX_RECURSIVE_NP:
/* Recursive mutex. */
if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
return EPERM;
@@ -43,27 +62,29 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
/* We still hold the mutex. */
return 0;
goto normal;
-
- case PTHREAD_MUTEX_ERRORCHECK_NP:
+ }
+ else if (__builtin_expect (type == PTHREAD_MUTEX_ADAPTIVE_NP, 1))
+ goto normal;
+ else
+ {
/* Error checking mutex. */
+ assert (type == PTHREAD_MUTEX_ERRORCHECK_NP);
if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid)
|| ! lll_islocked (mutex->__data.__lock))
return EPERM;
- /* FALLTHROUGH */
+ goto normal;
+ }
+}
- case PTHREAD_MUTEX_TIMED_NP:
- case PTHREAD_MUTEX_ADAPTIVE_NP:
- /* Always reset the owner field. */
- normal:
- mutex->__data.__owner = 0;
- if (decr)
- /* One less user. */
- --mutex->__data.__nusers;
- /* Unlock. */
- lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex));
- break;
+static int
+internal_function
+__pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
+{
+ int newowner = 0;
+ switch (PTHREAD_MUTEX_TYPE (mutex))
+ {
case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
/* Recursive mutex. */
if ((mutex->__data.__lock & FUTEX_TID_MASK)