[rtems commit] score: Add CORE mutex variants

Sebastian Huber sebh at rtems.org
Mon May 30 14:17:59 UTC 2016


Module:    rtems
Branch:    master
Commit:    5a598ac99b0de720a04afc5e2ac6764117589b90
Changeset: http://git.rtems.org/rtems/commit/?id=5a598ac99b0de720a04afc5e2ac6764117589b90

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri May 27 08:02:03 2016 +0200

score: Add CORE mutex variants

Add CORE_recursive_mutex_Control and CORE_ceiling_mutex_Control to avoid
the run-time evaluation of attributes to figure out how a particular
mutex methods should behave.  Start with the no protocol variants.  This
eliminates the CORE_MUTEX_DISCIPLINES_FIFO and
CORE_MUTEX_DISCIPLINES_PRIORITY disciplines.

---

 cpukit/libmisc/monitor/mon-sema.c                |   5 +-
 cpukit/libnetworking/rtems/rtems_glue.c          |   6 +-
 cpukit/posix/include/rtems/posix/mutex.h         |  33 ++++-
 cpukit/posix/include/rtems/posix/muteximpl.h     |  35 +++++
 cpukit/posix/src/mutexdestroy.c                  |  12 +-
 cpukit/posix/src/mutexgetprioceiling.c           |   6 +-
 cpukit/posix/src/mutexinit.c                     |  63 +++++---
 cpukit/posix/src/mutexlocksupp.c                 |  59 ++++++--
 cpukit/posix/src/mutexsetprioceiling.c           |   5 +-
 cpukit/posix/src/mutexunlock.c                   |  21 ++-
 cpukit/rtems/include/rtems/rtems/sem.h           |   2 +-
 cpukit/rtems/include/rtems/rtems/semimpl.h       |   6 +
 cpukit/rtems/src/semcreate.c                     |  59 ++++----
 cpukit/rtems/src/semdelete.c                     |   8 +-
 cpukit/rtems/src/semflush.c                      |   1 +
 cpukit/rtems/src/semobtain.c                     |  15 +-
 cpukit/rtems/src/semrelease.c                    |  10 +-
 cpukit/rtems/src/semsetpriority.c                |   3 +-
 cpukit/score/include/rtems/score/coremutex.h     |  43 ++++--
 cpukit/score/include/rtems/score/coremuteximpl.h | 177 ++++++++++++++++++++---
 cpukit/score/src/apimutex.c                      |   1 -
 cpukit/score/src/coremutex.c                     |  57 ++++----
 cpukit/score/src/coremutexseize.c                |  27 +++-
 cpukit/score/src/coremutexsurrender.c            |  28 +---
 24 files changed, 510 insertions(+), 172 deletions(-)

diff --git a/cpukit/libmisc/monitor/mon-sema.c b/cpukit/libmisc/monitor/mon-sema.c
index 5add7cf..bc74529 100644
--- a/cpukit/libmisc/monitor/mon-sema.c
+++ b/cpukit/libmisc/monitor/mon-sema.c
@@ -22,7 +22,7 @@ rtems_monitor_sema_canonical(
 
     canonical_sema->attribute = rtems_sema->attribute_set;
     canonical_sema->priority_ceiling =
-      rtems_sema->Core_control.mutex.Attributes.priority_ceiling;
+      rtems_sema->Core_control.Mutex.priority_ceiling;
 
     canonical_sema->holder_id = 0;
 
@@ -33,8 +33,9 @@ rtems_monitor_sema_canonical(
     }
     else {
       /* we have a binary semaphore (mutex) */
-      Thread_Control *holder = rtems_sema->Core_control.mutex.holder;
+      Thread_Control *holder;
 
+      holder = rtems_sema->Core_control.Mutex.Recursive.Mutex.holder;
       if (holder != NULL) {
         canonical_sema->holder_id = holder->Object.id;
         canonical_sema->cur_count = 0;
diff --git a/cpukit/libnetworking/rtems/rtems_glue.c b/cpukit/libnetworking/rtems/rtems_glue.c
index 9b6338c..45bb4d2 100644
--- a/cpukit/libnetworking/rtems/rtems_glue.c
+++ b/cpukit/libnetworking/rtems/rtems_glue.c
@@ -118,7 +118,7 @@ rtems_bsdnet_semaphore_release_recursive(void)
 
 	nest_count =
 		the_networkSemaphore ?
-		the_networkSemaphore->Core_control.mutex.nest_count : 0;
+		the_networkSemaphore->Core_control.Mutex.Recursive.Mutex.nest_count : 0;
 	for (i = 0; i < nest_count; ++i) {
 		rtems_bsdnet_semaphore_release();
 	}
@@ -378,7 +378,7 @@ rtems_bsdnet_semaphore_obtain (void)
 	_Thread_queue_Context_initialize(&queue_context);
 	_ISR_lock_ISR_disable(&queue_context.Lock_context);
 	status = _CORE_mutex_Seize (
-		&the_networkSemaphore->Core_control.mutex,
+		&the_networkSemaphore->Core_control.Mutex.Recursive.Mutex,
 		_Thread_Executing,
 		1,		/* wait */
 		0,		/* forever */
@@ -411,7 +411,7 @@ rtems_bsdnet_semaphore_release (void)
 	_Thread_queue_Context_initialize(&queue_context);
 	_ISR_lock_ISR_disable(&queue_context.Lock_context);
 	status = _CORE_mutex_Surrender (
-		&the_networkSemaphore->Core_control.mutex,
+		&the_networkSemaphore->Core_control.Mutex.Recursive.Mutex,
 		&queue_context
 		);
 	if (status != STATUS_SUCCESSFUL)
diff --git a/cpukit/posix/include/rtems/posix/mutex.h b/cpukit/posix/include/rtems/posix/mutex.h
index e1dfa34..97ab138 100644
--- a/cpukit/posix/include/rtems/posix/mutex.h
+++ b/cpukit/posix/include/rtems/posix/mutex.h
@@ -35,14 +35,35 @@ extern "C" {
  */
 /**@{**/
 
-/*
- *  Data Structure used to manage a POSIX mutex
+/**
+ * @brief The POSIX mutex control.
  */
-
 typedef struct {
-   Objects_Control     Object;
-   CORE_mutex_Control  Mutex;
-}  POSIX_Mutex_Control;
+  /**
+   * @brief The object control.
+   */
+  Objects_Control Object;
+
+  /**
+   * The most general mutex variant supported by a POSIX mutex.
+   *
+   * The priority inheritance or no protocol variants will use only parts of
+   * this structure.
+   */
+  CORE_ceiling_mutex_Control Mutex;
+
+  /**
+   * @brief The protocol variant.
+   *
+   * @see POSIX_Mutex_Protocol.
+   */
+  unsigned int protocol : 2;
+
+  /**
+   * @brief Indicates if this is a non-recursive or recursive mutex.
+   */
+  unsigned int is_recursive : 1;
+} POSIX_Mutex_Control;
 
 /** @} */
 
diff --git a/cpukit/posix/include/rtems/posix/muteximpl.h b/cpukit/posix/include/rtems/posix/muteximpl.h
index 30cc19d..4957e20 100644
--- a/cpukit/posix/include/rtems/posix/muteximpl.h
+++ b/cpukit/posix/include/rtems/posix/muteximpl.h
@@ -28,6 +28,19 @@
 extern "C" {
 #endif
 
+#define POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
+
+/**
+ * @brief Supported POSIX mutex protocols.
+ *
+ * Must be in synchronization with POSIX_Mutex_Control::protocol.
+ */
+typedef enum {
+  POSIX_MUTEX_NO_PROTOCOL,
+  POSIX_MUTEX_PRIORITY_INHERIT,
+  POSIX_MUTEX_PRIORITY_CEILING
+} POSIX_Mutex_Protocol;
+
 /**
  *  The following defines the information control block used to manage
  *  this class of objects.
@@ -39,6 +52,28 @@ extern Objects_Information _POSIX_Mutex_Information;
  */
 extern pthread_mutexattr_t _POSIX_Mutex_Default_attributes;
 
+RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Acquire_critical(
+  POSIX_Mutex_Control  *the_mutex,
+  Thread_queue_Context *queue_context
+)
+{
+  _CORE_mutex_Acquire_critical(
+    &the_mutex->Mutex.Recursive.Mutex,
+    queue_context
+  );
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Release(
+  POSIX_Mutex_Control  *the_mutex,
+  Thread_queue_Context *queue_context
+)
+{
+  _CORE_mutex_Release(
+    &the_mutex->Mutex.Recursive.Mutex,
+    queue_context
+  );
+}
+
 /**
  *  @brief POSIX Mutex Allocate
  *
diff --git a/cpukit/posix/src/mutexdestroy.c b/cpukit/posix/src/mutexdestroy.c
index 7fda7d3..57e6393 100644
--- a/cpukit/posix/src/mutexdestroy.c
+++ b/cpukit/posix/src/mutexdestroy.c
@@ -37,21 +37,23 @@ int pthread_mutex_destroy(
   the_mutex = _POSIX_Mutex_Get( mutex, &queue_context );
 
   if ( the_mutex != NULL ) {
-    _CORE_mutex_Acquire_critical( &the_mutex->Mutex, &queue_context );
+    _POSIX_Mutex_Acquire_critical( the_mutex, &queue_context );
 
     /*
      * XXX: There is an error for the mutex being locked
      *  or being in use by a condition variable.
      */
 
-    if ( !_CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
+    if (
+      !_CORE_mutex_Is_locked( &the_mutex->Mutex.Recursive.Mutex )
+    ) {
       _Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
-      _CORE_mutex_Release( &the_mutex->Mutex, &queue_context );
-      _CORE_mutex_Destroy( &the_mutex->Mutex );
+      _POSIX_Mutex_Release( the_mutex, &queue_context );
+      _CORE_mutex_Destroy( &the_mutex->Mutex.Recursive.Mutex );
       _POSIX_Mutex_Free( the_mutex );
       eno = 0;
     } else {
-      _CORE_mutex_Release( &the_mutex->Mutex, &queue_context );
+      _POSIX_Mutex_Release( the_mutex, &queue_context );
       eno = EBUSY;
     }
   } else {
diff --git a/cpukit/posix/src/mutexgetprioceiling.c b/cpukit/posix/src/mutexgetprioceiling.c
index 268457a..06eaf30 100644
--- a/cpukit/posix/src/mutexgetprioceiling.c
+++ b/cpukit/posix/src/mutexgetprioceiling.c
@@ -43,13 +43,13 @@ int pthread_mutex_getprioceiling(
     return EINVAL;
   }
 
-  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, &queue_context );
+  _POSIX_Mutex_Acquire_critical( the_mutex, &queue_context );
 
   *prioceiling = _POSIX_Priority_From_core(
-    the_mutex->Mutex.Attributes.priority_ceiling
+    the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling
   );
 
-  _CORE_mutex_Release( &the_mutex->Mutex, &queue_context );
+  _POSIX_Mutex_Release( the_mutex, &queue_context );
 
   return 0;
 }
diff --git a/cpukit/posix/src/mutexinit.c b/cpukit/posix/src/mutexinit.c
index d90b391..f2912ea 100644
--- a/cpukit/posix/src/mutexinit.c
+++ b/cpukit/posix/src/mutexinit.c
@@ -33,10 +33,9 @@ int pthread_mutex_init(
   const pthread_mutexattr_t *attr
 )
 {
-  POSIX_Mutex_Control          *the_mutex;
-  CORE_mutex_Attributes        *the_mutex_attr;
-  const pthread_mutexattr_t    *the_attr;
-  CORE_mutex_Disciplines        the_discipline;
+  POSIX_Mutex_Control       *the_mutex;
+  const pthread_mutexattr_t *the_attr;
+  POSIX_Mutex_Protocol       protocol;
 
   if ( attr ) the_attr = attr;
   else        the_attr = &_POSIX_Mutex_Default_attributes;
@@ -75,13 +74,13 @@ int pthread_mutex_init(
    */
   switch ( the_attr->protocol ) {
     case PTHREAD_PRIO_NONE:
-      the_discipline = CORE_MUTEX_DISCIPLINES_FIFO;
+      protocol = POSIX_MUTEX_NO_PROTOCOL;
       break;
     case PTHREAD_PRIO_INHERIT:
-      the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
+      protocol = POSIX_MUTEX_PRIORITY_INHERIT;
       break;
     case PTHREAD_PRIO_PROTECT:
-      the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
+      protocol = POSIX_MUTEX_PRIORITY_CEILING;
       break;
     default:
       return EINVAL;
@@ -117,21 +116,41 @@ int pthread_mutex_init(
     return EAGAIN;
   }
 
-  the_mutex_attr = &the_mutex->Mutex.Attributes;
-
-  if ( the_attr->type == PTHREAD_MUTEX_RECURSIVE )
-    the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
-  else
-    the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
-  the_mutex_attr->only_owner_release = true;
-  the_mutex_attr->priority_ceiling =
-    _POSIX_Priority_To_core( the_attr->prio_ceiling );
-  the_mutex_attr->discipline = the_discipline;
-
-  /*
-   *  Must be initialized to unlocked.
-   */
-  _CORE_mutex_Initialize( &the_mutex->Mutex, NULL, the_mutex_attr, false );
+  the_mutex->protocol = protocol;
+  the_mutex->is_recursive = ( the_attr->type == PTHREAD_MUTEX_RECURSIVE );
+
+  if ( protocol == POSIX_MUTEX_NO_PROTOCOL ) {
+    _CORE_recursive_mutex_Initialize(
+      &the_mutex->Mutex.Recursive
+    );
+  } else {
+    CORE_mutex_Attributes the_mutex_attr;
+
+    if ( the_attr->type == PTHREAD_MUTEX_RECURSIVE ) {
+      the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
+    } else {
+      the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
+    }
+
+    the_mutex_attr.priority_ceiling =
+      _POSIX_Priority_To_core( the_attr->prio_ceiling );
+
+    if ( protocol == POSIX_MUTEX_PRIORITY_CEILING ) {
+      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
+    } else {
+      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
+    }
+
+    /*
+     *  Must be initialized to unlocked.
+     */
+    _CORE_mutex_Initialize(
+      &the_mutex->Mutex.Recursive.Mutex,
+      NULL,
+      &the_mutex_attr,
+      false
+    );
+  }
 
   _Objects_Open_u32( &_POSIX_Mutex_Information, &the_mutex->Object, 0 );
 
diff --git a/cpukit/posix/src/mutexlocksupp.c b/cpukit/posix/src/mutexlocksupp.c
index 6ecf87c..2499ae1 100644
--- a/cpukit/posix/src/mutexlocksupp.c
+++ b/cpukit/posix/src/mutexlocksupp.c
@@ -21,16 +21,39 @@
 #include <rtems/posix/muteximpl.h>
 #include <rtems/posix/posixapi.h>
 
-THREAD_QUEUE_OBJECT_ASSERT( POSIX_Mutex_Control, Mutex.Wait_queue );
+THREAD_QUEUE_OBJECT_ASSERT(
+  POSIX_Mutex_Control,
+  Mutex.Recursive.Mutex.Wait_queue
+);
+
+static Status_Control _POSIX_Mutex_Lock_nested(
+  CORE_recursive_mutex_Control *the_recursive_mutex
+)
+{
+  POSIX_Mutex_Control *the_mutex;
+
+  the_mutex = RTEMS_CONTAINER_OF(
+    the_recursive_mutex,
+    POSIX_Mutex_Control,
+    Mutex.Recursive
+  );
+
+  if ( the_mutex->is_recursive ) {
+    return _CORE_recursive_mutex_Seize_nested( the_recursive_mutex );
+  } else {
+    return STATUS_NESTING_NOT_ALLOWED;
+  }
+}
 
 int _POSIX_Mutex_Lock_support(
   pthread_mutex_t   *mutex,
-  bool               blocking,
+  bool               wait,
   Watchdog_Interval  timeout
 )
 {
   POSIX_Mutex_Control  *the_mutex;
   Thread_queue_Context  queue_context;
+  Thread_Control       *executing;
   Status_Control        status;
 
   the_mutex = _POSIX_Mutex_Get( mutex, &queue_context );
@@ -39,12 +62,30 @@ int _POSIX_Mutex_Lock_support(
     return EINVAL;
   }
 
-  status = _CORE_mutex_Seize(
-    &the_mutex->Mutex,
-    _Thread_Executing,
-    blocking,
-    timeout,
-    &queue_context
-  );
+  executing = _Thread_Executing;
+
+  switch ( the_mutex->protocol ) {
+    case POSIX_MUTEX_NO_PROTOCOL:
+      status = _CORE_recursive_mutex_Seize_no_protocol(
+        &the_mutex->Mutex.Recursive,
+        POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS,
+        executing,
+        wait,
+        timeout,
+        _POSIX_Mutex_Lock_nested,
+        &queue_context
+      );
+      break;
+    default:
+      status = _CORE_mutex_Seize(
+        &the_mutex->Mutex.Recursive.Mutex,
+        executing,
+        wait,
+        timeout,
+        &queue_context
+      );
+      break;
+  }
+
   return _POSIX_Get_error( status );
 }
diff --git a/cpukit/posix/src/mutexsetprioceiling.c b/cpukit/posix/src/mutexsetprioceiling.c
index 20f14dc..5d11edf 100644
--- a/cpukit/posix/src/mutexsetprioceiling.c
+++ b/cpukit/posix/src/mutexsetprioceiling.c
@@ -57,9 +57,10 @@ int pthread_mutex_setprioceiling(
   _Assert( the_mutex != NULL );
 
   *old_ceiling = _POSIX_Priority_From_core(
-    the_mutex->Mutex.Attributes.priority_ceiling
+    the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling
   );
-  the_mutex->Mutex.Attributes.priority_ceiling = the_priority;
+  the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling =
+    the_priority;
 
   error = pthread_mutex_unlock( mutex );
   _Assert( error == 0 );
diff --git a/cpukit/posix/src/mutexunlock.c b/cpukit/posix/src/mutexunlock.c
index 1c3f2d8..b0ca33d 100644
--- a/cpukit/posix/src/mutexunlock.c
+++ b/cpukit/posix/src/mutexunlock.c
@@ -33,6 +33,7 @@ int pthread_mutex_unlock(
 {
   POSIX_Mutex_Control  *the_mutex;
   Thread_queue_Context  queue_context;
+  Thread_Control       *executing;
   Status_Control        status;
 
   the_mutex = _POSIX_Mutex_Get( mutex, &queue_context );
@@ -41,6 +42,24 @@ int pthread_mutex_unlock(
     return EINVAL;
   }
 
-  status = _CORE_mutex_Surrender( &the_mutex->Mutex, &queue_context );
+  executing = _Thread_Executing;
+
+  switch ( the_mutex->protocol ) {
+    case POSIX_MUTEX_NO_PROTOCOL:
+      status = _CORE_recursive_mutex_Surrender_no_protocol(
+        &the_mutex->Mutex.Recursive,
+        POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS,
+        executing,
+        &queue_context
+      );
+      break;
+    default:
+      status = _CORE_mutex_Surrender(
+        &the_mutex->Mutex.Recursive.Mutex,
+        &queue_context
+      );
+      break;
+  }
+
   return _POSIX_Get_error( status );
 }
diff --git a/cpukit/rtems/include/rtems/rtems/sem.h b/cpukit/rtems/include/rtems/rtems/sem.h
index fe74f44..220b0e3 100644
--- a/cpukit/rtems/include/rtems/rtems/sem.h
+++ b/cpukit/rtems/include/rtems/rtems/sem.h
@@ -83,7 +83,7 @@ typedef struct {
      *  This is the SuperCore Mutex instance associated with this Classic
      *  API Semaphore instance.
      */
-    CORE_mutex_Control     mutex;
+    CORE_ceiling_mutex_Control Mutex;
 
     /**
      *  This is the SuperCore Semaphore instance associated with this Classic
diff --git a/cpukit/rtems/include/rtems/rtems/semimpl.h b/cpukit/rtems/include/rtems/rtems/semimpl.h
index f3dfa02..5b789d6 100644
--- a/cpukit/rtems/include/rtems/rtems/semimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/semimpl.h
@@ -26,8 +26,14 @@
 extern "C" {
 #endif
 
+/**
+ * @brief Classic semaphore variants.
+ *
+ * Must be in synchronization with Semaphore_Control::variant.
+ */
 typedef enum {
   SEMAPHORE_VARIANT_MUTEX,
+  SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL,
   SEMAPHORE_VARIANT_SIMPLE_BINARY,
   SEMAPHORE_VARIANT_COUNTING
 #if defined(RTEMS_SMP)
diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c
index 455182b..91f693c 100644
--- a/cpukit/rtems/src/semcreate.c
+++ b/cpukit/rtems/src/semcreate.c
@@ -63,6 +63,7 @@ rtems_status_code rtems_semaphore_create(
 {
   Semaphore_Control     *the_semaphore;
   CORE_mutex_Attributes  the_mutex_attr;
+  Thread_Control        *executing;
   Status_Control         status;
 
   if ( !rtems_is_name_valid( name ) )
@@ -136,6 +137,7 @@ rtems_status_code rtems_semaphore_create(
 #endif
 
   the_semaphore->attribute_set = attribute_set;
+  executing = _Thread_Get_executing();
 
   if ( _Attributes_Is_priority( attribute_set ) ) {
     the_semaphore->discipline = SEMAPHORE_DISCIPLINE_PRIORITY;
@@ -163,43 +165,46 @@ rtems_status_code rtems_semaphore_create(
     status = _MRSP_Initialize(
       &the_semaphore->Core_control.mrsp,
       priority_ceiling,
-      _Thread_Get_executing(),
+      executing,
       count != 1
     );
 #endif
-  } else {
-    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX;
+  } else if (
+    !_Attributes_Is_inherit_priority( attribute_set )
+      && !_Attributes_Is_priority_ceiling( attribute_set )
+  ) {
+    _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
+    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL;
+    _CORE_recursive_mutex_Initialize(
+      &the_semaphore->Core_control.Mutex.Recursive
+    );
+
+    if ( count == 0 ) {
+      _CORE_mutex_Set_owner(
+        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
+        executing
+      );
+    }
 
+    status = STATUS_SUCCESSFUL;
+  } else {
     _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
+    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX;
 
-    /*
-     *  It is either simple binary semaphore or a more powerful mutex
-     *  style binary semaphore.  This is the mutex style.
-     */
-    if ( _Attributes_Is_priority( attribute_set ) )
-      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY;
-    else
-      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
-
-    the_mutex_attr.priority_ceiling      = _RTEMS_tasks_Priority_to_Core(
-                                             priority_ceiling
-                                           );
+    the_mutex_attr.priority_ceiling =
+      _RTEMS_tasks_Priority_to_Core( priority_ceiling );
     the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
-    the_mutex_attr.only_owner_release    = false;
-
-    if ( the_mutex_attr.discipline == CORE_MUTEX_DISCIPLINES_PRIORITY ) {
-      if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
-        the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
-        the_mutex_attr.only_owner_release = true;
-      } else if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
-        the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
-        the_mutex_attr.only_owner_release = true;
-      }
+
+    if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
+      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
+    } else {
+      _Assert( _Attributes_Is_priority_ceiling( attribute_set ) );
+      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
     }
 
     status = _CORE_mutex_Initialize(
-      &the_semaphore->Core_control.mutex,
-      _Thread_Get_executing(),
+      &the_semaphore->Core_control.Mutex.Recursive.Mutex,
+      executing,
       &the_mutex_attr,
       count != 1
     );
diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c
index 34da496b..365d895 100644
--- a/cpukit/rtems/src/semdelete.c
+++ b/cpukit/rtems/src/semdelete.c
@@ -51,7 +51,12 @@ rtems_status_code rtems_semaphore_delete(
 
   switch ( the_semaphore->variant ) {
     case SEMAPHORE_VARIANT_MUTEX:
-      if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) ) {
+    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
+      if (
+        _CORE_mutex_Is_locked(
+          &the_semaphore->Core_control.Mutex.Recursive.Mutex
+        )
+      ) {
         status = STATUS_RESOURCE_IN_USE;
       } else {
         status = STATUS_SUCCESSFUL;
@@ -92,6 +97,7 @@ rtems_status_code rtems_semaphore_delete(
     default:
       _Assert(
         the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
+          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
           || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
           || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
       );
diff --git a/cpukit/rtems/src/semflush.c b/cpukit/rtems/src/semflush.c
index 0db8c34..6c1f4dd 100644
--- a/cpukit/rtems/src/semflush.c
+++ b/cpukit/rtems/src/semflush.c
@@ -58,6 +58,7 @@ rtems_status_code rtems_semaphore_flush( rtems_id id )
     default:
       _Assert(
         the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
+          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
           || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
           || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
       );
diff --git a/cpukit/rtems/src/semobtain.c b/cpukit/rtems/src/semobtain.c
index 5eebfa1..a7774d6 100644
--- a/cpukit/rtems/src/semobtain.c
+++ b/cpukit/rtems/src/semobtain.c
@@ -29,7 +29,7 @@ THREAD_QUEUE_OBJECT_ASSERT(
 
 THREAD_QUEUE_OBJECT_ASSERT(
   Semaphore_Control,
-  Core_control.mutex.Wait_queue
+  Core_control.Mutex.Recursive.Mutex.Wait_queue
 );
 
 THREAD_QUEUE_OBJECT_ASSERT(
@@ -83,13 +83,24 @@ rtems_status_code rtems_semaphore_obtain(
 #endif
     case SEMAPHORE_VARIANT_MUTEX:
       status = _CORE_mutex_Seize(
-        &the_semaphore->Core_control.mutex,
+        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
         executing,
         wait,
         timeout,
         &queue_context
       );
       break;
+    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
+      status = _CORE_recursive_mutex_Seize_no_protocol(
+        &the_semaphore->Core_control.Mutex.Recursive,
+        _Semaphore_Get_operations( the_semaphore ),
+        executing,
+        wait,
+        timeout,
+        _CORE_recursive_mutex_Seize_nested,
+        &queue_context
+      );
+      break;
     default:
       _Assert(
         the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c
index 3e13334..7cd92cf 100644
--- a/cpukit/rtems/src/semrelease.c
+++ b/cpukit/rtems/src/semrelease.c
@@ -57,10 +57,18 @@ rtems_status_code rtems_semaphore_release( rtems_id id )
 #endif
     case SEMAPHORE_VARIANT_MUTEX:
       status = _CORE_mutex_Surrender(
-        &the_semaphore->Core_control.mutex,
+        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
         &queue_context
       );
       break;
+    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
+      _CORE_recursive_mutex_Surrender_no_protocol_classic(
+        &the_semaphore->Core_control.Mutex.Recursive,
+        _Semaphore_Get_operations( the_semaphore ),
+        &queue_context
+      );
+      status = STATUS_SUCCESSFUL;
+      break;
     case SEMAPHORE_VARIANT_SIMPLE_BINARY:
       status = _CORE_semaphore_Surrender(
         &the_semaphore->Core_control.semaphore,
diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c
index ee6614a..0a8c58c 100644
--- a/cpukit/rtems/src/semsetpriority.c
+++ b/cpukit/rtems/src/semsetpriority.c
@@ -54,8 +54,9 @@ static rtems_status_code _Semaphore_Set_priority(
   } else
 #endif
   if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
-    CORE_mutex_Control *mutex = &the_semaphore->Core_control.mutex;
+    CORE_mutex_Control *mutex;
 
+    mutex = &the_semaphore->Core_control.Mutex.Recursive.Mutex;
     _CORE_mutex_Acquire_critical( mutex, queue_context );
 
     old_priority = mutex->Attributes.priority_ceiling;
diff --git a/cpukit/score/include/rtems/score/coremutex.h b/cpukit/score/include/rtems/score/coremutex.h
index f869409..173bb2e 100644
--- a/cpukit/score/include/rtems/score/coremutex.h
+++ b/cpukit/score/include/rtems/score/coremutex.h
@@ -47,10 +47,6 @@ extern "C" {
  *  This enumerated type defines the blocking disciplines for a mutex.
  */
 typedef enum {
-  /** This specifies that threads will wait for the mutex in FIFO order. */
-  CORE_MUTEX_DISCIPLINES_FIFO,
-  /** This specifies that threads will wait for the mutex in priority order.  */
-  CORE_MUTEX_DISCIPLINES_PRIORITY,
   /** This specifies that threads will wait for the mutex in priority order.
    *  Additionally, the Priority Inheritance Protocol will be in effect.
    */
@@ -100,10 +96,6 @@ typedef struct {
    *  be when attempting to acquire the mutex when it is already locked.
    */
   CORE_mutex_Nesting_behaviors lock_nesting_behavior;
-  /** When this field is true, then only the thread that locked the mutex
-   *  is allowed to unlock it.
-   */
-  bool                         only_owner_release;
   /** This field indicates whether threads waiting on the mutex block in
    *  FIFO or priority order.
    */
@@ -125,11 +117,6 @@ typedef struct {
    */
   Thread_queue_Control    Wait_queue;
 
-  /**
-   * @brief The thread queue operations according to the blocking discipline.
-   */
-  const Thread_queue_Operations *operations;
-
   /** This element is the set of attributes which define this instance's
    *  behavior.
    */
@@ -145,6 +132,36 @@ typedef struct {
   Thread_Control         *holder;
 }   CORE_mutex_Control;
 
+/**
+ * @brief The recursive mutex control.
+ */
+typedef struct {
+  /**
+   * @brief The plain non-recursive mutex.
+   */
+  CORE_mutex_Control Mutex;
+
+  /**
+   * @brief The nest level in case of a recursive seize.
+   */
+  unsigned int nest_level;
+} CORE_recursive_mutex_Control;
+
+/**
+ * @brief The recursive mutex control with priority ceiling protocol support.
+ */
+typedef struct {
+  /**
+   * @brief The plain recursive mutex.
+   */
+  CORE_recursive_mutex_Control Recursive;
+
+  /**
+   * @brief The priority ceiling value for the mutex owner.
+   */
+  Priority_Control priority_ceiling;
+} CORE_ceiling_mutex_Control;
+
 /**@}*/
 
 #ifdef __cplusplus
diff --git a/cpukit/score/include/rtems/score/coremuteximpl.h b/cpukit/score/include/rtems/score/coremuteximpl.h
index f8869b0..fc2ffd9 100644
--- a/cpukit/score/include/rtems/score/coremuteximpl.h
+++ b/cpukit/score/include/rtems/score/coremuteximpl.h
@@ -33,6 +33,8 @@ extern "C" {
  */
 /**@{**/
 
+#define CORE_MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
+
 /**
  *  @brief Initializes the mutex based on the parameters passed.
  *
@@ -100,6 +102,13 @@ Status_Control _CORE_mutex_Seize_interrupt_blocking(
   Thread_queue_Context *queue_context
 );
 
+RTEMS_INLINE_ROUTINE Thread_Control *_CORE_mutex_Get_owner(
+  const CORE_mutex_Control *the_mutex
+)
+{
+  return the_mutex->holder;
+}
+
 /**
  * @brief Is mutex locked.
  *
@@ -115,7 +124,7 @@ RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(
   const CORE_mutex_Control *the_mutex
 )
 {
-  return the_mutex->holder != NULL;
+  return _CORE_mutex_Get_owner( the_mutex ) != NULL;
 }
 
 /**
@@ -180,10 +189,7 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_mutex_Seize_interrupt_trylock(
   if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
     the_mutex->holder     = executing;
     the_mutex->nest_count = 1;
-    if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
-         _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){
-      executing->resource_count++;
-    }
+    ++executing->resource_count;
 
     if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
       _CORE_mutex_Release( the_mutex, queue_context );
@@ -309,35 +315,168 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_mutex_Seize(
   );
 }
 
+Status_Control _CORE_mutex_Seize_no_protocol_slow(
+  CORE_mutex_Control            *the_mutex,
+  const Thread_queue_Operations *operations,
+  Thread_Control                *executing,
+  bool                           wait,
+  Watchdog_Interval              timeout,
+  Thread_queue_Context          *queue_context
+);
+
 Status_Control _CORE_mutex_Surrender(
   CORE_mutex_Control   *the_mutex,
   Thread_queue_Context *queue_context
 );
 
+RTEMS_INLINE_ROUTINE void _CORE_mutex_Set_owner(
+  CORE_mutex_Control *the_mutex,
+  Thread_Control     *owner
+)
+{
+  the_mutex->holder = owner;
+}
+
 RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_owner(
   const CORE_mutex_Control *the_mutex,
   const Thread_Control     *the_thread
 )
 {
-  return the_mutex->holder == the_thread;
+  return _CORE_mutex_Get_owner( the_mutex ) == the_thread;
 }
 
-/**
- * @brief Does core mutex use FIFO blocking.
- *
- * This routine returns true if the mutex's wait discipline is FIFO and false
- * otherwise.
- *
- * @param[in] the_attribute is the attribute set of the mutex.
- *
- * @retval true The mutex is using FIFO blocking order.
- * @retval false The mutex is not using FIFO blocking order.
+RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Initialize(
+  CORE_recursive_mutex_Control *the_mutex
+)
+{
+  _Thread_queue_Initialize( &the_mutex->Mutex.Wait_queue );
+  the_mutex->Mutex.holder = NULL;
+  the_mutex->nest_level = 0;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize_nested(
+  CORE_recursive_mutex_Control *the_mutex
+)
+{
+  ++the_mutex->nest_level;
+  return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize_no_protocol(
+  CORE_recursive_mutex_Control  *the_mutex,
+  const Thread_queue_Operations *operations,
+  Thread_Control                *executing,
+  bool                           wait,
+  Watchdog_Interval              timeout,
+  Status_Control              ( *nested )( CORE_recursive_mutex_Control * ),
+  Thread_queue_Context          *queue_context
+)
+{
+  Thread_Control *owner;
+
+  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
+
+  owner = _CORE_mutex_Get_owner( &the_mutex->Mutex );
+
+  if ( owner == NULL ) {
+    _CORE_mutex_Set_owner( &the_mutex->Mutex, executing );
+    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
+    return STATUS_SUCCESSFUL;
+  }
+
+  if ( owner == executing ) {
+    Status_Control status;
+
+    status = ( *nested )( the_mutex );
+    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
+    return status;
+  }
+
+  return _CORE_mutex_Seize_no_protocol_slow(
+    &the_mutex->Mutex,
+    operations,
+    executing,
+    wait,
+    timeout,
+    queue_context
+  );
+}
+
+RTEMS_INLINE_ROUTINE void
+_CORE_recursive_mutex_Surrender_no_protocol_finalize(
+  CORE_recursive_mutex_Control  *the_mutex,
+  const Thread_queue_Operations *operations,
+  Thread_queue_Context          *queue_context
+)
+{
+  unsigned int    nest_level;
+  Thread_Control *new_owner;
+
+  nest_level = the_mutex->nest_level;
+
+  if ( nest_level > 0 ) {
+    the_mutex->nest_level = nest_level - 1;
+    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
+    return;
+  }
+
+  new_owner = _Thread_queue_First_locked(
+    &the_mutex->Mutex.Wait_queue,
+    operations
+  );
+  _CORE_mutex_Set_owner( &the_mutex->Mutex, new_owner );
+
+  if ( new_owner == NULL ) {
+    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
+    return;
+  }
+
+  _Thread_queue_Extract_critical(
+    &the_mutex->Mutex.Wait_queue.Queue,
+    operations,
+    new_owner,
+    queue_context
+  );
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender_no_protocol(
+  CORE_recursive_mutex_Control  *the_mutex,
+  const Thread_queue_Operations *operations,
+  Thread_Control                *executing,
+  Thread_queue_Context          *queue_context
+)
+{
+  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
+
+  if ( !_CORE_mutex_Is_owner( &the_mutex->Mutex, executing ) ) {
+    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
+    return STATUS_NOT_OWNER;
+  }
+
+  _CORE_recursive_mutex_Surrender_no_protocol_finalize(
+    the_mutex,
+    operations,
+    queue_context
+  );
+  return STATUS_SUCCESSFUL;
+}
+
+/*
+ * The Classic no protocol recursive mutex has the nice property that everyone
+ * can release it.
  */
-RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo(
-  const CORE_mutex_Attributes *the_attribute
+RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Surrender_no_protocol_classic(
+  CORE_recursive_mutex_Control  *the_mutex,
+  const Thread_queue_Operations *operations,
+  Thread_queue_Context          *queue_context
 )
 {
-  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_FIFO;
+  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
+  _CORE_recursive_mutex_Surrender_no_protocol_finalize(
+    the_mutex,
+    operations,
+    queue_context
+  );
 }
 
 /** @} */
diff --git a/cpukit/score/src/apimutex.c b/cpukit/score/src/apimutex.c
index a098edb..8af374a 100644
--- a/cpukit/score/src/apimutex.c
+++ b/cpukit/score/src/apimutex.c
@@ -49,7 +49,6 @@ void _API_Mutex_Allocate(
 
   CORE_mutex_Attributes attr =  {
     CORE_MUTEX_NESTING_ACQUIRES,
-    true,
     CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT,
     0
   };
diff --git a/cpukit/score/src/coremutex.c b/cpukit/score/src/coremutex.c
index ec073ff..6f73c1b 100644
--- a/cpukit/score/src/coremutex.c
+++ b/cpukit/score/src/coremutex.c
@@ -39,42 +39,41 @@ Status_Control _CORE_mutex_Initialize(
   the_mutex->Attributes    = *the_mutex_attributes;
 
   if ( initially_locked ) {
-    bool is_priority_ceiling =
-      _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes );
+    bool              is_priority_ceiling;
+    Priority_Control  ceiling;
+    Per_CPU_Control  *cpu_self;
 
     the_mutex->nest_count = 1;
     the_mutex->holder     = executing;
 
-    if (  is_priority_ceiling ||
-         _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
-      Priority_Control ceiling = the_mutex->Attributes.priority_ceiling;
-      Per_CPU_Control *cpu_self;
-
-      /* The mutex initialization is only protected by the allocator lock */
-      cpu_self = _Thread_Dispatch_disable();
+    /* The mutex initialization is only protected by the allocator lock */
+    cpu_self = _Thread_Dispatch_disable();
 
+    is_priority_ceiling =
+      _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes );
+    ceiling = the_mutex->Attributes.priority_ceiling;
+
+    /*
+     * The test to check for a ceiling violation is a bit arbitrary.  In case
+     * this thread is the owner of a priority inheritance mutex, then it may
+     * get a higher priority later or anytime on SMP configurations.
+     */
+    if ( is_priority_ceiling && executing->current_priority < ceiling ) {
       /*
-       * The test to check for a ceiling violation is a bit arbitrary.  In case
-       * this thread is the owner of a priority inheritance mutex, then it may
-       * get a higher priority later or anytime on SMP configurations.
+       * There is no need to undo the previous work since this error aborts
+       * the object creation.
        */
-      if ( is_priority_ceiling && executing->current_priority < ceiling ) {
-        /*
-         * There is no need to undo the previous work since this error aborts
-         * the object creation.
-         */
-        _Thread_Dispatch_enable( cpu_self );
-        return STATUS_MUTEX_CEILING_VIOLATED;
-      }
-
-      executing->resource_count++;
+      _Thread_Dispatch_enable( cpu_self );
+      return STATUS_MUTEX_CEILING_VIOLATED;
+    }
 
-      if ( is_priority_ceiling ) {
-        _Thread_Raise_priority( executing, ceiling );
-      }
+    executing->resource_count++;
 
-      _Thread_Dispatch_enable( cpu_self );
+    if ( is_priority_ceiling ) {
+      _Thread_Raise_priority( executing, ceiling );
     }
+
+    _Thread_Dispatch_enable( cpu_self );
   } else {
     the_mutex->nest_count = 0;
     the_mutex->holder     = NULL;
@@ -82,11 +81,5 @@ Status_Control _CORE_mutex_Initialize(
 
   _Thread_queue_Initialize( &the_mutex->Wait_queue );
 
-  if ( _CORE_mutex_Is_fifo( the_mutex_attributes ) ) {
-    the_mutex->operations = &_Thread_queue_Operations_FIFO;
-  } else {
-    the_mutex->operations = &_Thread_queue_Operations_priority;
-  }
-
   return STATUS_SUCCESSFUL;
 }
diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c
index 7b8b603..596378f 100644
--- a/cpukit/score/src/coremutexseize.c
+++ b/cpukit/score/src/coremutexseize.c
@@ -68,7 +68,7 @@ Status_Control _CORE_mutex_Seize_interrupt_blocking(
 
   _Thread_queue_Enqueue_critical(
     &the_mutex->Wait_queue.Queue,
-    the_mutex->operations,
+    CORE_MUTEX_TQ_OPERATIONS,
     executing,
     STATES_WAITING_FOR_MUTEX,
     timeout,
@@ -82,3 +82,28 @@ Status_Control _CORE_mutex_Seize_interrupt_blocking(
   return _Thread_Wait_get_status( executing );
 }
 
+Status_Control _CORE_mutex_Seize_no_protocol_slow(
+  CORE_mutex_Control            *the_mutex,
+  const Thread_queue_Operations *operations,
+  Thread_Control                *executing,
+  bool                           wait,
+  Watchdog_Interval              timeout,
+  Thread_queue_Context          *queue_context
+)
+{
+  if ( wait ) {
+    _Thread_queue_Context_set_expected_level( queue_context, 1 );
+    _Thread_queue_Enqueue_critical(
+      &the_mutex->Wait_queue.Queue,
+      operations,
+      executing,
+      STATES_WAITING_FOR_MUTEX,
+      timeout,
+      queue_context
+    );
+    return _Thread_Wait_get_status( executing );
+  } else {
+    _CORE_mutex_Release( the_mutex, queue_context );
+    return STATUS_UNAVAILABLE;
+  }
+}
diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c
index 6047409..2d976e0 100644
--- a/cpukit/score/src/coremutexsurrender.c
+++ b/cpukit/score/src/coremutexsurrender.c
@@ -34,18 +34,12 @@ Status_Control _CORE_mutex_Surrender(
   holder = the_mutex->holder;
 
   /*
-   *  The following code allows a thread (or ISR) other than the thread
-   *  which acquired the mutex to release that mutex.  This is only
-   *  allowed when the mutex in quetion is FIFO or simple Priority
-   *  discipline.  But Priority Ceiling or Priority Inheritance mutexes
-   *  must be released by the thread which acquired them.
+   *  Priority Ceiling or Priority Inheritance mutexes must be released by the
+   *  thread which acquired them.
    */
-
-  if ( the_mutex->Attributes.only_owner_release ) {
-    if ( !_Thread_Is_executing( holder ) ) {
-      _ISR_lock_ISR_enable( &queue_context->Lock_context );
-      return STATUS_NOT_OWNER;
-    }
+  if ( !_Thread_Is_executing( holder ) ) {
+    _ISR_lock_ISR_enable( &queue_context->Lock_context );
+    return STATUS_NOT_OWNER;
   }
 
   _CORE_mutex_Acquire_critical( the_mutex, queue_context );
@@ -88,10 +82,7 @@ Status_Control _CORE_mutex_Surrender(
    *  Formally release the mutex before possibly transferring it to a
    *  blocked thread.
    */
-  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
-       _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
-    holder->resource_count--;
-  }
+   holder->resource_count--;
   the_mutex->holder = NULL;
 
   /*
@@ -101,7 +92,7 @@ Status_Control _CORE_mutex_Surrender(
   if (
     ( the_thread = _Thread_queue_First_locked(
         &the_mutex->Wait_queue,
-        the_mutex->operations
+        CORE_MUTEX_TQ_OPERATIONS
       )
     )
   ) {
@@ -118,7 +109,7 @@ Status_Control _CORE_mutex_Surrender(
      */
     unblock = _Thread_queue_Extract_locked(
       &the_mutex->Wait_queue.Queue,
-      the_mutex->operations,
+      CORE_MUTEX_TQ_OPERATIONS,
       the_thread,
       queue_context
     );
@@ -128,9 +119,6 @@ Status_Control _CORE_mutex_Surrender(
 #endif
     {
       switch ( the_mutex->Attributes.discipline ) {
-        case CORE_MUTEX_DISCIPLINES_FIFO:
-        case CORE_MUTEX_DISCIPLINES_PRIORITY:
-          break;
         case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
           the_thread->resource_count++;
           _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread );



More information about the vc mailing list