summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-10 08:48:54 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-22 14:36:40 +0200
commit77ff5599e0d8e6d91190a379be21a332f83252b0 (patch)
tree339e28b236beb9e606322cb801d7340e2e44f8bf
parentb8f76fa28e1e7258fbf9b15894fbf1be5b1fbe15 (diff)
downloadrtems-77ff5599e0d8e6d91190a379be21a332f83252b0.tar.bz2
score: Introduce map priority scheduler operation
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. Update #2173. Update #2556.
-rw-r--r--cpukit/libmisc/monitor/mon-sema.c6
-rw-r--r--cpukit/posix/include/rtems/posix/priorityimpl.h7
-rw-r--r--cpukit/posix/src/mutexgetprioceiling.c12
-rw-r--r--cpukit/posix/src/mutexinit.c9
-rw-r--r--cpukit/posix/src/mutexsetprioceiling.c39
-rw-r--r--cpukit/posix/src/psxpriorityisvalid.c13
-rw-r--r--cpukit/posix/src/pthreadcreate.c3
-rw-r--r--cpukit/rtems/include/rtems/rtems/tasksimpl.h7
-rw-r--r--cpukit/rtems/src/semcreate.c2
-rw-r--r--cpukit/rtems/src/semsetpriority.c69
-rw-r--r--cpukit/score/Makefile.am1
-rw-r--r--cpukit/score/include/rtems/score/coremutex.h9
-rw-r--r--cpukit/score/include/rtems/score/coremuteximpl.h42
-rw-r--r--cpukit/score/include/rtems/score/mrspimpl.h46
-rw-r--r--cpukit/score/include/rtems/score/scheduler.h27
-rw-r--r--cpukit/score/include/rtems/score/schedulercbs.h2
-rw-r--r--cpukit/score/include/rtems/score/scheduleredf.h12
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h37
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriority.h2
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h2
-rw-r--r--cpukit/score/include/rtems/score/schedulerprioritysmp.h2
-rw-r--r--cpukit/score/include/rtems/score/schedulersimple.h2
-rw-r--r--cpukit/score/include/rtems/score/schedulersimplesmp.h2
-rw-r--r--cpukit/score/include/rtems/score/schedulerstrongapa.h2
-rw-r--r--cpukit/score/include/rtems/score/status.h3
-rw-r--r--cpukit/score/src/schedulerdefaultmappriority.c21
-rw-r--r--cpukit/score/src/scheduleredfchangepriority.c16
-rw-r--r--cpukit/score/src/threadcreateidle.c4
-rw-r--r--testsuites/psxtests/psxautoinit01/init.c4
-rw-r--r--testsuites/smptests/Makefile.am1
-rw-r--r--testsuites/smptests/configure.ac1
-rw-r--r--testsuites/smptests/smppsxmutex01/Makefile.am19
-rw-r--r--testsuites/smptests/smppsxmutex01/init.c184
-rw-r--r--testsuites/smptests/smppsxmutex01/smppsxmutex01.doc12
-rw-r--r--testsuites/smptests/smppsxmutex01/smppsxmutex01.scn2
-rw-r--r--testsuites/smptests/smpscheduler02/init.c35
36 files changed, 573 insertions, 84 deletions
diff --git a/cpukit/libmisc/monitor/mon-sema.c b/cpukit/libmisc/monitor/mon-sema.c
index 272391f01e..7334611465 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 ae2e763fba..b986d64cd5 100644
--- a/cpukit/posix/include/rtems/posix/priorityimpl.h
+++ b/cpukit/posix/include/rtems/posix/priorityimpl.h
@@ -88,13 +88,10 @@ Priority_Control _POSIX_Priority_To_core(
*
* @return 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 );
-}
+);
/** @} */
diff --git a/cpukit/posix/src/mutexgetprioceiling.c b/cpukit/posix/src/mutexgetprioceiling.c
index eda02cba83..dfff98f9b7 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 2cda90ea05..0dacc3fa03 100644
--- a/cpukit/posix/src/mutexinit.c
+++ b/cpukit/posix/src/mutexinit.c
@@ -135,19 +135,14 @@ 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(
the_mutex->protocol == POSIX_MUTEX_NO_PROTOCOL
|| the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT
);
- _CORE_recursive_mutex_Initialize(
- &the_mutex->Mutex.Recursive
- );
+ _CORE_recursive_mutex_Initialize( &the_mutex->Mutex.Recursive );
break;
}
diff --git a/cpukit/posix/src/mutexsetprioceiling.c b/cpukit/posix/src/mutexsetprioceiling.c
index 478aafa6e0..31e54c5fc3 100644
--- a/cpukit/posix/src/mutexsetprioceiling.c
+++ b/cpukit/posix/src/mutexsetprioceiling.c
@@ -31,15 +31,13 @@ int pthread_mutex_setprioceiling(
int *old_ceiling
)
{
- POSIX_Mutex_Control *the_mutex;
- const Scheduler_Control *scheduler;
- bool valid;
- 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.
@@ -54,19 +52,26 @@ 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;
+ bool valid;
+ 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 );
- priority = _POSIX_Priority_To_core( scheduler, prioceiling, &valid );
- if ( valid ) {
- the_mutex->Mutex.priority_ceiling = priority;
- error = 0;
+ new_priority = _POSIX_Priority_To_core( scheduler, prioceiling, &valid );
+ if ( valid ) {
+ _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 22c4ac0b87..7c2300b4d6 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 )
{
@@ -44,5 +45,15 @@ Priority_Control _POSIX_Priority_To_core(
*valid = ( posix_priority >= POSIX_SCHEDULER_MINIMUM_PRIORITY
&& core_posix_priority < scheduler->maximum_priority );
- return core_priority;
+ return _Scheduler_Map_priority( scheduler, core_priority );
+}
+
+int _POSIX_Priority_From_core(
+ const Scheduler_Control *scheduler,
+ Priority_Control core_priority
+)
+{
+ core_priority = _Scheduler_Unmap_priority( scheduler, core_priority );
+
+ return (int) ( scheduler->maximum_priority - core_priority );
}
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index b266a4cd7f..54b6a71040 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -103,6 +103,7 @@ int pthread_create(
#endif
executing = _Thread_Get_executing();
+ scheduler = _Scheduler_Get_own( executing );
/*
* P1003.1c/Draft 10, p. 121.
@@ -197,7 +198,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/rtems/include/rtems/rtems/tasksimpl.h b/cpukit/rtems/include/rtems/rtems/tasksimpl.h
index c7f8952bcf..b0432351f3 100644
--- a/cpukit/rtems/include/rtems/rtems/tasksimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/tasksimpl.h
@@ -19,7 +19,7 @@
#include <rtems/rtems/tasks.h>
#include <rtems/score/objectimpl.h>
-#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerimpl.h>
#include <rtems/score/threadimpl.h>
#ifdef __cplusplus
@@ -96,7 +96,7 @@ RTEMS_INLINE_ROUTINE Priority_Control _RTEMS_Priority_To_core(
{
*valid = ( priority <= scheduler->maximum_priority );
- return (Priority_Control) priority;
+ return _Scheduler_Map_priority( scheduler, (Priority_Control) priority );
}
/**
@@ -113,7 +113,8 @@ RTEMS_INLINE_ROUTINE rtems_task_priority _RTEMS_Priority_From_core(
Priority_Control priority
)
{
- return (rtems_task_priority) priority;
+ return (rtems_task_priority)
+ _Scheduler_Unmap_priority( scheduler, priority );
}
/**@}*/
diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c
index f03475ee33..7d49542203 100644
--- a/cpukit/rtems/src/semcreate.c
+++ b/cpukit/rtems/src/semcreate.c
@@ -163,6 +163,7 @@ rtems_status_code rtems_semaphore_create(
if ( valid ) {
_CORE_ceiling_mutex_Initialize(
&the_semaphore->Core_control.Mutex,
+ scheduler,
priority
);
@@ -200,6 +201,7 @@ rtems_status_code rtems_semaphore_create(
if ( valid ) {
status = _MRSP_Initialize(
&the_semaphore->Core_control.MRSP,
+ scheduler,
priority,
executing,
count == 0
diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c
index 37d7a207ca..5c331bb292 100644
--- a/cpukit/rtems/src/semsetpriority.c
+++ b/cpukit/rtems/src/semsetpriority.c
@@ -20,6 +20,20 @@
#include <rtems/rtems/tasksimpl.h>
#include <rtems/score/schedulerimpl.h>
+static rtems_status_code _Semaphore_Is_scheduler_valid(
+ const CORE_ceiling_mutex_Control *the_mutex,
+ const Scheduler_Control *scheduler
+)
+{
+#if defined(RTEMS_SMP)
+ if ( scheduler != _CORE_ceiling_mutex_Get_scheduler( the_mutex ) ) {
+ return RTEMS_NOT_DEFINED;
+ }
+#endif
+
+ return RTEMS_SUCCESSFUL;
+}
+
static rtems_status_code _Semaphore_Set_priority(
Semaphore_Control *the_semaphore,
const Scheduler_Control *scheduler,
@@ -32,49 +46,51 @@ static rtems_status_code _Semaphore_Set_priority(
bool valid;
Priority_Control core_priority;
Priority_Control old_priority;
-#if defined(RTEMS_SMP)
- MRSP_Control *mrsp;
- uint32_t scheduler_index;
-#endif
core_priority = _RTEMS_Priority_To_core( scheduler, new_priority, &valid );
if ( new_priority != RTEMS_CURRENT_PRIORITY && !valid ) {
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
+ sc = _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 = core_priority;
+ if ( sc == RTEMS_SUCCESSFUL && new_priority != RTEMS_CURRENT_PRIORITY ) {
+ _CORE_ceiling_mutex_Set_priority(
+ &the_semaphore->Core_control.Mutex,
+ core_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( scheduler );
-
- _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, core_priority );
+ _MRSP_Set_priority(
+ &the_semaphore->Core_control.MRSP,
+ scheduler,
+ core_priority
+ );
}
- _MRSP_Release( mrsp, queue_context );
sc = RTEMS_SUCCESSFUL;
break;
#endif
@@ -85,14 +101,17 @@ 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;
break;
}
- *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
+ _Thread_queue_Release(
+ &the_semaphore->Core_control.Wait_queue,
+ &queue_context->Lock_context
+ );
+ *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
return sc;
}
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 7166d72750..97f0b3d615 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -227,6 +227,7 @@ 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
diff --git a/cpukit/score/include/rtems/score/coremutex.h b/cpukit/score/include/rtems/score/coremutex.h
index 26bb53920a..a3dcabf523 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 956dfa81ee..3a5ae99a95 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 cdeaff35c1..66f5cc6640 100644
--- a/cpukit/score/include/rtems/score/mrspimpl.h
+++ b/cpukit/score/include/rtems/score/mrspimpl.h
@@ -138,10 +138,11 @@ RTEMS_INLINE_ROUTINE void _MRSP_Claim_ownership(
}
RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize(
- MRSP_Control *mrsp,
- Priority_Control ceiling_priority,
- Thread_Control *executing,
- bool initially_locked
+ MRSP_Control *mrsp,
+ const Scheduler_Control *scheduler,
+ Priority_Control ceiling_priority,
+ Thread_Control *executing,
+ bool initially_locked
)
{
uint32_t scheduler_count = _Scheduler_Count;
@@ -159,7 +160,16 @@ RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize(
}
for ( i = 0 ; i < scheduler_count ; ++i ) {
- mrsp->ceiling_priorities[ i ] = ceiling_priority;
+ const Scheduler_Control *scheduler_of_cpu;
+
+ scheduler_of_cpu = _Scheduler_Get_by_CPU_index( i );
+
+ if ( scheduler != scheduler_of_cpu ) {
+ mrsp->ceiling_priorities[ i ] =
+ _Scheduler_Map_priority( scheduler_of_cpu, 0 );
+ } else {
+ mrsp->ceiling_priorities[ i ] = ceiling_priority;
+ }
}
_Resource_Initialize( &mrsp->Resource );
@@ -169,21 +179,27 @@ 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
)
{
+ uint32_t scheduler_index;
+
+ scheduler_index = _Scheduler_Get_index( scheduler );
return 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 )
@@ -307,10 +323,8 @@ RTEMS_INLINE_ROUTINE Status_Control _MRSP_Seize(
{
Status_Control status;
const Scheduler_Control *scheduler = _Scheduler_Get_own( executing );
- 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 );
+ Priority_Control ceiling_priority = _MRSP_Get_priority( mrsp, scheduler );
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 2e9aba5072..ba9c2b50bb 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() */
+ Priority_Control ( *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,21 @@ extern const Scheduler_Control _Scheduler_Table[];
extern const Scheduler_Assignment _Scheduler_Assignments[];
#endif
+/**
+ * @brief Returns the thread priority.
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] priority The thread priority.
+ *
+ * @return priority The thread priority.
+ */
+Priority_Control _Scheduler_default_Map_priority(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+);
+
+#define _Scheduler_default_Unmap_priority _Scheduler_default_Map_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 397488fc40..4e03e111a6 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 7d513ca416..042143f80d 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
);
+Priority_Control _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 50061fbe67..36214729d7 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -420,6 +420,43 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
}
/**
+ * @brief Maps a thread priority from the user domain to the scheduler domain.
+ *
+ * Let M be the maximum scheduler priority. The mapping must be bijective in
+ * the closed interval [0, M], e.g. _Scheduler_Unmap_priority( scheduler,
+ * _Scheduler_Map_priority( scheduler, p ) ) == p for all p in [0, M]. For
+ * other values the mapping is undefined.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The user domain thread priority.
+ *
+ * @return The corresponding thread priority of the scheduler domain is returned.
+ */
+RTEMS_INLINE_ROUTINE Priority_Control _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 scheduler domain 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 07599416d6..d5e73c19fc 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 e2d6f3b1c7..b0a704478c 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 d550c78836..0af7000808 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 9e40c4ac44..00f8dd790f 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 b9433534c6..31c837d00d 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 4f95aac8fb..d7c3888d5a 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 f6ebaa46f1..d30f731a70 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,
@@ -104,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/src/schedulerdefaultmappriority.c b/cpukit/score/src/schedulerdefaultmappriority.c
new file mode 100644
index 0000000000..37a600011e
--- /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>
+
+Priority_Control _Scheduler_default_Map_priority(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+)
+{
+ return priority;
+}
diff --git a/cpukit/score/src/scheduleredfchangepriority.c b/cpukit/score/src/scheduleredfchangepriority.c
index 61e0481d03..6efbf87ad3 100644
--- a/cpukit/score/src/scheduleredfchangepriority.c
+++ b/cpukit/score/src/scheduleredfchangepriority.c
@@ -20,6 +20,22 @@
#include <rtems/score/scheduleredfimpl.h>
+Priority_Control _Scheduler_EDF_Map_priority(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+)
+{
+ return SCHEDULER_EDF_PRIO_MSB | priority;
+}
+
+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 0df53ecfab..89e5d60a18 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>
@@ -47,6 +48,7 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
* _Workspace_Initialization.
*/
idle = _Thread_Internal_allocate();
+ _Assert( idle != NULL );
_Thread_Initialize(
&_Thread_Internal_information,
@@ -55,7 +57,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,
+ _Scheduler_Map_priority( scheduler, scheduler->maximum_priority ),
true, /* preemptable */
THREAD_CPU_BUDGET_ALGORITHM_NONE,
NULL, /* no budget algorithm callout */
diff --git a/testsuites/psxtests/psxautoinit01/init.c b/testsuites/psxtests/psxautoinit01/init.c
index fb70a1e63e..f22cb1dc9d 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 9cefd268f1..66c2780260 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 2ea9eec214..2e702522a5 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 0000000000..0b09b16bd9
--- /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@.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 0000000000..761b5b9d51
--- /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@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 0000000000..dd255daeda
--- /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 0000000000..e4c8a1a3ef
--- /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 479e468147..52b3f61816 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