summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-21 17:12:40 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-22 14:00:28 +0200
commitc82835a231351377866ceb82826010ba0485255d (patch)
treea6a891207d89e37f01bc54cf276e4c6cac9c6236 /cpukit
parentposix: Generalize _POSIX_Priority_To_core() (diff)
downloadrtems-c82835a231351377866ceb82826010ba0485255d.tar.bz2
rtems: Rework RTEMS API to SuperCore priority
Use same structure as POSIX API for thread priority conversion to/from SuperCore.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/libmisc/capture/capture.c8
-rw-r--r--cpukit/libmisc/capture/capture.h4
-rw-r--r--cpukit/rtems/include/rtems/rtems/tasksimpl.h49
-rw-r--r--cpukit/rtems/src/semcreate.c82
-rw-r--r--cpukit/rtems/src/semsetpriority.c41
-rw-r--r--cpukit/rtems/src/taskcreate.c18
-rw-r--r--cpukit/rtems/src/tasksetpriority.c101
-rw-r--r--cpukit/rtems/src/timerserver.c9
-rw-r--r--cpukit/score/include/rtems/score/status.h2
9 files changed, 199 insertions, 115 deletions
diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
index dfde5ddbb7..6879a37a81 100644
--- a/cpukit/libmisc/capture/capture.c
+++ b/cpukit/libmisc/capture/capture.c
@@ -365,16 +365,14 @@ void rtems_capture_initialize_task( rtems_tcb* tcb )
void rtems_capture_record_task( rtems_tcb* tcb )
{
- rtems_capture_task_record_t rec;
- void* ptr;
+ rtems_capture_task_record_t rec;
+ void* ptr;
rtems_interrupt_lock_context lock_context;
rtems_object_get_classic_name( tcb->Object.id, &rec.name );
rec.stack_size = tcb->Start.Initial_stack.size;
- rec.start_priority = _RTEMS_tasks_Priority_from_Core(
- tcb->Start.initial_priority
- );
+ rec.start_priority = rtems_capture_task_start_priority (tcb);
rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);
tcb->Capture.flags |= RTEMS_CAPTURE_RECORD_TASK;
diff --git a/cpukit/libmisc/capture/capture.h b/cpukit/libmisc/capture/capture.h
index ab461a92e5..d439968005 100644
--- a/cpukit/libmisc/capture/capture.h
+++ b/cpukit/libmisc/capture/capture.h
@@ -47,6 +47,7 @@ extern "C" {
#include <rtems.h>
#include <rtems/rtems/tasksimpl.h>
+#include <rtems/score/schedulerimpl.h>
/**
* The number of tasks in a trigger group.
@@ -737,7 +738,8 @@ rtems_capture_task_control_flags (rtems_tcb* tcb)
static inline rtems_task_priority
rtems_capture_task_start_priority (rtems_tcb* tcb)
{
- return _RTEMS_tasks_Priority_from_Core(
+ return _RTEMS_Priority_From_core(
+ _Scheduler_Get_own( tcb ),
tcb->Start.initial_priority
);
}
diff --git a/cpukit/rtems/include/rtems/rtems/tasksimpl.h b/cpukit/rtems/include/rtems/rtems/tasksimpl.h
index 82e8618b8c..c7f8952bcf 100644
--- a/cpukit/rtems/include/rtems/rtems/tasksimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/tasksimpl.h
@@ -19,6 +19,7 @@
#include <rtems/rtems/tasks.h>
#include <rtems/score/objectimpl.h>
+#include <rtems/score/scheduler.h>
#include <rtems/score/threadimpl.h>
#ifdef __cplusplus
@@ -74,41 +75,45 @@ RTEMS_INLINE_ROUTINE void _RTEMS_tasks_Free (
}
/**
- * @brief Converts an RTEMS API priority into a core priority.
+ * @brief Converts the RTEMS API priority to the corresponding SuperCore
+ * priority and validates it.
*
- * This function converts an RTEMS API priority into a core priority.
+ * The RTEMS API system priority is accepted as valid.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The RTEMS API priority to convert and validate.
+ * @param[out] valid Indicates if the RTEMS API priority is valid and a
+ * corresponding SuperCore priority in the specified scheduler instance
+ * exists.
+ *
+ * @return The corresponding SuperCore priority.
*/
-RTEMS_INLINE_ROUTINE Priority_Control _RTEMS_tasks_Priority_to_Core(
- rtems_task_priority priority
+RTEMS_INLINE_ROUTINE Priority_Control _RTEMS_Priority_To_core(
+ const Scheduler_Control *scheduler,
+ rtems_task_priority priority,
+ bool *valid
)
{
+ *valid = ( priority <= scheduler->maximum_priority );
+
return (Priority_Control) priority;
}
/**
- * @brief Converts a core priority into an RTEMS API priority.
+ * @brief Converts the SuperCore priority to the corresponding RTEMS API
+ * priority.
*
- * This function converts a core priority into an RTEMS API priority.
- */
-RTEMS_INLINE_ROUTINE rtems_task_priority _RTEMS_tasks_Priority_from_Core (
- Priority_Control priority
-)
-{
- return (rtems_task_priority) priority;
-}
-
-/**
- * @brief Checks whether the priority is a valid user task.
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The SuperCore priority to convert.
*
- * This function returns TRUE if the_priority is a valid user task priority
- * and FALSE otherwise.
+ * @return The corresponding RTEMS API priority.
*/
-RTEMS_INLINE_ROUTINE bool _RTEMS_tasks_Priority_is_valid (
- rtems_task_priority the_priority
+RTEMS_INLINE_ROUTINE rtems_task_priority _RTEMS_Priority_From_core(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
)
{
- return ( ( the_priority >= RTEMS_MINIMUM_PRIORITY ) &&
- ( the_priority <= RTEMS_MAXIMUM_PRIORITY ) );
+ return (rtems_task_priority) priority;
}
/**@}*/
diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c
index bb1c6b4e61..f03475ee33 100644
--- a/cpukit/rtems/src/semcreate.c
+++ b/cpukit/rtems/src/semcreate.c
@@ -22,6 +22,7 @@
#include <rtems/rtems/attrimpl.h>
#include <rtems/rtems/statusimpl.h>
#include <rtems/rtems/tasksimpl.h>
+#include <rtems/score/schedulerimpl.h>
#include <rtems/score/sysstate.h>
#define SEMAPHORE_KIND_MASK ( RTEMS_SEMAPHORE_CLASS | RTEMS_INHERIT_PRIORITY \
@@ -35,12 +36,15 @@ rtems_status_code rtems_semaphore_create(
rtems_id *id
)
{
- Semaphore_Control *the_semaphore;
- Thread_Control *executing;
- Status_Control status;
- rtems_attribute maybe_global;
- rtems_attribute mutex_with_protocol;
- Semaphore_Variant variant;
+ Semaphore_Control *the_semaphore;
+ Thread_Control *executing;
+ Status_Control status;
+ rtems_attribute maybe_global;
+ rtems_attribute mutex_with_protocol;
+ Semaphore_Variant variant;
+ const Scheduler_Control *scheduler;
+ bool valid;
+ Priority_Control priority;
if ( !rtems_is_name_valid( name ) )
return RTEMS_INVALID_NAME;
@@ -122,7 +126,6 @@ rtems_status_code rtems_semaphore_create(
}
#endif
- priority_ceiling = _RTEMS_tasks_Priority_to_Core( priority_ceiling );
executing = _Thread_Get_executing();
the_semaphore->variant = variant;
@@ -154,42 +157,57 @@ rtems_status_code rtems_semaphore_create(
status = STATUS_SUCCESSFUL;
break;
case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
- _CORE_ceiling_mutex_Initialize(
- &the_semaphore->Core_control.Mutex,
- priority_ceiling
- );
-
- if ( count == 0 ) {
- Thread_queue_Context queue_context;
+ scheduler = _Scheduler_Get_own( executing );
+ priority = _RTEMS_Priority_To_core( scheduler, priority_ceiling, &valid );
- _Thread_queue_Context_initialize( &queue_context );
- _ISR_lock_ISR_disable( &queue_context.Lock_context );
- _CORE_mutex_Acquire_critical(
- &the_semaphore->Core_control.Mutex.Recursive.Mutex,
- &queue_context
- );
- status = _CORE_ceiling_mutex_Set_owner(
+ if ( valid ) {
+ _CORE_ceiling_mutex_Initialize(
&the_semaphore->Core_control.Mutex,
- executing,
- &queue_context
+ priority
);
- if ( status != STATUS_SUCCESSFUL ) {
- _Thread_queue_Destroy( &the_semaphore->Core_control.Wait_queue );
+ if ( count == 0 ) {
+ Thread_queue_Context queue_context;
+
+ _Thread_queue_Context_initialize( &queue_context );
+ _ISR_lock_ISR_disable( &queue_context.Lock_context );
+ _CORE_mutex_Acquire_critical(
+ &the_semaphore->Core_control.Mutex.Recursive.Mutex,
+ &queue_context
+ );
+ status = _CORE_ceiling_mutex_Set_owner(
+ &the_semaphore->Core_control.Mutex,
+ executing,
+ &queue_context
+ );
+
+ if ( status != STATUS_SUCCESSFUL ) {
+ _Thread_queue_Destroy( &the_semaphore->Core_control.Wait_queue );
+ }
+ } else {
+ status = STATUS_SUCCESSFUL;
}
} else {
- status = STATUS_SUCCESSFUL;
+ status = STATUS_INVALID_PRIORITY;
}
break;
#if defined(RTEMS_SMP)
case SEMAPHORE_VARIANT_MRSP:
- status = _MRSP_Initialize(
- &the_semaphore->Core_control.MRSP,
- priority_ceiling,
- executing,
- count == 0
- );
+ scheduler = _Scheduler_Get_own( executing );
+ priority = _RTEMS_Priority_To_core( scheduler, priority_ceiling, &valid );
+
+ if ( valid ) {
+ status = _MRSP_Initialize(
+ &the_semaphore->Core_control.MRSP,
+ priority,
+ executing,
+ count == 0
+ );
+ } else {
+ status = STATUS_INVALID_PRIORITY;
+ }
+
break;
#endif
default:
diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c
index 455cc15717..37d7a207ca 100644
--- a/cpukit/rtems/src/semsetpriority.c
+++ b/cpukit/rtems/src/semsetpriority.c
@@ -21,21 +21,26 @@
#include <rtems/score/schedulerimpl.h>
static rtems_status_code _Semaphore_Set_priority(
- Semaphore_Control *the_semaphore,
- rtems_id scheduler_id,
- rtems_task_priority new_priority,
- rtems_task_priority *old_priority_p,
- Thread_queue_Context *queue_context
+ Semaphore_Control *the_semaphore,
+ const Scheduler_Control *scheduler,
+ rtems_task_priority new_priority,
+ rtems_task_priority *old_priority_p,
+ Thread_queue_Context *queue_context
)
{
rtems_status_code sc;
- rtems_task_priority old_priority;
+ bool valid;
+ Priority_Control core_priority;
+ Priority_Control old_priority;
#if defined(RTEMS_SMP)
MRSP_Control *mrsp;
uint32_t scheduler_index;
#endif
- new_priority = _RTEMS_tasks_Priority_to_Core( new_priority );
+ core_priority = _RTEMS_Priority_To_core( scheduler, new_priority, &valid );
+ if ( new_priority != RTEMS_CURRENT_PRIORITY && !valid ) {
+ return RTEMS_INVALID_PRIORITY;
+ }
switch ( the_semaphore->variant ) {
case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
@@ -47,7 +52,7 @@ static rtems_status_code _Semaphore_Set_priority(
old_priority = the_semaphore->Core_control.Mutex.priority_ceiling;
if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
- the_semaphore->Core_control.Mutex.priority_ceiling = new_priority;
+ the_semaphore->Core_control.Mutex.priority_ceiling = core_priority;
}
_CORE_mutex_Release(
@@ -59,14 +64,14 @@ static rtems_status_code _Semaphore_Set_priority(
#if defined(RTEMS_SMP)
case SEMAPHORE_VARIANT_MRSP:
mrsp = &the_semaphore->Core_control.MRSP;
- scheduler_index = _Scheduler_Get_index_by_id( scheduler_id );
+ scheduler_index = _Scheduler_Get_index( scheduler );
_MRSP_Acquire_critical( mrsp, queue_context );
old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index );
if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
- _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority );
+ _MRSP_Set_ceiling_priority( mrsp, scheduler_index, core_priority );
}
_MRSP_Release( mrsp, queue_context );
@@ -86,7 +91,7 @@ static rtems_status_code _Semaphore_Set_priority(
break;
}
- *old_priority_p = _RTEMS_tasks_Priority_from_Core( old_priority );
+ *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
return sc;
}
@@ -98,19 +103,15 @@ rtems_status_code rtems_semaphore_set_priority(
rtems_task_priority *old_priority
)
{
- Semaphore_Control *the_semaphore;
- Thread_queue_Context queue_context;
-
- if ( new_priority != RTEMS_CURRENT_PRIORITY &&
- !_RTEMS_tasks_Priority_is_valid( new_priority ) ) {
- return RTEMS_INVALID_PRIORITY;
- }
+ const Scheduler_Control *scheduler;
+ Semaphore_Control *the_semaphore;
+ Thread_queue_Context queue_context;
if ( old_priority == NULL ) {
return RTEMS_INVALID_ADDRESS;
}
- if ( !_Scheduler_Is_id_valid( scheduler_id ) ) {
+ if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
return RTEMS_INVALID_ID;
}
@@ -128,7 +129,7 @@ rtems_status_code rtems_semaphore_set_priority(
return _Semaphore_Set_priority(
the_semaphore,
- scheduler_id,
+ scheduler,
new_priority,
old_priority,
&queue_context
diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c
index 5d9f9dda91..e231d4a0c3 100644
--- a/cpukit/rtems/src/taskcreate.c
+++ b/cpukit/rtems/src/taskcreate.c
@@ -37,6 +37,7 @@ rtems_status_code rtems_task_create(
)
{
Thread_Control *the_thread;
+ const Scheduler_Control *scheduler;
bool is_fp;
#if defined(RTEMS_MULTIPROCESSING)
Objects_MP_Control *the_global_object = NULL;
@@ -44,7 +45,8 @@ rtems_status_code rtems_task_create(
#endif
bool status;
rtems_attribute the_attribute_set;
- Priority_Control core_priority;
+ bool valid;
+ Priority_Control priority;
RTEMS_API_Control *api;
ASR_Information *asr;
@@ -83,11 +85,17 @@ rtems_status_code rtems_task_create(
*/
if ( !_Attributes_Is_system_task( the_attribute_set ) ) {
- if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) )
+ if ( initial_priority == PRIORITY_MINIMUM ) {
return RTEMS_INVALID_PRIORITY;
+ }
}
- core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority );
+ scheduler = _Scheduler_Get_by_CPU_index( _SMP_Get_current_processor() );
+
+ priority = _RTEMS_Priority_To_core( scheduler, initial_priority, &valid );
+ if ( !valid ) {
+ return RTEMS_INVALID_PRIORITY;
+ }
#if defined(RTEMS_MULTIPROCESSING)
if ( _Attributes_Is_global( the_attribute_set ) ) {
@@ -136,11 +144,11 @@ rtems_status_code rtems_task_create(
status = _Thread_Initialize(
&_RTEMS_tasks_Information,
the_thread,
- _Scheduler_Get_by_CPU_index( _SMP_Get_current_processor() ),
+ scheduler,
NULL,
stack_size,
is_fp,
- core_priority,
+ priority,
_Modes_Is_preempt(initial_modes) ? true : false,
_Modes_Is_timeslice(initial_modes) ?
THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :
diff --git a/cpukit/rtems/src/tasksetpriority.c b/cpukit/rtems/src/tasksetpriority.c
index 32a77f77ba..0a2df6e1ca 100644
--- a/cpukit/rtems/src/tasksetpriority.c
+++ b/cpukit/rtems/src/tasksetpriority.c
@@ -19,52 +19,109 @@
#endif
#include <rtems/rtems/tasksimpl.h>
+#include <rtems/score/schedulerimpl.h>
#include <rtems/score/threadimpl.h>
+typedef struct {
+ const Scheduler_Control *scheduler;
+ rtems_task_priority new_priority;
+ Priority_Control old_priority;
+ rtems_status_code status;
+} RTEMS_tasks_Set_priority_context;
+
+static bool _RTEMS_tasks_Set_priority_filter(
+ Thread_Control *the_thread,
+ Priority_Control *new_priority_p,
+ void *arg
+)
+{
+ RTEMS_tasks_Set_priority_context *context;
+ const Scheduler_Control *scheduler;
+ bool valid;
+ Priority_Control current_priority;
+ Priority_Control new_priority;
+
+ context = arg;
+ scheduler = _Scheduler_Get_own( the_thread );
+ current_priority = the_thread->current_priority;
+
+ context->scheduler = scheduler;
+ context->old_priority = current_priority;
+
+ new_priority = _RTEMS_Priority_To_core(
+ scheduler,
+ context->new_priority,
+ &valid
+ );
+
+ *new_priority_p = new_priority;
+
+ if ( !valid ) {
+ context->status = RTEMS_INVALID_PRIORITY;
+ return false;
+ }
+
+ the_thread->real_priority = new_priority;
+ context->status = STATUS_SUCCESSFUL;
+
+ return _Thread_Priority_less_than( current_priority, new_priority )
+ || !_Thread_Owns_resources( the_thread );
+}
+
rtems_status_code rtems_task_set_priority(
rtems_id id,
rtems_task_priority new_priority,
- rtems_task_priority *old_priority
+ rtems_task_priority *old_priority_p
)
{
- Thread_Control *the_thread;
- ISR_lock_Context lock_context;
- Per_CPU_Control *cpu_self;
+ Thread_Control *the_thread;
+ ISR_lock_Context lock_context;
+ const Scheduler_Control *scheduler;
+ Priority_Control old_priority;
+ rtems_status_code status;
- if ( new_priority != RTEMS_CURRENT_PRIORITY &&
- !_RTEMS_tasks_Priority_is_valid( new_priority ) )
- return RTEMS_INVALID_PRIORITY;
-
- if ( !old_priority )
+ if ( old_priority_p == NULL ) {
return RTEMS_INVALID_ADDRESS;
+ }
the_thread = _Thread_Get( id, &lock_context );
if ( the_thread == NULL ) {
#if defined(RTEMS_MULTIPROCESSING)
- return _RTEMS_tasks_MP_Set_priority( id, new_priority, old_priority );
+ return _RTEMS_tasks_MP_Set_priority( id, new_priority, old_priority_p );
#else
return RTEMS_INVALID_ID;
#endif
}
- cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
- _ISR_lock_ISR_enable( &lock_context );
-
if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
- _Thread_Set_priority(
+ RTEMS_tasks_Set_priority_context context;
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+ _ISR_lock_ISR_enable( &lock_context );
+
+ context.new_priority = new_priority;
+ _Thread_Change_priority(
the_thread,
- _RTEMS_tasks_Priority_to_Core( new_priority ),
- old_priority,
+ 0,
+ &context,
+ _RTEMS_tasks_Set_priority_filter,
false
);
- *old_priority = _RTEMS_tasks_Priority_from_Core( *old_priority );
+
+ _Thread_Dispatch_enable( cpu_self );
+ scheduler = context.scheduler;
+ old_priority = context.old_priority;
+ status = context.status;
} else {
- *old_priority = _RTEMS_tasks_Priority_from_Core(
- the_thread->current_priority
- );
+ _Thread_State_acquire_critical( the_thread, &lock_context );
+ scheduler = _Scheduler_Get_own( the_thread );
+ old_priority = the_thread->current_priority;
+ _Thread_State_release( the_thread, &lock_context );
+ status = RTEMS_SUCCESSFUL;
}
- _Thread_Dispatch_enable( cpu_self );
- return RTEMS_SUCCESSFUL;
+ *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
+ return status;
}
diff --git a/cpukit/rtems/src/timerserver.c b/cpukit/rtems/src/timerserver.c
index cf06319434..dfdba8c2e2 100644
--- a/cpukit/rtems/src/timerserver.c
+++ b/cpukit/rtems/src/timerserver.c
@@ -153,14 +153,7 @@ static rtems_status_code _Timer_server_Initiate(
return RTEMS_INCORRECT_STATE;
}
- /*
- * Make sure the requested priority is valid. The if is
- * structured so we check it is invalid before looking for
- * a specific invalid value as the default.
- */
- if ( !_RTEMS_tasks_Priority_is_valid( priority ) ) {
- if ( priority != RTEMS_TIMER_SERVER_DEFAULT_PRIORITY )
- return RTEMS_INVALID_PRIORITY;
+ if ( priority == RTEMS_TIMER_SERVER_DEFAULT_PRIORITY ) {
priority = PRIORITY_PSEUDO_ISR;
}
diff --git a/cpukit/score/include/rtems/score/status.h b/cpukit/score/include/rtems/score/status.h
index eaf69c1597..f6ebaa46f1 100644
--- a/cpukit/score/include/rtems/score/status.h
+++ b/cpukit/score/include/rtems/score/status.h
@@ -86,6 +86,8 @@ typedef enum {
STATUS_BUILD( STATUS_CLASSIC_INTERNAL_ERROR, EINTR ),
STATUS_INVALID_NUMBER =
STATUS_BUILD( STATUS_CLASSIC_INVALID_NUMBER, EINVAL ),
+ STATUS_INVALID_PRIORITY =
+ STATUS_BUILD( STATUS_CLASSIC_INVALID_PRIORITY, EINVAL ),
STATUS_MAXIMUM_COUNT_EXCEEDED =
STATUS_BUILD( STATUS_CLASSIC_INTERNAL_ERROR, EOVERFLOW ),
STATUS_MESSAGE_INVALID_SIZE =