about summary refs log tree commit diff
path: root/nptl/pthread_mutex_lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/pthread_mutex_lock.c')
-rw-r--r--nptl/pthread_mutex_lock.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index dd22567c71..06eef49c71 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.c
@@ -108,25 +108,33 @@ __pthread_mutex_lock (mutex)
       assert (mutex->__data.__owner == 0);
       break;
 
-    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 = id;
+#ifdef NO_INCR
+	      newval |= FUTEX_WAITERS;
+#endif
+
+	      newval
+		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						       newval, oldval);
+
+	      if (newval != oldval)
 		{
-		  if ((newval & FUTEX_OWNER_DIED) == 0)
-		    goto normal;
 		  oldval = newval;
+		  goto again;
 		}
 
 	      /* We got the mutex.  */
@@ -135,6 +143,7 @@ __pthread_mutex_lock (mutex)
 	      mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
 
 	      ENQUEUE_MUTEX (mutex);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 
 	      /* Note that we deliberately exit here.  If we fall
 		 through to the end of the function __nusers would be
@@ -149,18 +158,23 @@ __pthread_mutex_lock (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.  */
@@ -180,6 +194,7 @@ __pthread_mutex_lock (mutex)
 	      /* This mutex is now not recoverable.  */
 	      mutex->__data.__count = 0;
 	      lll_mutex_unlock (mutex->__data.__lock);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 	      return ENOTRECOVERABLE;
 	    }
 	}
@@ -187,6 +202,7 @@ __pthread_mutex_lock (mutex)
 
       mutex->__data.__count = 1;
       ENQUEUE_MUTEX (mutex);
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
 
     default: