about summary refs log tree commit diff
path: root/nptl/pthread_mutex_unlock.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-12-22 20:10:10 +0000
committerUlrich Drepper <drepper@redhat.com>2004-12-22 20:10:10 +0000
commita334319f6530564d22e775935d9c91663623a1b4 (patch)
treeb5877475619e4c938e98757d518bb1e9cbead751 /nptl/pthread_mutex_unlock.c
parent0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (diff)
downloadglibc-a334319f6530564d22e775935d9c91663623a1b4.tar.gz
glibc-a334319f6530564d22e775935d9c91663623a1b4.tar.xz
glibc-a334319f6530564d22e775935d9c91663623a1b4.zip
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
Diffstat (limited to 'nptl/pthread_mutex_unlock.c')
-rw-r--r--nptl/pthread_mutex_unlock.c214
1 files changed, 14 insertions, 200 deletions
diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
index 33919d60af..32bc2a4bc1 100644
--- a/nptl/pthread_mutex_unlock.c
+++ b/nptl/pthread_mutex_unlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -18,7 +18,6 @@
    02111-1307 USA.  */
 
 #include <errno.h>
-#include <stdlib.h>
 #include "pthreadP.h"
 #include <lowlevellock.h>
 
@@ -29,8 +28,6 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
      pthread_mutex_t *mutex;
      int decr;
 {
-  int newowner = 0;
-
   switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
     {
     case PTHREAD_MUTEX_RECURSIVE_NP:
@@ -41,214 +38,31 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
       if (--mutex->__data.__count != 0)
 	/* We still hold the mutex.  */
 	return 0;
-      goto normal;
+      break;
 
     case PTHREAD_MUTEX_ERRORCHECK_NP:
       /* Error checking mutex.  */
       if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid)
 	  || ! lll_mutex_islocked (mutex->__data.__lock))
 	return EPERM;
-      /* FALLTHROUGH */
+      break;
 
+    default:
+      /* Correct code cannot set any other type.  */
     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_mutex_unlock (mutex->__data.__lock);
-      break;
-
-    case PTHREAD_MUTEX_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 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 robust;
-
-    case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
-    case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
-    case PTHREAD_MUTEX_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 (__builtin_expect (mutex->__data.__owner
-			    == PTHREAD_MUTEX_INCONSISTENT, 0))
-      notrecoverable:
-	newowner = PTHREAD_MUTEX_NOTRECOVERABLE;
-
-    robust:
-      /* Remove mutex from the list.  */
-      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
-		     &mutex->__data.__list.__next);
-      DEQUEUE_MUTEX (mutex);
-
-      mutex->__data.__owner = newowner;
-      if (decr)
-	/* One less user.  */
-	--mutex->__data.__nusers;
-
-      /* Unlock.  */
-      lll_robust_mutex_unlock (mutex->__data.__lock);
-
-      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
-      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);
+      /* Normal mutex.  Nothing special to do.  */
       break;
+    }
 
-    case PTHREAD_MUTEX_PP_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 pp;
-
-    case PTHREAD_MUTEX_PP_ERRORCHECK_NP:
-      /* Error checking mutex.  */
-      if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid)
-	  || (mutex->__data.__lock & ~ PTHREAD_MUTEX_PRIO_CEILING_MASK) == 0)
-	return EPERM;
-      /* FALLTHROUGH */
-
-    case PTHREAD_MUTEX_PP_NORMAL_NP:
-    case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
-      /* Always reset the owner field.  */
-    pp:
-      mutex->__data.__owner = 0;
-
-      if (decr)
-	/* One less user.  */
-	--mutex->__data.__nusers;
-
-      /* Unlock.  */
-      int newval, oldval;
-      do
-	{
-	  oldval = mutex->__data.__lock;
-	  newval = oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK;
-	}
-      while (atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock,
-						   newval, oldval));
-
-      if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1)
-	lll_futex_wake (&mutex->__data.__lock, 1);
-
-      int oldprio = newval >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
-      return __pthread_tpp_change_priority (oldprio, -1);
+  /* Always reset the owner field.  */
+  mutex->__data.__owner = 0;
+  if (decr)
+    /* One less user.  */
+    --mutex->__data.__nusers;
 
-    default:
-      /* Correct code cannot set any other type.  */
-      return EINVAL;
-    }
+  /* Unlock.  */
+  lll_mutex_unlock (mutex->__data.__lock);
 
   return 0;
 }