]> sourceware.org Git - glibc.git/blobdiff - nptl/pthread_mutex_unlock.c
* sysdeps/powerpc/powerpc32/dl-trampoline.S (_dl_runtime_resolve):
[glibc.git] / nptl / pthread_mutex_unlock.c
index 2b5064fbacabbcede14d1d9a2a9700ef59152dc3..33919d60af129e74c26e4c58fe3842800658ae69 100644 (file)
@@ -202,6 +202,49 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       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);
+
     default:
       /* Correct code cannot set any other type.  */
       return EINVAL;
This page took 0.028194 seconds and 5 git commands to generate.