--- 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 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel