From 5a32c486f9b7bd8687af253931b47d7abb091bc3 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 14 Jun 2016 15:57:54 +0200 Subject: posix: Make POSIX API aware of scheduler instances --- cpukit/posix/include/rtems/posix/priorityimpl.h | 85 ++++++++----------------- 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 | 17 +++-- cpukit/posix/src/pthreadsetschedparam.c | 11 ++-- cpukit/posix/src/pthreadsetschedprio.c | 7 +- 10 files changed, 91 insertions(+), 93 deletions(-) diff --git a/cpukit/posix/include/rtems/posix/priorityimpl.h b/cpukit/posix/include/rtems/posix/priorityimpl.h index e3f23e748d..d06b600f04 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. + * @brief Interface to the POSIX Priority Implementation. * - * 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. - * - * 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,43 @@ 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. - * - * @param[in] priority is the POSIX API priority. - * - * @return This method returns the corresponding SuperCore priority. - */ -RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Priority_To_core( - int priority -) -{ - return (Priority_Control) (POSIX_SCHEDULER_MAXIMUM_PRIORITY - priority + 1); -} - -/** - * @brief Convert SuperCore priority To POSIX priority. - * - * This method converts a SuperCore priority into onto the corresponding - * POSIX API value. + * @brief Converts the SuperCore priority to the corresponding POSIX API + * priority. * - * @param[in] priority is the POSIX API priority. + * @param[in] scheduler The scheduler instance. + * @param[in] priority The SuperCore priority to convert. * - * @return This method returns the corresponding POSIX priority. + * @return 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 2df4776048..eda02cba83 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 0d4833ed90..04c36e11bb 100644 --- a/cpukit/posix/src/mutexinit.c +++ b/cpukit/posix/src/mutexinit.c @@ -20,6 +20,7 @@ #include #include +#include /** * 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 96e8dbfeba..65b93c7a56 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 c883416c86..ea7f6f4382 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 ca7efa9c7d..b29acaeea5 100644 --- a/cpukit/posix/src/pthread.c +++ b/cpukit/posix/src/pthread.c @@ -37,8 +37,9 @@ #include #include #include -#include #include +#include +#include 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 f2fc1ca68e..a4b468494a 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 6751c647d7..a0a4c6e15b 100644 --- a/cpukit/posix/src/pthreadgetschedparam.c +++ b/cpukit/posix/src/pthreadgetschedparam.c @@ -26,6 +26,7 @@ #include #include +#include #include int pthread_getschedparam( @@ -34,9 +35,11 @@ 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; + Priority_Control priority; if ( policy == NULL || param == NULL ) { return EINVAL; @@ -54,10 +57,12 @@ int pthread_getschedparam( *policy = api->Attributes.schedpolicy; *param = api->Attributes.schedparam; - param->sched_priority = _POSIX_Priority_From_core( - the_thread->real_priority - ); + + scheduler = _Scheduler_Get_own( the_thread ); + 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/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c index 15d016fce7..148391dcc4 100644 --- a/cpukit/posix/src/pthreadsetschedparam.c +++ b/cpukit/posix/src/pthreadsetschedparam.c @@ -28,6 +28,7 @@ #include #include #include +#include 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 25dc59fb11..dace70ad1f 100644 --- a/cpukit/posix/src/pthreadsetschedprio.c +++ b/cpukit/posix/src/pthreadsetschedprio.c @@ -16,6 +16,7 @@ #include #include #include +#include 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; -- cgit v1.2.3