about summary refs log tree commit diff
path: root/nptl/pthread_mutex_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/pthread_mutex_init.c')
-rw-r--r--nptl/pthread_mutex_init.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c
index 6ceca86052..96f1fb00f8 100644
--- a/nptl/pthread_mutex_init.c
+++ b/nptl/pthread_mutex_init.c
@@ -46,7 +46,6 @@ __pthread_mutex_init (mutex, mutexattr)
   imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr;
 
   /* Sanity checks.  */
-  // XXX For now we don't support priority protected mutexes.
   switch (__builtin_expect (imutexattr->mutexkind
 			    & PTHREAD_MUTEXATTR_PROTOCOL_MASK,
 			    PTHREAD_PRIO_NONE
@@ -72,7 +71,10 @@ __pthread_mutex_init (mutex, mutexattr)
       break;
 
     default:
-      return ENOTSUP;
+      /* XXX: For now we don't support robust priority protected mutexes.  */
+      if (imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST)
+	return ENOTSUP;
+      break;
     }
 
   /* Clear the whole variable.  */
@@ -100,15 +102,18 @@ __pthread_mutex_init (mutex, mutexattr)
 
     case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
       mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP;
-      if (PTHREAD_MUTEX_PRIO_CEILING_MASK
-	  == PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
-	mutex->__data.__kind |= (imutexattr->mutexkind
-				 & PTHREAD_MUTEXATTR_PRIO_CEILING_MASK);
-      else
-	mutex->__data.__kind |= ((imutexattr->mutexkind
-				  & PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
-				 >> PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT)
-				<< PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
+
+      int ceiling = (imutexattr->mutexkind
+		     & PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
+		    >> PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT;
+      if (! ceiling)
+	{
+	  if (__sched_fifo_min_prio == -1)
+	    __init_sched_fifo_prio ();
+	  if (ceiling < __sched_fifo_min_prio)
+	    ceiling = __sched_fifo_min_prio;
+	}
+      mutex->__data.__lock = ceiling << PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
       break;
 
     default: