mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-22 17:20:48 +08:00
posix: Make POSIX API aware of scheduler instances
This commit is contained in:
@@ -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 );
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user