[PATCH 07/16] posix: Make POSIX API aware of scheduler instances
Sebastian Huber
sebastian.huber at embedded-brains.de
Fri Jun 17 10:51:44 UTC 2016
---
cpukit/posix/include/rtems/posix/priorityimpl.h | 82 ++++++++++---------------
cpukit/posix/src/mutexgetprioceiling.c | 1 +
cpukit/posix/src/mutexinit.c | 5 +-
cpukit/posix/src/mutexsetprioceiling.c | 35 +++++++----
cpukit/posix/src/psxpriorityisvalid.c | 8 +--
cpukit/posix/src/pthread.c | 4 +-
cpukit/posix/src/pthreadcreate.c | 11 ++--
cpukit/posix/src/pthreadgetschedparam.c | 11 +++-
cpukit/posix/src/pthreadsetschedparam.c | 11 ++--
cpukit/posix/src/pthreadsetschedprio.c | 7 ++-
10 files changed, 94 insertions(+), 81 deletions(-)
diff --git a/cpukit/posix/include/rtems/posix/priorityimpl.h b/cpukit/posix/include/rtems/posix/priorityimpl.h
index e3f23e7..7e770f7 100644
--- a/cpukit/posix/include/rtems/posix/priorityimpl.h
+++ b/cpukit/posix/include/rtems/posix/priorityimpl.h
@@ -30,29 +30,10 @@ extern "C" {
*
* @ingroup POSIXAPI
*
- * @brief Interface to the POSIX Priority Implementation
- *
- */
-/**@{**/
-
-/**
- * 1003.1b-1993,2.2.2.80 definition of priority, p. 19
- *
- * "Numerically higher values represent higher priorities."
- *
- * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API.
- *
- * There are only 254 posix priority levels since a task at priority level
- * 255 would never run because of the RTEMS idle task. This is necessary
- * because GNAT maps the lowest Ada task priority to the lowest thread
- * priority. The lowest priority Ada task should get to run, so there is
- * a fundamental conflict with having 255 priorities.
+ * @brief Interface to the POSIX Priority Implementation.
*
- * But since RTEMS can be configured with fewer than 256 priorities,
- * we use the internal constant.
+ * @{
*/
-#define POSIX_SCHEDULER_MAXIMUM_PRIORITY (PRIORITY_MAXIMUM - 1)
-
/**
* This is the numerically least important POSIX priority.
@@ -72,53 +53,58 @@ int _POSIX_Priority_Get_maximum( const Scheduler_Control *scheduler );
/**
* @brief Check if POSIX priority is valid.
*
- * 1003.1b-1993,2.2.2.80 definition of priority, p. 19
- *
- * "Numerically higher values represent higher priorities."
- *
- * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API.
- *
- * @param[in] priority is the priority to test
- *
- * @retval TRUE The priority is valid.
- * @retval FALSE The priority is invalid.
+ * According to POSIX, numerically higher values represent higher priorities.
+ * Thus, SuperCore has priorities run in the opposite sense of the POSIX API.
+ *
+ * Let N be the maximum priority of this scheduler instance. The SuperCore
+ * priority zero is system reserved (PRIORITY_PSEUDO_ISR). There are only
+ * N - 1 POSIX API priority levels since a thread at SuperCore priority N would
+ * never run because of the idle threads. This is necessary because GNAT maps
+ * the lowest Ada task priority to the lowest thread priority. The lowest
+ * priority Ada task should get to run, so there is a fundamental conflict with
+ * having N priorities.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The POSIX API priority to test.
+ *
+ * @retval true The priority is valid.
+ * @retval false Otherwise.
*/
bool _POSIX_Priority_Is_valid(
- int priority
+ const Scheduler_Control *scheduler,
+ int priority
);
/**
- * @brief Convert POSIX priority to SuperCore priority.
- *
- * This method converts a POSIX API priority into onto the corresponding
- * SuperCore value.
+ * @brief Converts POSIX priority to SuperCore priority.
*
- * @param[in] priority is the POSIX API priority.
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The POSIX API priority.
*
- * @return This method returns the corresponding SuperCore priority.
+ * @return Returns the corresponding SuperCore priority.
*/
RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Priority_To_core(
- int priority
+ const Scheduler_Control *scheduler,
+ int priority
)
{
- return (Priority_Control) (POSIX_SCHEDULER_MAXIMUM_PRIORITY - priority + 1);
+ return scheduler->maximum_priority - (Priority_Control) priority;
}
/**
- * @brief Convert SuperCore priority To POSIX priority.
- *
- * This method converts a SuperCore priority into onto the corresponding
- * POSIX API value.
+ * @brief Converts SuperCore priority to POSIX priority.
*
- * @param[in] priority is the POSIX API priority.
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The SuperCore priority.
*
- * @return This method returns the corresponding POSIX priority.
+ * @return Returns the corresponding POSIX API priority.
*/
RTEMS_INLINE_ROUTINE int _POSIX_Priority_From_core(
- Priority_Control priority
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
)
{
- return (POSIX_SCHEDULER_MAXIMUM_PRIORITY - priority + 1);
+ return (int) ( scheduler->maximum_priority - priority );
}
/** @} */
diff --git a/cpukit/posix/src/mutexgetprioceiling.c b/cpukit/posix/src/mutexgetprioceiling.c
index 2df4776..eda02cb 100644
--- a/cpukit/posix/src/mutexgetprioceiling.c
+++ b/cpukit/posix/src/mutexgetprioceiling.c
@@ -46,6 +46,7 @@ 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
);
diff --git a/cpukit/posix/src/mutexinit.c b/cpukit/posix/src/mutexinit.c
index 0d4833e..04c36e1 100644
--- a/cpukit/posix/src/mutexinit.c
+++ b/cpukit/posix/src/mutexinit.c
@@ -20,6 +20,7 @@
#include <rtems/posix/muteximpl.h>
#include <rtems/posix/priorityimpl.h>
+#include <rtems/score/schedulerimpl.h>
/**
* 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
@@ -115,11 +116,11 @@ int pthread_mutex_init(
prio_ceiling = _POSIX_Priority_Get_maximum( scheduler );
}
- if ( !_POSIX_Priority_Is_valid( prio_ceiling ) ) {
+ if ( !_POSIX_Priority_Is_valid( scheduler, prio_ceiling ) ) {
return EINVAL;
}
- priority = _POSIX_Priority_To_core( prio_ceiling );
+ priority = _POSIX_Priority_To_core( scheduler, prio_ceiling );
}
the_mutex = _POSIX_Mutex_Allocate();
diff --git a/cpukit/posix/src/mutexsetprioceiling.c b/cpukit/posix/src/mutexsetprioceiling.c
index 96e8dbf..65b93c7 100644
--- a/cpukit/posix/src/mutexsetprioceiling.c
+++ b/cpukit/posix/src/mutexsetprioceiling.c
@@ -31,18 +31,14 @@ int pthread_mutex_setprioceiling(
int *old_ceiling
)
{
- register POSIX_Mutex_Control *the_mutex;
- Priority_Control the_priority;
- int error;
+ POSIX_Mutex_Control *the_mutex;
+ const Scheduler_Control *scheduler;
+ int error;
+ int unlock_error;
if ( !old_ceiling )
return EINVAL;
- if ( !_POSIX_Priority_Is_valid( prioceiling ) )
- return EINVAL;
-
- the_priority = _POSIX_Priority_To_core( prioceiling );
-
/*
* Must acquire the mutex before we can change it's ceiling.
* POSIX says block until we acquire it.
@@ -56,13 +52,26 @@ int pthread_mutex_setprioceiling(
the_mutex = _POSIX_Mutex_Get_no_protection( mutex );
_Assert( the_mutex != NULL );
+ scheduler = &_Scheduler_Table[ 0 ];
+
*old_ceiling = _POSIX_Priority_From_core(
+ scheduler,
the_mutex->Mutex.priority_ceiling
);
- the_mutex->Mutex.priority_ceiling = the_priority;
- error = pthread_mutex_unlock( mutex );
- _Assert( error == 0 );
- (void) error;
- return 0;
+ if ( _POSIX_Priority_Is_valid( scheduler, prioceiling ) ) {
+ Priority_Control priority;
+
+ priority = _POSIX_Priority_To_core( scheduler, prioceiling );
+ the_mutex->Mutex.priority_ceiling = priority;
+
+ error = 0;
+ } else {
+ error = EINVAL;
+ }
+
+ unlock_error = pthread_mutex_unlock( mutex );
+ _Assert( unlock_error == 0 );
+ (void) unlock_error;
+ return error;
}
diff --git a/cpukit/posix/src/psxpriorityisvalid.c b/cpukit/posix/src/psxpriorityisvalid.c
index c883416..ea7f6f4 100644
--- a/cpukit/posix/src/psxpriorityisvalid.c
+++ b/cpukit/posix/src/psxpriorityisvalid.c
@@ -30,11 +30,11 @@ int _POSIX_Priority_Get_maximum( const Scheduler_Control *scheduler )
}
bool _POSIX_Priority_Is_valid(
- int priority
+ const Scheduler_Control *scheduler,
+ int priority
)
{
- return ((priority >= POSIX_SCHEDULER_MINIMUM_PRIORITY) &&
- (priority <= POSIX_SCHEDULER_MAXIMUM_PRIORITY));
-
+ return priority >= POSIX_SCHEDULER_MINIMUM_PRIORITY
+ && (Priority_Control) priority < scheduler->maximum_priority;
}
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index ca7efa9..b29acae 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -37,8 +37,9 @@
#include <rtems/posix/psignalimpl.h>
#include <rtems/posix/config.h>
#include <rtems/posix/keyimpl.h>
-#include <rtems/score/cpusetimpl.h>
#include <rtems/score/assert.h>
+#include <rtems/score/cpusetimpl.h>
+#include <rtems/score/schedulerimpl.h>
Thread_Information _POSIX_Threads_Information;
@@ -182,6 +183,7 @@ static bool _POSIX_Threads_Create_extension(
api->thread = created;
_POSIX_Threads_Initialize_attributes( &api->Attributes );
api->Attributes.schedparam.sched_priority = _POSIX_Priority_From_core(
+ _Scheduler_Get_own( created ),
created->current_priority
);
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index f2fc1ca..a4b4684 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -70,6 +70,7 @@ int pthread_create(
bool status;
Thread_Control *the_thread;
Thread_Control *executing;
+ const Scheduler_Control *scheduler;
POSIX_API_Control *api;
int schedpolicy = SCHED_RR;
struct sched_param schedparam;
@@ -151,16 +152,18 @@ int pthread_create(
high_prio = low_prio;
}
- if ( !_POSIX_Priority_Is_valid( low_prio ) ) {
+ scheduler = _Scheduler_Get_own( executing );
+
+ if ( !_POSIX_Priority_Is_valid( scheduler, low_prio ) ) {
return EINVAL;
}
- if ( !_POSIX_Priority_Is_valid( high_prio ) ) {
+ if ( !_POSIX_Priority_Is_valid( scheduler, high_prio ) ) {
return EINVAL;
}
- core_low_prio = _POSIX_Priority_To_core( low_prio );
- core_high_prio = _POSIX_Priority_To_core( high_prio );
+ core_low_prio = _POSIX_Priority_To_core( scheduler, low_prio );
+ core_high_prio = _POSIX_Priority_To_core( scheduler, high_prio );
#if defined(RTEMS_SMP)
#if __RTEMS_HAVE_SYS_CPUSET_H__
diff --git a/cpukit/posix/src/pthreadgetschedparam.c b/cpukit/posix/src/pthreadgetschedparam.c
index 6751c64..55e4048 100644
--- a/cpukit/posix/src/pthreadgetschedparam.c
+++ b/cpukit/posix/src/pthreadgetschedparam.c
@@ -27,6 +27,7 @@
#include <rtems/posix/pthreadimpl.h>
#include <rtems/posix/priorityimpl.h>
#include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulerimpl.h>
int pthread_getschedparam(
pthread_t thread,
@@ -34,9 +35,10 @@ int pthread_getschedparam(
struct sched_param *param
)
{
- Thread_Control *the_thread;
- ISR_lock_Context lock_context;
- POSIX_API_Control *api;
+ Thread_Control *the_thread;
+ ISR_lock_Context lock_context;
+ POSIX_API_Control *api;
+ const Scheduler_Control *scheduler;
if ( policy == NULL || param == NULL ) {
return EINVAL;
@@ -54,7 +56,10 @@ int pthread_getschedparam(
*policy = api->Attributes.schedpolicy;
*param = api->Attributes.schedparam;
+
+ scheduler = _Scheduler_Get_own( the_thread );
param->sched_priority = _POSIX_Priority_From_core(
+ scheduler,
the_thread->real_priority
);
diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c
index 15d016f..148391d 100644
--- a/cpukit/posix/src/pthreadsetschedparam.c
+++ b/cpukit/posix/src/pthreadsetschedparam.c
@@ -28,6 +28,7 @@
#include <rtems/posix/pthreadimpl.h>
#include <rtems/posix/priorityimpl.h>
#include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulerimpl.h>
typedef struct {
int policy;
@@ -45,6 +46,7 @@ static bool _POSIX_Set_sched_param_filter(
{
POSIX_Set_sched_param_context *context;
const struct sched_param *param;
+ const Scheduler_Control *scheduler;
POSIX_API_Control *api;
int low_prio;
int high_prio;
@@ -54,6 +56,7 @@ static bool _POSIX_Set_sched_param_filter(
context = arg;
param = context->param;
+ scheduler = _Scheduler_Get_own( the_thread );
if ( context->policy == SCHED_SPORADIC ) {
low_prio = param->sched_ss_low_priority;
@@ -63,18 +66,18 @@ static bool _POSIX_Set_sched_param_filter(
high_prio = low_prio;
}
- if ( !_POSIX_Priority_Is_valid( low_prio ) ) {
+ if ( !_POSIX_Priority_Is_valid( scheduler, low_prio ) ) {
context->error = EINVAL;
return false;
}
- if ( !_POSIX_Priority_Is_valid( high_prio ) ) {
+ if ( !_POSIX_Priority_Is_valid( scheduler, high_prio ) ) {
context->error = EINVAL;
return false;
}
- core_low_prio = _POSIX_Priority_To_core( low_prio );
- core_high_prio = _POSIX_Priority_To_core( high_prio );
+ core_low_prio = _POSIX_Priority_To_core( scheduler, low_prio );
+ core_high_prio = _POSIX_Priority_To_core( scheduler, high_prio );
*new_priority_p = core_high_prio;
diff --git a/cpukit/posix/src/pthreadsetschedprio.c b/cpukit/posix/src/pthreadsetschedprio.c
index 25dc59f..dace70a 100644
--- a/cpukit/posix/src/pthreadsetschedprio.c
+++ b/cpukit/posix/src/pthreadsetschedprio.c
@@ -16,6 +16,7 @@
#include <rtems/posix/priorityimpl.h>
#include <rtems/posix/threadsup.h>
#include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulerimpl.h>
typedef struct {
int prio;
@@ -30,19 +31,21 @@ static bool _POSIX_Set_sched_prio_filter(
{
POSIX_Set_sched_prio_context *context;
int prio;
+ const Scheduler_Control *scheduler;
POSIX_API_Control *api;
Priority_Control current_priority;
Priority_Control new_priority;
context = arg;
prio = context->prio;
+ scheduler = _Scheduler_Get_own( the_thread );
- if ( !_POSIX_Priority_Is_valid( prio ) ) {
+ if ( !_POSIX_Priority_Is_valid( scheduler, prio ) ) {
context->error = EINVAL;
return false;
}
- new_priority = _POSIX_Priority_To_core( prio );
+ new_priority = _POSIX_Priority_To_core( scheduler, prio );
*new_priority_p = new_priority;
current_priority = the_thread->current_priority;
--
1.8.4.5
More information about the devel
mailing list