diff options
Diffstat (limited to 'nptl/pthread_mutex_unlock.c')
-rw-r--r-- | nptl/pthread_mutex_unlock.c | 57 |
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) |