[PATCH 10/16] score: Introduce map priority scheduler operation

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Jun 17 10:51:47 UTC 2016


Introduce map/unmap priority scheduler operations to map thread priority
values from/to the user domain to/from the scheduler domain.  Use the
map priority operation to validate the thread priority.  The EDF
schedulers use this new operation to distinguish between normal
priorities and priorities obtain through a job release.
---
 cpukit/libmisc/monitor/mon-sema.c                  |   6 +-
 cpukit/posix/include/rtems/posix/priorityimpl.h    |  13 +-
 cpukit/posix/src/mutexgetprioceiling.c             |  12 +-
 cpukit/posix/src/mutexinit.c                       |   6 +-
 cpukit/posix/src/mutexsetprioceiling.c             |  36 ++--
 cpukit/posix/src/psxpriorityisvalid.c              |  25 ++-
 cpukit/posix/src/pthreadcreate.c                   |   3 +-
 cpukit/posix/src/pthreadgetschedparam.c            |   9 +-
 cpukit/rtems/src/semcreate.c                       |  59 ++++---
 cpukit/rtems/src/semsetpriority.c                  | 105 +++++++-----
 cpukit/rtems/src/tasksetpriority.c                 |  47 +++---
 cpukit/score/Makefile.am                           |   2 +
 cpukit/score/include/rtems/score/coremutex.h       |   9 +
 cpukit/score/include/rtems/score/coremuteximpl.h   |  42 +++++
 cpukit/score/include/rtems/score/mrspimpl.h        |  39 +++--
 cpukit/score/include/rtems/score/scheduler.h       |  40 +++++
 cpukit/score/include/rtems/score/schedulercbs.h    |   2 +
 cpukit/score/include/rtems/score/scheduleredf.h    |  12 ++
 cpukit/score/include/rtems/score/schedulerimpl.h   |  39 +++++
 .../score/include/rtems/score/schedulerpriority.h  |   2 +
 .../rtems/score/schedulerpriorityaffinitysmp.h     |   2 +
 .../include/rtems/score/schedulerprioritysmp.h     |   2 +
 cpukit/score/include/rtems/score/schedulersimple.h |   2 +
 .../score/include/rtems/score/schedulersimplesmp.h |   2 +
 .../score/include/rtems/score/schedulerstrongapa.h |   2 +
 cpukit/score/include/rtems/score/status.h          |   5 +
 cpukit/score/include/rtems/score/threadimpl.h      |  24 +++
 cpukit/score/src/schedulerdefaultmappriority.c     |  21 +++
 cpukit/score/src/schedulerdefaultunmappriority.c   |  23 +++
 cpukit/score/src/scheduleredfchangepriority.c      |  21 +++
 cpukit/score/src/threadcreateidle.c                |  11 +-
 cpukit/score/src/threadsetpriority.c               |  57 +++++++
 testsuites/psxtests/psxautoinit01/init.c           |   4 +
 testsuites/smptests/Makefile.am                    |   1 +
 testsuites/smptests/configure.ac                   |   1 +
 testsuites/smptests/smppsxmutex01/Makefile.am      |  19 +++
 testsuites/smptests/smppsxmutex01/init.c           | 184 +++++++++++++++++++++
 .../smptests/smppsxmutex01/smppsxmutex01.doc       |  12 ++
 .../smptests/smppsxmutex01/smppsxmutex01.scn       |   2 +
 testsuites/smptests/smpscheduler02/init.c          |  35 +++-
 testsuites/sptests/sp51/init.c                     |  10 ++
 testsuites/sptests/sp51/sp51.scn                   |   5 +-
 testsuites/sptests/spmrsp01/init.c                 |  13 ++
 43 files changed, 825 insertions(+), 141 deletions(-)
 create mode 100644 cpukit/score/src/schedulerdefaultmappriority.c
 create mode 100644 cpukit/score/src/schedulerdefaultunmappriority.c
 create mode 100644 testsuites/smptests/smppsxmutex01/Makefile.am
 create mode 100644 testsuites/smptests/smppsxmutex01/init.c
 create mode 100644 testsuites/smptests/smppsxmutex01/smppsxmutex01.doc
 create mode 100644 testsuites/smptests/smppsxmutex01/smppsxmutex01.scn

diff --git a/cpukit/libmisc/monitor/mon-sema.c b/cpukit/libmisc/monitor/mon-sema.c
index 272391f..7334611 100644
--- a/cpukit/libmisc/monitor/mon-sema.c
+++ b/cpukit/libmisc/monitor/mon-sema.c
@@ -61,8 +61,10 @@ rtems_monitor_sema_canonical(
 
     switch ( rtems_sema->variant ) {
       case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
-        canonical_sema->priority_ceiling =
-          rtems_sema->Core_control.Mutex.priority_ceiling;
+        canonical_sema->priority_ceiling = _Scheduler_Unmap_priority(
+          _CORE_ceiling_mutex_Get_scheduler( &rtems_sema->Core_control.Mutex ),
+          _CORE_ceiling_mutex_Get_priority( &rtems_sema->Core_control.Mutex )
+        );
         /* Fall through */
       case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY:
       case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
diff --git a/cpukit/posix/include/rtems/posix/priorityimpl.h b/cpukit/posix/include/rtems/posix/priorityimpl.h
index 54f5c9c..bc59742 100644
--- a/cpukit/posix/include/rtems/posix/priorityimpl.h
+++ b/cpukit/posix/include/rtems/posix/priorityimpl.h
@@ -79,20 +79,17 @@ bool _POSIX_Priority_To_core(
 );
 
 /**
- * @brief Converts SuperCore priority to POSIX priority.
+ * @brief Converts SuperCore priority to the corresponding POSIX API priority.
  *
  * @param[in] scheduler The scheduler instance.
- * @param[in] priority The SuperCore priority.
+ * @param[in] core_priority The SuperCore priority.
  *
  * @return Returns the corresponding POSIX API priority.
  */
-RTEMS_INLINE_ROUTINE int _POSIX_Priority_From_core(
+int _POSIX_Priority_From_core(
   const Scheduler_Control *scheduler,
-  Priority_Control         priority
-)
-{
-  return (int) ( scheduler->maximum_priority - priority );
-}
+  Priority_Control         core_priority
+);
 
 /** @} */
 
diff --git a/cpukit/posix/src/mutexgetprioceiling.c b/cpukit/posix/src/mutexgetprioceiling.c
index eda02cb..dfff98f 100644
--- a/cpukit/posix/src/mutexgetprioceiling.c
+++ b/cpukit/posix/src/mutexgetprioceiling.c
@@ -45,10 +45,14 @@ int pthread_mutex_getprioceiling(
 
   _POSIX_Mutex_Acquire_critical( the_mutex, &queue_context );
 
-  *prioceiling = _POSIX_Priority_From_core(
-    &_Scheduler_Table[ 0 ],
-    the_mutex->Mutex.priority_ceiling
-  );
+  if ( the_mutex->protocol == POSIX_MUTEX_PRIORITY_CEILING ) {
+    *prioceiling = _POSIX_Priority_From_core(
+      _CORE_ceiling_mutex_Get_scheduler( &the_mutex->Mutex ),
+      _CORE_ceiling_mutex_Get_priority( &the_mutex->Mutex )
+    );
+  } else {
+    *prioceiling = 0;
+  }
 
   _POSIX_Mutex_Release( the_mutex, &queue_context );
 
diff --git a/cpukit/posix/src/mutexinit.c b/cpukit/posix/src/mutexinit.c
index 7fbb53a..0b5f19e 100644
--- a/cpukit/posix/src/mutexinit.c
+++ b/cpukit/posix/src/mutexinit.c
@@ -19,6 +19,7 @@
 #endif
 
 #include <rtems/posix/muteximpl.h>
+#include <rtems/posix/posixapi.h>
 #include <rtems/posix/priorityimpl.h>
 #include <rtems/score/schedulerimpl.h>
 
@@ -133,10 +134,7 @@ int pthread_mutex_init(
 
   switch ( protocol ) {
     case POSIX_MUTEX_PRIORITY_CEILING:
-      _CORE_ceiling_mutex_Initialize(
-        &the_mutex->Mutex,
-        priority
-      );
+      _CORE_ceiling_mutex_Initialize( &the_mutex->Mutex, scheduler, priority );
       break;
     default:
       _Assert(
diff --git a/cpukit/posix/src/mutexsetprioceiling.c b/cpukit/posix/src/mutexsetprioceiling.c
index f1aa741..69aed16 100644
--- a/cpukit/posix/src/mutexsetprioceiling.c
+++ b/cpukit/posix/src/mutexsetprioceiling.c
@@ -19,6 +19,7 @@
 #endif
 
 #include <rtems/posix/muteximpl.h>
+#include <rtems/posix/posixapi.h>
 #include <rtems/posix/priorityimpl.h>
 
 /*
@@ -31,14 +32,13 @@ int pthread_mutex_setprioceiling(
   int               *old_ceiling
 )
 {
-  POSIX_Mutex_Control     *the_mutex;
-  const Scheduler_Control *scheduler;
-  Priority_Control         priority;
-  int                      error;
-  int                      unlock_error;
+  POSIX_Mutex_Control *the_mutex;
+  int                  error;
+  int                  unlock_error;
 
-  if ( !old_ceiling )
+  if ( old_ceiling == NULL ) {
     return EINVAL;
+  }
 
   /*
    *  Must acquire the mutex before we can change it's ceiling.
@@ -53,18 +53,24 @@ int pthread_mutex_setprioceiling(
   the_mutex = _POSIX_Mutex_Get_no_protection( mutex );
   _Assert( the_mutex != NULL );
 
-  scheduler = &_Scheduler_Table[ 0 ];
+  if ( the_mutex->protocol == POSIX_MUTEX_PRIORITY_CEILING ) {
+    const Scheduler_Control *scheduler;
+    Priority_Control         new_priority;
+    Priority_Control         old_priority;
 
-  *old_ceiling = _POSIX_Priority_From_core(
-    scheduler,
-    the_mutex->Mutex.priority_ceiling
-  );
+    scheduler = _CORE_ceiling_mutex_Get_scheduler( &the_mutex->Mutex );
+    old_priority = _CORE_ceiling_mutex_Get_priority( &the_mutex->Mutex );
+    *old_ceiling = _POSIX_Priority_From_core( scheduler, old_priority );
 
-  if ( _POSIX_Priority_To_core( scheduler, prioceiling, &priority ) ) {
-    the_mutex->Mutex.priority_ceiling = priority;
-    error = 0;
+    if ( _POSIX_Priority_To_core( scheduler, prioceiling, &new_priority ) ) {
+      _CORE_ceiling_mutex_Set_priority( &the_mutex->Mutex, new_priority );
+      error = 0;
+    } else {
+      error = EINVAL;
+    }
   } else {
-    error = EINVAL;
+    *old_ceiling = 0;
+    error = 0;
   }
 
   unlock_error = pthread_mutex_unlock( mutex );
diff --git a/cpukit/posix/src/psxpriorityisvalid.c b/cpukit/posix/src/psxpriorityisvalid.c
index 2d3a0d4..48b2794 100644
--- a/cpukit/posix/src/psxpriorityisvalid.c
+++ b/cpukit/posix/src/psxpriorityisvalid.c
@@ -19,6 +19,7 @@
 #endif
 
 #include <rtems/posix/priorityimpl.h>
+#include <rtems/score/schedulerimpl.h>
 
 int _POSIX_Priority_Get_maximum( const Scheduler_Control *scheduler )
 {
@@ -36,13 +37,27 @@ bool _POSIX_Priority_To_core(
 )
 {
   Priority_Control core_posix_priority;
-  Priority_Control core_priority;
 
   core_posix_priority = (Priority_Control) posix_priority;
-  core_priority = scheduler->maximum_priority - core_posix_priority;
 
-  *core_priority_p = core_priority;
+  if (
+    posix_priority < POSIX_SCHEDULER_MINIMUM_PRIORITY
+      || core_posix_priority >= scheduler->maximum_priority
+  ) {
+    return false;
+  }
+
+  *core_priority_p = scheduler->maximum_priority - core_posix_priority;
+
+  return _Scheduler_Map_priority( scheduler, core_priority_p );
+}
+
+int _POSIX_Priority_From_core(
+  const Scheduler_Control *scheduler,
+  Priority_Control         core_priority
+)
+{
+  core_priority = _Scheduler_Unmap_priority( scheduler, core_priority );
 
-  return posix_priority >= POSIX_SCHEDULER_MINIMUM_PRIORITY
-    && core_posix_priority < scheduler->maximum_priority;
+  return (int) ( scheduler->maximum_priority - core_priority );
 }
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index b471625..887c9ae 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -102,6 +102,7 @@ int pthread_create(
   #endif
 
   executing = _Thread_Get_executing();
+  scheduler = _Scheduler_Get_own( executing );
 
   /*
    *  P1003.1c/Draft 10, p. 121.
@@ -194,7 +195,7 @@ int pthread_create(
   status = _Thread_Initialize(
     &_POSIX_Threads_Information,
     the_thread,
-    _Scheduler_Get( executing ),
+    scheduler,
     the_attr->stackaddr,
     _POSIX_Threads_Ensure_minimum_stack(the_attr->stacksize),
     is_fp,
diff --git a/cpukit/posix/src/pthreadgetschedparam.c b/cpukit/posix/src/pthreadgetschedparam.c
index 55e4048..4f91f95 100644
--- a/cpukit/posix/src/pthreadgetschedparam.c
+++ b/cpukit/posix/src/pthreadgetschedparam.c
@@ -26,6 +26,7 @@
 
 #include <rtems/posix/pthreadimpl.h>
 #include <rtems/posix/priorityimpl.h>
+#include <rtems/score/schedulerimpl.h>
 #include <rtems/score/threadimpl.h>
 #include <rtems/score/schedulerimpl.h>
 
@@ -39,6 +40,7 @@ int pthread_getschedparam(
   ISR_lock_Context         lock_context;
   POSIX_API_Control       *api;
   const Scheduler_Control *scheduler;
+  Priority_Control         priority;
 
   if ( policy == NULL || param == NULL ) {
     return EINVAL;
@@ -58,11 +60,10 @@ int pthread_getschedparam(
   *param  = api->Attributes.schedparam;
 
   scheduler = _Scheduler_Get_own( the_thread );
-  param->sched_priority = _POSIX_Priority_From_core(
-    scheduler,
-    the_thread->real_priority
-  );
+  priority = the_thread->real_priority;
 
   _Thread_Lock_release_default( the_thread, &lock_context );
+
+  param->sched_priority = _POSIX_Priority_From_core( scheduler, priority );
   return 0;
 }
diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c
index bb1c6b4..c7a7821 100644
--- a/cpukit/rtems/src/semcreate.c
+++ b/cpukit/rtems/src/semcreate.c
@@ -22,6 +22,7 @@
 #include <rtems/rtems/attrimpl.h>
 #include <rtems/rtems/statusimpl.h>
 #include <rtems/rtems/tasksimpl.h>
+#include <rtems/score/schedulerimpl.h>
 #include <rtems/score/sysstate.h>
 
 #define SEMAPHORE_KIND_MASK ( RTEMS_SEMAPHORE_CLASS | RTEMS_INHERIT_PRIORITY \
@@ -35,12 +36,13 @@ rtems_status_code rtems_semaphore_create(
   rtems_id            *id
 )
 {
-  Semaphore_Control *the_semaphore;
-  Thread_Control    *executing;
-  Status_Control     status;
-  rtems_attribute    maybe_global;
-  rtems_attribute    mutex_with_protocol;
-  Semaphore_Variant  variant;
+  Semaphore_Control       *the_semaphore;
+  Thread_Control          *executing;
+  Status_Control           status;
+  rtems_attribute          maybe_global;
+  rtems_attribute          mutex_with_protocol;
+  Semaphore_Variant        variant;
+  const Scheduler_Control *scheduler;
 
   if ( !rtems_is_name_valid( name ) )
     return RTEMS_INVALID_NAME;
@@ -154,31 +156,38 @@ rtems_status_code rtems_semaphore_create(
       status = STATUS_SUCCESSFUL;
       break;
     case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
-      _CORE_ceiling_mutex_Initialize(
-        &the_semaphore->Core_control.Mutex,
-        priority_ceiling
-      );
-
-      if ( count == 0 ) {
-        Thread_queue_Context queue_context;
+      scheduler = _Scheduler_Get_own( executing );
 
-        _Thread_queue_Context_initialize( &queue_context );
-        _ISR_lock_ISR_disable( &queue_context.Lock_context );
-        _CORE_mutex_Acquire_critical(
-          &the_semaphore->Core_control.Mutex.Recursive.Mutex,
-          &queue_context
-        );
-        status = _CORE_ceiling_mutex_Set_owner(
+      if ( _Scheduler_Map_priority( scheduler, &priority_ceiling ) ) {
+        _CORE_ceiling_mutex_Initialize(
           &the_semaphore->Core_control.Mutex,
-          executing,
-          &queue_context
+          scheduler,
+          priority_ceiling
         );
 
-        if ( status != STATUS_SUCCESSFUL ) {
-          _Thread_queue_Destroy( &the_semaphore->Core_control.Wait_queue );
+        if ( count == 0 ) {
+          Thread_queue_Context queue_context;
+
+          _Thread_queue_Context_initialize( &queue_context );
+          _ISR_lock_ISR_disable( &queue_context.Lock_context );
+          _CORE_mutex_Acquire_critical(
+            &the_semaphore->Core_control.Mutex.Recursive.Mutex,
+            &queue_context
+          );
+          status = _CORE_ceiling_mutex_Set_owner(
+            &the_semaphore->Core_control.Mutex,
+            executing,
+            &queue_context
+          );
+
+          if ( status != STATUS_SUCCESSFUL ) {
+            _Thread_queue_Destroy( &the_semaphore->Core_control.Wait_queue );
+          }
+        } else {
+          status = STATUS_SUCCESSFUL;
         }
       } else {
-        status = STATUS_SUCCESSFUL;
+        status = STATUS_INVALID_PRIORITY;
       }
 
       break;
diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c
index 455cc15..4afed04 100644
--- a/cpukit/rtems/src/semsetpriority.c
+++ b/cpukit/rtems/src/semsetpriority.c
@@ -17,60 +17,84 @@
 #endif
 
 #include <rtems/rtems/semimpl.h>
+#include <rtems/rtems/statusimpl.h>
 #include <rtems/rtems/tasksimpl.h>
 #include <rtems/score/schedulerimpl.h>
 
-static rtems_status_code _Semaphore_Set_priority(
-  Semaphore_Control    *the_semaphore,
-  rtems_id              scheduler_id,
-  rtems_task_priority   new_priority,
-  rtems_task_priority  *old_priority_p,
-  Thread_queue_Context *queue_context
+static Status_Control _Semaphore_Is_scheduler_valid(
+  const CORE_ceiling_mutex_Control *the_mutex,
+  const Scheduler_Control          *scheduler
 )
 {
-  rtems_status_code    sc;
-  rtems_task_priority  old_priority;
 #if defined(RTEMS_SMP)
-  MRSP_Control        *mrsp;
-  uint32_t             scheduler_index;
+  if ( scheduler != _CORE_ceiling_mutex_Get_scheduler( the_mutex ) ) {
+    return STATUS_NOT_DEFINED;
+  }
 #endif
 
+  return STATUS_SUCCESSFUL;
+}
+
+static rtems_status_code _Semaphore_Set_priority(
+  Semaphore_Control       *the_semaphore,
+  const Scheduler_Control *scheduler,
+  rtems_task_priority      new_priority,
+  rtems_task_priority     *old_priority_p,
+  Thread_queue_Context    *queue_context
+)
+{
+  rtems_task_priority old_priority;
+  Status_Control      status;
+
   new_priority = _RTEMS_tasks_Priority_to_Core( new_priority );
 
+  if ( !_Scheduler_Map_priority( scheduler, &new_priority ) ) {
+    return RTEMS_INVALID_PRIORITY;
+  }
+
+  _Thread_queue_Acquire_critical(
+    &the_semaphore->Core_control.Wait_queue,
+    &queue_context->Lock_context
+  );
+
   switch ( the_semaphore->variant ) {
     case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
-      _CORE_mutex_Acquire_critical(
-        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
-        queue_context
+      status = _Semaphore_Is_scheduler_valid(
+        &the_semaphore->Core_control.Mutex,
+        scheduler
       );
 
-      old_priority = the_semaphore->Core_control.Mutex.priority_ceiling;
+      old_priority = _CORE_ceiling_mutex_Get_priority(
+        &the_semaphore->Core_control.Mutex
+      );
 
-      if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
-        the_semaphore->Core_control.Mutex.priority_ceiling = new_priority;
+      if (
+        status == STATUS_SUCCESSFUL
+          && new_priority != RTEMS_CURRENT_PRIORITY
+      ) {
+        _CORE_ceiling_mutex_Set_priority(
+          &the_semaphore->Core_control.Mutex,
+          new_priority
+        );
       }
 
-      _CORE_mutex_Release(
-        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
-        queue_context
-      );
-      sc = RTEMS_SUCCESSFUL;
       break;
 #if defined(RTEMS_SMP)
     case SEMAPHORE_VARIANT_MRSP:
-      mrsp = &the_semaphore->Core_control.MRSP;
-      scheduler_index = _Scheduler_Get_index_by_id( scheduler_id );
-
-      _MRSP_Acquire_critical( mrsp, queue_context );
-
-      old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index );
+      old_priority = _MRSP_Get_priority(
+        &the_semaphore->Core_control.MRSP,
+        scheduler
+      );
 
       if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
-        _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority );
+        _MRSP_Set_priority(
+          &the_semaphore->Core_control.MRSP,
+          scheduler,
+          new_priority
+        );
       }
 
-      _MRSP_Release( mrsp, queue_context );
-      sc = RTEMS_SUCCESSFUL;
+      status = STATUS_SUCCESSFUL;
       break;
 #endif
     default:
@@ -80,15 +104,19 @@ static rtems_status_code _Semaphore_Set_priority(
           || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
           || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
       );
-      _ISR_lock_ISR_enable( &queue_context->Lock_context );
       old_priority = 0;
-      sc = RTEMS_NOT_DEFINED;
+      status = STATUS_NOT_DEFINED;
       break;
   }
 
-  *old_priority_p = _RTEMS_tasks_Priority_from_Core( old_priority );
+  _Thread_queue_Release(
+    &the_semaphore->Core_control.Wait_queue,
+    &queue_context->Lock_context
+  );
 
-  return sc;
+  old_priority = _Scheduler_Unmap_priority( scheduler, old_priority );
+  *old_priority_p = _RTEMS_tasks_Priority_from_Core( old_priority );
+  return _Status_Get( status );
 }
 
 rtems_status_code rtems_semaphore_set_priority(
@@ -98,8 +126,9 @@ rtems_status_code rtems_semaphore_set_priority(
   rtems_task_priority *old_priority
 )
 {
-  Semaphore_Control    *the_semaphore;
-  Thread_queue_Context  queue_context;
+  const Scheduler_Control *scheduler;
+  Semaphore_Control       *the_semaphore;
+  Thread_queue_Context     queue_context;
 
   if ( new_priority != RTEMS_CURRENT_PRIORITY &&
        !_RTEMS_tasks_Priority_is_valid( new_priority ) ) {
@@ -110,7 +139,7 @@ rtems_status_code rtems_semaphore_set_priority(
     return RTEMS_INVALID_ADDRESS;
   }
 
-  if ( !_Scheduler_Is_id_valid( scheduler_id ) ) {
+  if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
     return RTEMS_INVALID_ID;
   }
 
@@ -128,7 +157,7 @@ rtems_status_code rtems_semaphore_set_priority(
 
   return _Semaphore_Set_priority(
     the_semaphore,
-    scheduler_id,
+    scheduler,
     new_priority,
     old_priority,
     &queue_context
diff --git a/cpukit/rtems/src/tasksetpriority.c b/cpukit/rtems/src/tasksetpriority.c
index 32a77f7..eff0740 100644
--- a/cpukit/rtems/src/tasksetpriority.c
+++ b/cpukit/rtems/src/tasksetpriority.c
@@ -19,52 +19,59 @@
 #endif
 
 #include <rtems/rtems/tasksimpl.h>
+#include <rtems/rtems/statusimpl.h>
+#include <rtems/score/schedulerimpl.h>
 #include <rtems/score/threadimpl.h>
 
 rtems_status_code rtems_task_set_priority(
   rtems_id             id,
   rtems_task_priority  new_priority,
-  rtems_task_priority *old_priority
+  rtems_task_priority *old_priority_p
 )
 {
   Thread_Control   *the_thread;
   ISR_lock_Context  lock_context;
-  Per_CPU_Control  *cpu_self;
+  Status_Control    status;
 
-  if ( new_priority != RTEMS_CURRENT_PRIORITY &&
-       !_RTEMS_tasks_Priority_is_valid( new_priority ) )
-    return RTEMS_INVALID_PRIORITY;
-
-  if ( !old_priority )
+  if ( old_priority_p == NULL ) {
     return RTEMS_INVALID_ADDRESS;
+  }
 
   the_thread = _Thread_Get( id, &lock_context );
 
   if ( the_thread == NULL ) {
 #if defined(RTEMS_MULTIPROCESSING)
-    return _RTEMS_tasks_MP_Set_priority( id, new_priority, old_priority );
+    return _RTEMS_tasks_MP_Set_priority( id, new_priority, old_priority_p );
 #else
     return RTEMS_INVALID_ID;
 #endif
   }
 
-  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
-  _ISR_lock_ISR_enable( &lock_context );
-
   if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
-    _Thread_Set_priority(
+    Per_CPU_Control *cpu_self;
+
+    cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+    _ISR_lock_ISR_enable( &lock_context );
+
+    status = _Thread_Map_and_set_priority(
       the_thread,
       _RTEMS_tasks_Priority_to_Core( new_priority ),
-      old_priority,
-      false
+      old_priority_p
     );
-    *old_priority = _RTEMS_tasks_Priority_from_Core( *old_priority );
+
+    _Thread_Dispatch_enable( cpu_self );
   } else {
-    *old_priority = _RTEMS_tasks_Priority_from_Core(
-      the_thread->current_priority
-    );
+    const Scheduler_Control *scheduler;
+    Priority_Control         old_priority;
+
+    _Thread_State_acquire_critical( the_thread, &lock_context );
+    scheduler = _Scheduler_Get_own( the_thread );
+    old_priority = the_thread->current_priority;
+    _Thread_State_release( the_thread, &lock_context );
+    *old_priority_p = _Scheduler_Unmap_priority( scheduler, old_priority );
+    status = STATUS_SUCCESSFUL;
   }
 
-  _Thread_Dispatch_enable( cpu_self );
-  return RTEMS_SUCCESSFUL;
+  *old_priority_p = _RTEMS_tasks_Priority_from_Core( *old_priority_p );
+  return _Status_Get( status );
 }
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 7166d72..5437562 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -227,12 +227,14 @@ libscore_a_SOURCES += src/log2table.c
 libscore_a_SOURCES += src/scheduler.c
 libscore_a_SOURCES += src/schedulergetaffinity.c
 libscore_a_SOURCES += src/schedulersetaffinity.c
+libscore_a_SOURCES += src/schedulerdefaultmappriority.c
 libscore_a_SOURCES += src/schedulerdefaultnodedestroy.c
 libscore_a_SOURCES += src/schedulerdefaultnodeinit.c
 libscore_a_SOURCES += src/schedulerdefaultreleasejob.c
 libscore_a_SOURCES += src/schedulerdefaultschedule.c
 libscore_a_SOURCES += src/schedulerdefaultstartidle.c
 libscore_a_SOURCES += src/schedulerdefaulttick.c
+libscore_a_SOURCES += src/schedulerdefaultunmappriority.c
 libscore_a_SOURCES += src/schedulerdefaultupdate.c
 
 ## SCHEDULERPRIORITY_C_FILES
diff --git a/cpukit/score/include/rtems/score/coremutex.h b/cpukit/score/include/rtems/score/coremutex.h
index 26bb539..a3dcabf 100644
--- a/cpukit/score/include/rtems/score/coremutex.h
+++ b/cpukit/score/include/rtems/score/coremutex.h
@@ -27,6 +27,8 @@
 #include <rtems/score/watchdog.h>
 #include <rtems/score/interr.h>
 
+struct Scheduler_Control;
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -83,6 +85,13 @@ typedef struct {
    * @brief The priority ceiling value for the mutex owner.
    */
   Priority_Control priority_ceiling;
+
+#if defined(RTEMS_SMP)
+  /**
+   * @brief The scheduler instance for this priority ceiling mutex.
+   */
+  const struct Scheduler_Control *scheduler;
+#endif
 } CORE_ceiling_mutex_Control;
 
 /**@}*/
diff --git a/cpukit/score/include/rtems/score/coremuteximpl.h b/cpukit/score/include/rtems/score/coremuteximpl.h
index 956dfa8..3a5ae99 100644
--- a/cpukit/score/include/rtems/score/coremuteximpl.h
+++ b/cpukit/score/include/rtems/score/coremuteximpl.h
@@ -20,6 +20,7 @@
 
 #include <rtems/score/coremutex.h>
 #include <rtems/score/chainimpl.h>
+#include <rtems/score/schedulerimpl.h>
 #include <rtems/score/status.h>
 #include <rtems/score/threadimpl.h>
 #include <rtems/score/threadqimpl.h>
@@ -358,11 +359,42 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender_no_protocol(
 
 RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Initialize(
   CORE_ceiling_mutex_Control *the_mutex,
+  const Scheduler_Control    *scheduler,
   Priority_Control            priority_ceiling
 )
 {
   _CORE_recursive_mutex_Initialize( &the_mutex->Recursive );
   the_mutex->priority_ceiling = priority_ceiling;
+#if defined(RTEMS_SMP)
+  the_mutex->scheduler = scheduler;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE const Scheduler_Control *
+_CORE_ceiling_mutex_Get_scheduler(
+  const CORE_ceiling_mutex_Control *the_mutex
+)
+{
+#if defined(RTEMS_SMP)
+  return the_mutex->scheduler;
+#else
+  return _Scheduler_Get_by_CPU_index( 0 );
+#endif
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Set_priority(
+  CORE_ceiling_mutex_Control *the_mutex,
+  Priority_Control            priority_ceiling
+)
+{
+  the_mutex->priority_ceiling = priority_ceiling;
+}
+
+RTEMS_INLINE_ROUTINE Priority_Control _CORE_ceiling_mutex_Get_priority(
+  const CORE_ceiling_mutex_Control *the_mutex
+)
+{
+  return the_mutex->priority_ceiling;
 }
 
 RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Set_owner(
@@ -414,6 +446,16 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Seize(
   owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
 
   if ( owner == NULL ) {
+#if defined(RTEMS_SMP)
+    if (
+      _Scheduler_Get_own( executing )
+        != _CORE_ceiling_mutex_Get_scheduler( the_mutex )
+    ) {
+      _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+      return STATUS_NOT_DEFINED;
+    }
+#endif
+
     return _CORE_ceiling_mutex_Set_owner(
       the_mutex,
       executing,
diff --git a/cpukit/score/include/rtems/score/mrspimpl.h b/cpukit/score/include/rtems/score/mrspimpl.h
index cdeaff3..16bc8ff 100644
--- a/cpukit/score/include/rtems/score/mrspimpl.h
+++ b/cpukit/score/include/rtems/score/mrspimpl.h
@@ -159,7 +159,17 @@ RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize(
   }
 
   for ( i = 0 ; i < scheduler_count ; ++i ) {
+    const Scheduler_Control *scheduler;
+
+    scheduler = _Scheduler_Get_by_CPU_index( i );
     mrsp->ceiling_priorities[ i ] = ceiling_priority;
+
+    if (
+      !_Scheduler_Map_priority( scheduler, &mrsp->ceiling_priorities[ i ] )
+    ) {
+      _Workspace_Free( mrsp->ceiling_priorities );
+      return STATUS_INVALID_PRIORITY;
+    }
   }
 
   _Resource_Initialize( &mrsp->Resource );
@@ -169,21 +179,30 @@ RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize(
   return STATUS_SUCCESSFUL;
 }
 
-RTEMS_INLINE_ROUTINE Priority_Control _MRSP_Get_ceiling_priority(
-  MRSP_Control *mrsp,
-  uint32_t      scheduler_index
+RTEMS_INLINE_ROUTINE Priority_Control _MRSP_Get_priority(
+  const MRSP_Control      *mrsp,
+  const Scheduler_Control *scheduler
 )
 {
-  return mrsp->ceiling_priorities[ scheduler_index ];
+  uint32_t scheduler_index;
+
+  scheduler_index = _Scheduler_Get_index( scheduler );
+  return _Scheduler_Unmap_priority(
+    scheduler,
+    mrsp->ceiling_priorities[ scheduler_index ]
+  );
 }
 
-RTEMS_INLINE_ROUTINE void _MRSP_Set_ceiling_priority(
-  MRSP_Control      *mrsp,
-  uint32_t           scheduler_index,
-  Priority_Control   ceiling_priority
+RTEMS_INLINE_ROUTINE void _MRSP_Set_priority(
+  MRSP_Control            *mrsp,
+  const Scheduler_Control *scheduler,
+  Priority_Control         new_priority
 )
 {
-  mrsp->ceiling_priorities[ scheduler_index ] = ceiling_priority;
+  uint32_t scheduler_index;
+
+  scheduler_index = _Scheduler_Get_index( scheduler );
+  mrsp->ceiling_priorities[ scheduler_index ] = new_priority;
 }
 
 RTEMS_INLINE_ROUTINE void _MRSP_Timeout( Watchdog_Control *watchdog )
@@ -310,7 +329,7 @@ RTEMS_INLINE_ROUTINE Status_Control _MRSP_Seize(
   uint32_t scheduler_index = _Scheduler_Get_index( scheduler );
   Priority_Control initial_priority = executing->current_priority;
   Priority_Control ceiling_priority =
-    _MRSP_Get_ceiling_priority( mrsp, scheduler_index );
+    mrsp->ceiling_priorities[ scheduler_index ];
   bool priority_ok = !_Thread_Priority_less_than(
     ceiling_priority,
     initial_priority
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index 2e9aba5..c4e2bb9 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -91,6 +91,18 @@ typedef struct {
     bool
   );
 
+  /** @see _Scheduler_Map_priority() */
+  bool ( *map_priority )(
+    const Scheduler_Control *,
+    Priority_Control *
+  );
+
+  /** @see _Scheduler_Unmap_priority() */
+  Priority_Control ( *unmap_priority )(
+    const Scheduler_Control *,
+    Priority_Control
+  );
+
 #if defined(RTEMS_SMP)
   /**
    * Ask for help operation.
@@ -403,6 +415,34 @@ extern const Scheduler_Control _Scheduler_Table[];
   extern const Scheduler_Assignment _Scheduler_Assignments[];
 #endif
 
+/**
+ * @brief Checks the priority is less than or equal to the maximum priority
+ *   value of this scheduler instance.
+ *
+ * @param[in] scheduler The scheduler control.
+ * @param[in] priority The priority which is not modified.
+ *
+ * @retval true The priority is valid.
+ * @retval false Otherwise.
+ */
+bool _Scheduler_default_Map_priority(
+  const Scheduler_Control *scheduler,
+  Priority_Control        *priority
+);
+
+/**
+ * @brief Returns the priority.
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] priority The priority.
+ *
+ * @return The priority.
+ */
+Priority_Control _Scheduler_default_Unmap_priority(
+  const Scheduler_Control *scheduler,
+  Priority_Control         priority
+);
+
 #if defined(RTEMS_SMP)
   /**
    * @brief Does nothing.
diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h
index 397488f..4e03e11 100644
--- a/cpukit/score/include/rtems/score/schedulercbs.h
+++ b/cpukit/score/include/rtems/score/schedulercbs.h
@@ -55,6 +55,8 @@ extern "C" {
     _Scheduler_EDF_Block,            /* block entry point */ \
     _Scheduler_CBS_Unblock,          /* unblock entry point */ \
     _Scheduler_EDF_Change_priority,  /* change priority entry point */ \
+    _Scheduler_EDF_Map_priority,     /* map priority entry point */ \
+    _Scheduler_EDF_Unmap_priority,   /* unmap priority entry point */ \
     SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
     _Scheduler_CBS_Node_initialize,  /* node initialize entry point */ \
     _Scheduler_default_Node_destroy, /* node destroy entry point */ \
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index 7d513ca..8dfc187 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -48,6 +48,8 @@ extern "C" {
     _Scheduler_EDF_Block,            /* block entry point */ \
     _Scheduler_EDF_Unblock,          /* unblock entry point */ \
     _Scheduler_EDF_Change_priority,  /* change priority entry point */ \
+    _Scheduler_EDF_Map_priority,     /* map priority entry point */ \
+    _Scheduler_EDF_Unmap_priority,   /* unmap priority entry point */ \
     SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
     _Scheduler_EDF_Node_initialize,  /* node initialize entry point */ \
     _Scheduler_default_Node_destroy, /* node destroy entry point */ \
@@ -203,6 +205,16 @@ Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
   bool                     prepend_it
 );
 
+bool _Scheduler_EDF_Map_priority(
+  const Scheduler_Control *scheduler,
+  Priority_Control        *priority
+);
+
+Priority_Control _Scheduler_EDF_Unmap_priority(
+  const Scheduler_Control *scheduler,
+  Priority_Control         priority
+);
+
 /**
  *  @brief invoked when a thread wishes to voluntarily
  *  transfer control of the processor to another thread
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 50061fb..fad7ecc 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -420,6 +420,45 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
 }
 
 /**
+ * @brief Maps a thread priority from the user domain to the scheduler domain.
+ *
+ * The mapping must be injective.  A scheduler domain value must exist for all
+ * user domain values from 0 up to and including the maximum scheduler
+ * priority.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in, out] priority The thread priority.
+ *
+ * @retval true The thread priority in the scheduler domain exists for the user
+ *   specified thread priority.  In this case the corresponding thread priority
+ *   of the scheduler domain is returned.
+ * @retval false Otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Scheduler_Map_priority(
+  const Scheduler_Control *scheduler,
+  Priority_Control        *priority
+)
+{
+  return ( *scheduler->Operations.map_priority )( scheduler, priority );
+}
+
+/**
+ * @brief Unmaps a thread priority from the scheduler domain to the user domain.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The thread priority.
+ *
+ * @return The corresponding thread priority of the user domain is returned.
+ */
+RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Unmap_priority(
+  const Scheduler_Control *scheduler,
+  Priority_Control         priority
+)
+{
+  return ( *scheduler->Operations.unmap_priority )( scheduler, priority );
+}
+
+/**
  * @brief Initializes a scheduler node.
  *
  * The scheduler node contains arbitrary data on function entry.  The caller
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index 0759941..d5e73c1 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -45,6 +45,8 @@ extern "C" {
     _Scheduler_priority_Block,            /* block entry point */ \
     _Scheduler_priority_Unblock,          /* unblock entry point */ \
     _Scheduler_priority_Change_priority,  /* change priority entry point */ \
+    _Scheduler_default_Map_priority,      /* map priority entry point */ \
+    _Scheduler_default_Unmap_priority,    /* unmap priority entry point */ \
     SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
     _Scheduler_default_Node_initialize,   /* node initialize entry point */ \
     _Scheduler_default_Node_destroy,      /* node destroy entry point */ \
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
index e2d6f3b..b0a7044 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
@@ -55,6 +55,8 @@ extern "C" {
     _Scheduler_priority_affinity_SMP_Block, \
     _Scheduler_priority_affinity_SMP_Unblock, \
     _Scheduler_priority_affinity_SMP_Change_priority, \
+    _Scheduler_default_Map_priority, \
+    _Scheduler_default_Unmap_priority, \
     _Scheduler_priority_affinity_SMP_Ask_for_help, \
     _Scheduler_priority_affinity_SMP_Node_initialize, \
     _Scheduler_default_Node_destroy, \
diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
index d550c78..0af7000 100644
--- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
@@ -84,6 +84,8 @@ typedef struct {
     _Scheduler_priority_SMP_Block, \
     _Scheduler_priority_SMP_Unblock, \
     _Scheduler_priority_SMP_Change_priority, \
+    _Scheduler_default_Map_priority, \
+    _Scheduler_default_Unmap_priority, \
     _Scheduler_priority_SMP_Ask_for_help, \
     _Scheduler_priority_SMP_Node_initialize, \
     _Scheduler_default_Node_destroy, \
diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h
index 9e40c4a..00f8dd7 100644
--- a/cpukit/score/include/rtems/score/schedulersimple.h
+++ b/cpukit/score/include/rtems/score/schedulersimple.h
@@ -45,6 +45,8 @@ extern "C" {
     _Scheduler_simple_Block,              /* block entry point */ \
     _Scheduler_simple_Unblock,            /* unblock entry point */ \
     _Scheduler_simple_Change_priority,    /* change priority entry point */ \
+    _Scheduler_default_Map_priority,      /* map priority entry point */ \
+    _Scheduler_default_Unmap_priority,    /* unmap priority entry point */ \
     SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
     _Scheduler_default_Node_initialize,   /* node initialize entry point */ \
     _Scheduler_default_Node_destroy,      /* node destroy entry point */ \
diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h
index b943353..31c837d 100644
--- a/cpukit/score/include/rtems/score/schedulersimplesmp.h
+++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h
@@ -67,6 +67,8 @@ typedef struct {
     _Scheduler_simple_SMP_Block, \
     _Scheduler_simple_SMP_Unblock, \
     _Scheduler_simple_SMP_Change_priority, \
+    _Scheduler_default_Map_priority, \
+    _Scheduler_default_Unmap_priority, \
     _Scheduler_simple_SMP_Ask_for_help, \
     _Scheduler_simple_SMP_Node_initialize, \
     _Scheduler_default_Node_destroy, \
diff --git a/cpukit/score/include/rtems/score/schedulerstrongapa.h b/cpukit/score/include/rtems/score/schedulerstrongapa.h
index 4f95aac..d7c3888 100644
--- a/cpukit/score/include/rtems/score/schedulerstrongapa.h
+++ b/cpukit/score/include/rtems/score/schedulerstrongapa.h
@@ -84,6 +84,8 @@ typedef struct {
     _Scheduler_strong_APA_Block, \
     _Scheduler_strong_APA_Unblock, \
     _Scheduler_strong_APA_Change_priority, \
+    _Scheduler_default_Map_priority, \
+    _Scheduler_default_Unmap_priority, \
     _Scheduler_strong_APA_Ask_for_help, \
     _Scheduler_strong_APA_Node_initialize, \
     _Scheduler_default_Node_destroy, \
diff --git a/cpukit/score/include/rtems/score/status.h b/cpukit/score/include/rtems/score/status.h
index eaf69c1..d30f731 100644
--- a/cpukit/score/include/rtems/score/status.h
+++ b/cpukit/score/include/rtems/score/status.h
@@ -38,6 +38,7 @@ typedef enum {
   STATUS_CLASSIC_INVALID_PRIORITY = 19,
   STATUS_CLASSIC_INVALID_SIZE = 8,
   STATUS_CLASSIC_NO_MEMORY = 26,
+  STATUS_CLASSIC_NOT_DEFINED = 11,
   STATUS_CLASSIC_NOT_OWNER_OF_RESOURCE = 23,
   STATUS_CLASSIC_OBJECT_WAS_DELETED = 7,
   STATUS_CLASSIC_RESOURCE_IN_USE = 12,
@@ -86,6 +87,8 @@ typedef enum {
     STATUS_BUILD( STATUS_CLASSIC_INTERNAL_ERROR, EINTR ),
   STATUS_INVALID_NUMBER =
     STATUS_BUILD( STATUS_CLASSIC_INVALID_NUMBER, EINVAL ),
+  STATUS_INVALID_PRIORITY =
+    STATUS_BUILD( STATUS_CLASSIC_INVALID_PRIORITY, EINVAL ),
   STATUS_MAXIMUM_COUNT_EXCEEDED =
     STATUS_BUILD( STATUS_CLASSIC_INTERNAL_ERROR, EOVERFLOW ),
   STATUS_MESSAGE_INVALID_SIZE =
@@ -102,6 +105,8 @@ typedef enum {
     STATUS_BUILD( STATUS_CLASSIC_UNSATISFIED, EDEADLK ),
   STATUS_NO_MEMORY =
     STATUS_BUILD( STATUS_CLASSIC_NO_MEMORY, EINVAL ),
+  STATUS_NOT_DEFINED =
+    STATUS_BUILD( STATUS_CLASSIC_NOT_DEFINED, EINVAL ),
   STATUS_NOT_OWNER =
     STATUS_BUILD( STATUS_CLASSIC_NOT_OWNER_OF_RESOURCE, EPERM ),
   STATUS_OBJECT_WAS_DELETED =
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 164773a..4bd1330 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -535,6 +535,30 @@ RTEMS_INLINE_ROUTINE void _Thread_Inherit_priority(
 void _Thread_Restore_priority( Thread_Control *the_thread );
 
 /**
+ * @brief Maps and sets the priority of a thread if the mapping was successful.
+ *
+ * It sets the real priority of the thread.  In addition it changes the current
+ * priority of the thread if the new priority is higher than the current
+ * priority or the thread owns no resources.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] new_priority The new priority of the thread.
+ * @param[out] old_priority The old real priority of the thread.  This pointer
+ * must not be @c NULL.
+ *
+ * @retval STATUS_SUCCESSFUL Successful operation.
+ * @retval STATUS_INVALID_PRIORITY An invalid thread priority was specified for
+ *   which no mapping to a value suitable for the scheduler exists.
+ *
+ * @see _Thread_Change_priority().
+ */
+Status_Control _Thread_Map_and_set_priority(
+  Thread_Control   *the_thread,
+  Priority_Control  new_priority,
+  Priority_Control *old_priority
+);
+
+/**
  * @brief Sets the priority of a thread.
  *
  * It sets the real priority of the thread.  In addition it changes the current
diff --git a/cpukit/score/src/schedulerdefaultmappriority.c b/cpukit/score/src/schedulerdefaultmappriority.c
new file mode 100644
index 0000000..dc68689
--- /dev/null
+++ b/cpukit/score/src/schedulerdefaultmappriority.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/scheduler.h>
+
+bool _Scheduler_default_Map_priority(
+  const Scheduler_Control *scheduler,
+  Priority_Control        *priority
+)
+{
+  return *priority <= scheduler->maximum_priority;
+}
diff --git a/cpukit/score/src/schedulerdefaultunmappriority.c b/cpukit/score/src/schedulerdefaultunmappriority.c
new file mode 100644
index 0000000..2f75298
--- /dev/null
+++ b/cpukit/score/src/schedulerdefaultunmappriority.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/scheduler.h>
+
+Priority_Control _Scheduler_default_Unmap_priority(
+  const Scheduler_Control *scheduler,
+  Priority_Control         priority
+)
+{
+  (void) scheduler;
+
+  return priority;
+}
diff --git a/cpukit/score/src/scheduleredfchangepriority.c b/cpukit/score/src/scheduleredfchangepriority.c
index 61e0481..1444dff 100644
--- a/cpukit/score/src/scheduleredfchangepriority.c
+++ b/cpukit/score/src/scheduleredfchangepriority.c
@@ -20,6 +20,27 @@
 
 #include <rtems/score/scheduleredfimpl.h>
 
+bool _Scheduler_EDF_Map_priority(
+  const Scheduler_Control *scheduler,
+  Priority_Control        *priority
+)
+{
+  if ( *priority > scheduler->maximum_priority ) {
+    return false;
+  }
+
+  *priority = SCHEDULER_EDF_PRIO_MSB | *priority;
+  return true;
+}
+
+Priority_Control _Scheduler_EDF_Unmap_priority(
+  const Scheduler_Control *scheduler,
+  Priority_Control         priority
+)
+{
+  return priority & ~SCHEDULER_EDF_PRIO_MSB;
+}
+
 Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread,
diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c
index 0df53ec..d76a7fa 100644
--- a/cpukit/score/src/threadcreateidle.c
+++ b/cpukit/score/src/threadcreateidle.c
@@ -19,6 +19,7 @@
 #endif
 
 #include <rtems/score/threadimpl.h>
+#include <rtems/score/assert.h>
 #include <rtems/score/schedulerimpl.h>
 #include <rtems/score/stackimpl.h>
 #include <rtems/score/sysstate.h>
@@ -30,6 +31,8 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
   Objects_Name             name;
   Thread_Control          *idle;
   const Scheduler_Control *scheduler;
+  Priority_Control         idle_priority;
+  bool                     success;
 
   scheduler = _Scheduler_Get_by_CPU( cpu );
 
@@ -41,12 +44,18 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
 
   name.name_u32 = _Objects_Build_name( 'I', 'D', 'L', 'E' );
 
+  idle_priority = scheduler->maximum_priority;
+  success = _Scheduler_Map_priority( scheduler, &idle_priority );
+  _Assert( success );
+  (void) success;
+
   /*
    *  The entire workspace is zeroed during its initialization.  Thus, all
    *  fields not explicitly assigned were explicitly zeroed by
    *  _Workspace_Initialization.
    */
   idle = _Thread_Internal_allocate();
+  _Assert( idle != NULL );
 
   _Thread_Initialize(
     &_Thread_Internal_information,
@@ -55,7 +64,7 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
     NULL,        /* allocate the stack */
     _Stack_Ensure_minimum( rtems_configuration_get_idle_task_stack_size() ),
     CPU_IDLE_TASK_IS_FP,
-    scheduler->maximum_priority,
+    idle_priority,
     true,        /* preemptable */
     THREAD_CPU_BUDGET_ALGORITHM_NONE,
     NULL,        /* no budget algorithm callout */
diff --git a/cpukit/score/src/threadsetpriority.c b/cpukit/score/src/threadsetpriority.c
index f6a061a..36d3d63 100644
--- a/cpukit/score/src/threadsetpriority.c
+++ b/cpukit/score/src/threadsetpriority.c
@@ -19,6 +19,63 @@
 #endif
 
 #include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulerimpl.h>
+
+typedef struct {
+  Priority_Control *old_priority;
+  Status_Control    status;
+} Thread_Map_and_set_context;
+
+static bool _Thread_Map_and_set_priority_filter(
+  Thread_Control   *the_thread,
+  Priority_Control *new_priority_ptr,
+  void             *arg
+)
+{
+  Thread_Map_and_set_context *context;
+  const Scheduler_Control    *scheduler;
+  Priority_Control            current_priority;
+  Priority_Control            new_priority;
+
+  context = arg;
+  scheduler = _Scheduler_Get_own( the_thread );
+
+  if ( !_Scheduler_Map_priority( scheduler, new_priority_ptr ) ) {
+    context->status = STATUS_INVALID_PRIORITY;
+    return false;
+  }
+
+  current_priority = the_thread->current_priority;
+  new_priority = *new_priority_ptr;
+
+  context->status = STATUS_SUCCESSFUL;
+  *context->old_priority =
+    _Scheduler_Unmap_priority( scheduler, current_priority );
+  the_thread->real_priority = new_priority;
+
+  return _Thread_Priority_less_than( current_priority, new_priority )
+    || !_Thread_Owns_resources( the_thread );
+}
+
+Status_Control _Thread_Map_and_set_priority(
+  Thread_Control   *the_thread,
+  Priority_Control  new_priority,
+  Priority_Control *old_priority
+)
+{
+  Thread_Map_and_set_context context;
+
+  context.old_priority = old_priority;
+  _Thread_Change_priority(
+    the_thread,
+    new_priority,
+    &context,
+    _Thread_Map_and_set_priority_filter,
+    false
+  );
+
+  return context.status;
+}
 
 static bool _Thread_Set_priority_filter(
   Thread_Control   *the_thread,
diff --git a/testsuites/psxtests/psxautoinit01/init.c b/testsuites/psxtests/psxautoinit01/init.c
index fb70a1e..f22cb1d 100644
--- a/testsuites/psxtests/psxautoinit01/init.c
+++ b/testsuites/psxtests/psxautoinit01/init.c
@@ -54,12 +54,16 @@ void *POSIX_Init(
   mutex1 = PTHREAD_MUTEX_INITIALIZER;
   mutex2 = PTHREAD_MUTEX_INITIALIZER;
   puts( "Init - pthread_mutex_getprioceiling - auto initialize - OK" );
+  prioceiling = 1;
   sc = pthread_mutex_getprioceiling( &mutex1, &prioceiling );
   fatal_posix_service_status( sc, 0, "mutex getprioceiling OK" );
+  rtems_test_assert( prioceiling == 0 );
 
   puts( "Init - pthread_mutex_getprioceiling - auto initialize - EINVAL" );
+  prioceiling = 1;
   sc = pthread_mutex_getprioceiling( &mutex2, &prioceiling );
   fatal_posix_service_status( sc, EINVAL, "mutex getprioceiling EINVAL" );
+  rtems_test_assert( prioceiling == 1 );
 
   puts( "Init - pthread_mutex_destroy - OK" );
   sc = pthread_mutex_destroy( &mutex1 );
diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am
index 9cefd26..66c2780 100644
--- a/testsuites/smptests/Makefile.am
+++ b/testsuites/smptests/Makefile.am
@@ -45,6 +45,7 @@ SUBDIRS += smpwakeafter01
 if HAS_POSIX
 SUBDIRS += smppsxaffinity01
 SUBDIRS += smppsxaffinity02
+SUBDIRS += smppsxmutex01
 SUBDIRS += smppsxsignal01
 endif
 endif
diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac
index 2ea9eec..2e70252 100644
--- a/testsuites/smptests/configure.ac
+++ b/testsuites/smptests/configure.ac
@@ -57,6 +57,7 @@ AM_CONDITIONAL(HAS_CPUSET,test x"${ac_cv_header_sys_cpuset_h}" = x"yes")
 
 # Explicitly list all Makefiles here
 AC_CONFIG_FILES([Makefile
+smppsxmutex01/Makefile
 smpstrongapa01/Makefile
 smp01/Makefile
 smp02/Makefile
diff --git a/testsuites/smptests/smppsxmutex01/Makefile.am b/testsuites/smptests/smppsxmutex01/Makefile.am
new file mode 100644
index 0000000..0b09b16
--- /dev/null
+++ b/testsuites/smptests/smppsxmutex01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = smppsxmutex01
+smppsxmutex01_SOURCES = init.c
+
+dist_rtems_tests_DATA = smppsxmutex01.scn smppsxmutex01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(smppsxmutex01_OBJECTS)
+LINK_LIBS = $(smppsxmutex01_LDLIBS)
+
+smppsxmutex01$(EXEEXT): $(smppsxmutex01_OBJECTS) $(smppsxmutex01_DEPENDENCIES)
+	@rm -f smppsxmutex01$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/smptests/smppsxmutex01/init.c b/testsuites/smptests/smppsxmutex01/init.c
new file mode 100644
index 0000000..761b5b9
--- /dev/null
+++ b/testsuites/smptests/smppsxmutex01/init.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems.h>
+#include <rtems/libcsupport.h>
+
+#include "tmacros.h"
+
+const char rtems_test_name[] = "SMPPSXMUTEX 1";
+
+#define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
+
+#define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
+
+typedef struct {
+  pthread_t thread_b;
+  pthread_mutexattr_t mtx_attr;
+  pthread_mutex_t mtx_a;
+  pthread_mutex_t mtx_b;
+} test_context;
+
+static test_context test_instance;
+
+static void *thread_b(void *arg)
+{
+  test_context *ctx;
+  rtems_id scheduler_b_id;
+  rtems_status_code sc;
+  int prio_ceiling;
+  int eno;
+
+  ctx = arg;
+
+  rtems_test_assert(rtems_get_current_processor() == 0);
+
+  sc = rtems_scheduler_ident(SCHED_B, &scheduler_b_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_set_scheduler(pthread_self(), scheduler_b_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rtems_test_assert(rtems_get_current_processor() == 1);
+
+  eno = pthread_mutex_init(&ctx->mtx_b, &ctx->mtx_attr);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutex_getprioceiling(&ctx->mtx_b, &prio_ceiling);
+  rtems_test_assert(eno == 0);
+  rtems_test_assert(prio_ceiling == 254);
+
+  eno = pthread_mutex_lock(&ctx->mtx_b);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutex_unlock(&ctx->mtx_b);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutex_destroy(&ctx->mtx_b);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutex_getprioceiling(&ctx->mtx_a, &prio_ceiling);
+  rtems_test_assert(eno == 0);
+  rtems_test_assert(prio_ceiling == 126);
+
+  eno = pthread_mutex_lock(&ctx->mtx_a);
+  rtems_test_assert(eno == EINVAL);
+
+  return ctx;
+}
+
+static void test(test_context *ctx)
+{
+  uint32_t cpu_count;
+  int prio_ceiling;
+  int eno;
+
+  cpu_count = rtems_get_processor_count();
+
+  rtems_test_assert(rtems_get_current_processor() == 0);
+
+  eno = pthread_mutexattr_init(&ctx->mtx_attr);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutexattr_setprotocol(&ctx->mtx_attr, PTHREAD_PRIO_PROTECT);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutex_init(&ctx->mtx_a, &ctx->mtx_attr);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutex_getprioceiling(&ctx->mtx_a, &prio_ceiling);
+  rtems_test_assert(eno == 0);
+  rtems_test_assert(prio_ceiling == 126);
+
+  eno = pthread_mutex_lock(&ctx->mtx_a);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutex_unlock(&ctx->mtx_a);
+  rtems_test_assert(eno == 0);
+
+  if (cpu_count > 1) {
+    void *exit_code;
+
+    eno = pthread_create(&ctx->thread_b, NULL, thread_b, ctx);
+    rtems_test_assert(eno == 0);
+
+    exit_code = NULL;
+    eno = pthread_join(ctx->thread_b, &exit_code);
+    rtems_test_assert(eno == 0);
+    rtems_test_assert(exit_code == ctx);
+  }
+
+  eno = pthread_mutex_destroy(&ctx->mtx_a);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutexattr_destroy(&ctx->mtx_attr);
+  rtems_test_assert(eno == 0);
+}
+
+static void *POSIX_Init(void *arg)
+{
+  rtems_resource_snapshot snapshot;
+
+  TEST_BEGIN();
+
+  rtems_resource_snapshot_take(&snapshot);
+
+  test(&test_instance);
+
+  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
+
+  TEST_END();
+  rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
+#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 2
+
+#define CONFIGURE_SMP_APPLICATION
+
+#define CONFIGURE_SMP_MAXIMUM_PROCESSORS 2
+
+#define CONFIGURE_SCHEDULER_PRIORITY_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP(a, 128);
+
+RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP(b, 256);
+
+#define CONFIGURE_SCHEDULER_CONTROLS \
+  RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP(a, SCHED_A), \
+  RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP(b, SCHED_B)  \
+
+#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
+  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
+  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/smptests/smppsxmutex01/smppsxmutex01.doc b/testsuites/smptests/smppsxmutex01/smppsxmutex01.doc
new file mode 100644
index 0000000..dd255da
--- /dev/null
+++ b/testsuites/smptests/smppsxmutex01/smppsxmutex01.doc
@@ -0,0 +1,12 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smppsxmutex01
+
+directives:
+
+  - pthread_mutex_lock()
+
+concepts:
+
+  - Ensure that priority ceiling mutexes work only in their dedicated scheduler
+    instance.
diff --git a/testsuites/smptests/smppsxmutex01/smppsxmutex01.scn b/testsuites/smptests/smppsxmutex01/smppsxmutex01.scn
new file mode 100644
index 0000000..e4c8a1a
--- /dev/null
+++ b/testsuites/smptests/smppsxmutex01/smppsxmutex01.scn
@@ -0,0 +1,2 @@
+*** BEGIN OF TEST SMPPSXMUTEX 1 ***
+*** END OF TEST SMPPSXMUTEX 1 ***
diff --git a/testsuites/smptests/smpscheduler02/init.c b/testsuites/smptests/smpscheduler02/init.c
index 479e468..52b3f61 100644
--- a/testsuites/smptests/smpscheduler02/init.c
+++ b/testsuites/smptests/smpscheduler02/init.c
@@ -35,6 +35,8 @@ const char rtems_test_name[] = "SMPSCHEDULER 2";
 
 static rtems_id main_task_id;
 
+static rtems_id sema_id;
+
 static void task(rtems_task_argument arg)
 {
   rtems_status_code sc;
@@ -45,6 +47,9 @@ static void task(rtems_task_argument arg)
   rtems_test_assert(sched_get_priority_min(SCHED_RR) == 1);
   rtems_test_assert(sched_get_priority_max(SCHED_RR) == 126);
 
+  sc = rtems_semaphore_obtain(sema_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_NOT_DEFINED);
+
   sc = rtems_event_transient_send(main_task_id);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
@@ -61,6 +66,7 @@ static void test(void)
   rtems_id scheduler_a_id;
   rtems_id scheduler_b_id;
   rtems_id scheduler_c_id;
+  rtems_task_priority prio;
   cpu_set_t cpuset;
   cpu_set_t first_cpu;
   cpu_set_t second_cpu;
@@ -95,6 +101,27 @@ static void test(void)
   sc = rtems_scheduler_ident(SCHED_C, &scheduler_c_id);
   rtems_test_assert(sc == RTEMS_UNSATISFIED);
 
+  sc = rtems_semaphore_create(
+    SCHED_A,
+    1,
+    RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING,
+    1,
+    &sema_id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  prio = 2;
+  sc = rtems_semaphore_set_priority(sema_id, scheduler_a_id, prio, &prio);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+  rtems_test_assert(prio == 1);
+
+  if (cpu_count > 1) {
+    prio = 1;
+    sc = rtems_semaphore_set_priority(sema_id, scheduler_b_id, prio, &prio);
+    rtems_test_assert(sc == RTEMS_NOT_DEFINED);
+    rtems_test_assert(prio == 2);
+  }
+
   CPU_ZERO(&cpuset);
   sc = rtems_scheduler_get_processor_set(
     scheduler_a_id,
@@ -182,6 +209,9 @@ static void test(void)
 
   sc = rtems_task_delete(task_id);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_semaphore_delete(sema_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 }
 
 #else /* defined(__RTEMS_HAVE_SYS_CPUSET_H__) */
@@ -212,6 +242,9 @@ static void Init(rtems_task_argument arg)
 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
 
+#define CONFIGURE_MAXIMUM_TASKS 2
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
 #define CONFIGURE_SMP_APPLICATION
 
 /* Lets see when the first RTEMS system hits this limit */
@@ -269,8 +302,6 @@ RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(c);
   RTEMS_SCHEDULER_ASSIGN_NO_SCHEDULER, \
   RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
 
-#define CONFIGURE_MAXIMUM_TASKS 2
-
 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
 
 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
diff --git a/testsuites/sptests/sp51/init.c b/testsuites/sptests/sp51/init.c
index 48f0146..1e8f9e5 100644
--- a/testsuites/sptests/sp51/init.c
+++ b/testsuites/sptests/sp51/init.c
@@ -61,6 +61,16 @@ rtems_task Init(
 
   TEST_BEGIN();
 
+  puts( "Create semaphore - priority ceiling unlocked - invalid ceiling" );
+  sc = rtems_semaphore_create(
+    rtems_build_name( 'S', 'E', 'M', '1' ),
+    0,
+    RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING | RTEMS_PRIORITY,
+    UINT32_MAX,
+    &mutex
+  );
+  fatal_directive_status(sc, RTEMS_INVALID_PRIORITY, "rtems_semaphore_create");
+
   puts( "Create semaphore - priority ceiling locked - violate ceiling" );
   sc = rtems_semaphore_create(
     rtems_build_name( 'S', 'E', 'M', '1' ),
diff --git a/testsuites/sptests/sp51/sp51.scn b/testsuites/sptests/sp51/sp51.scn
index 9fe4622..4ade359 100644
--- a/testsuites/sptests/sp51/sp51.scn
+++ b/testsuites/sptests/sp51/sp51.scn
@@ -1,6 +1,7 @@
-*** TEST 51 ***
+*** BEGIN OF TEST SP 51 ***
+Create semaphore - priority ceiling unlocked - invalid ceiling
 Create semaphore - priority ceiling locked - violate ceiling
 Create semaphore - priority ceiling unlocked
 Obtain semaphore -- violate ceiling
 Release semaphore we did not obtain
-*** END OF TEST 51 ***
+*** END OF TEST SP 51 ***
diff --git a/testsuites/sptests/spmrsp01/init.c b/testsuites/sptests/spmrsp01/init.c
index d5acb0a..e5e522f 100644
--- a/testsuites/sptests/spmrsp01/init.c
+++ b/testsuites/sptests/spmrsp01/init.c
@@ -45,8 +45,21 @@ static void create_not_defined(rtems_attribute attr)
 
 static void test_mrsp_create_errors(void)
 {
+  rtems_status_code sc;
+  rtems_id id;
+
   puts("test MrsP create errors");
 
+  sc = rtems_semaphore_create(
+    rtems_build_name('M', 'R', 'S', 'P'),
+    1,
+    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+      | RTEMS_BINARY_SEMAPHORE,
+    UINT32_MAX,
+    &id
+  );
+  rtems_test_assert(sc == RTEMS_INVALID_PRIORITY);
+
   create_not_defined(
     RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
       | RTEMS_COUNTING_SEMAPHORE
-- 
1.8.4.5





More information about the devel mailing list