posix: Make POSIX API aware of scheduler instances

This commit is contained in:
Sebastian Huber
2016-06-22 14:00:28 +02:00
parent eec08efc90
commit 5a32c486f9
10 changed files with 89 additions and 91 deletions
+26 -55
View File
@@ -30,29 +30,10 @@ extern "C" {
*
* @ingroup POSIXAPI
*
* @brief Interface to the POSIX Priority Implementation
*
* @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.
*
* 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
* According to POSIX, numerically higher values represent higher priorities.
* Thus, SuperCore has priorities run in the opposite sense of the POSIX API.
*
* "Numerically higher values represent higher priorities."
* 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.
*
* Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API.
* @param[in] scheduler The scheduler instance.
* @param[in] priority The POSIX API priority to test.
*
* @param[in] priority is the priority to test
*
* @retval TRUE The priority is valid.
* @retval FALSE The priority is invalid.
* @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.
* @brief Converts the SuperCore priority to the corresponding POSIX API
* priority.
*
* This method converts a POSIX API priority into onto the corresponding
* SuperCore value.
* @param[in] scheduler The scheduler instance.
* @param[in] priority The SuperCore priority to convert.
*
* @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.
*
* @param[in] priority is the POSIX API priority.
*
* @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 );
}
/** @} */
+1
View File
@@ -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
);
+3 -2
View File
@@ -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();
+22 -13
View File
@@ -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;
}
+4 -4
View File
@@ -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;
}
+3 -1
View File
@@ -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
);
+7 -4
View File
@@ -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__
+11 -6
View File
@@ -26,6 +26,7 @@
#include <rtems/posix/pthreadimpl.h>
#include <rtems/posix/priorityimpl.h>
#include <rtems/score/schedulerimpl.h>
#include <rtems/score/threadimpl.h>
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;
}
+7 -4
View File
@@ -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;
+5 -2
View File
@@ -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;