mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-22 04:54:43 +08:00
score: Simplify _Scheduler_Get_by_id()
Avoid dead code in non-SMP configurations. Return scheduler identifier independent of the current processor count of the scheduler via rtems_scheduler_ident(), since this value may change during run-time. Check the processor count in _Scheduler_Set() under scheduler lock protection. Update #2797.
This commit is contained in:
@@ -555,8 +555,6 @@ void rtems_task_iterate(
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_INVALID_ADDRESS The @a id parameter is @c NULL.
|
||||
* @retval RTEMS_INVALID_NAME Invalid scheduler name.
|
||||
* @retval RTEMS_UNSATISFIED A scheduler with this name exists, but the
|
||||
* processor set of this scheduler is empty.
|
||||
*/
|
||||
rtems_status_code rtems_scheduler_ident(
|
||||
rtems_name name,
|
||||
|
||||
@@ -34,7 +34,8 @@ rtems_status_code rtems_scheduler_get_processor_set(
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
|
||||
scheduler = _Scheduler_Get_by_id( scheduler_id );
|
||||
if ( scheduler == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,12 +36,8 @@ rtems_status_code rtems_scheduler_ident(
|
||||
const Scheduler_Control *scheduler = &_Scheduler_Table[ i ];
|
||||
|
||||
if ( scheduler->name == name ) {
|
||||
if ( _Scheduler_Get_processor_count( scheduler ) > 0 ) {
|
||||
*id = _Scheduler_Build_id( i );
|
||||
sc = RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
sc = RTEMS_UNSATISFIED;
|
||||
}
|
||||
*id = _Scheduler_Build_id( i );
|
||||
sc = RTEMS_SUCCESSFUL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -138,7 +138,8 @@ rtems_status_code rtems_semaphore_set_priority(
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
|
||||
scheduler = _Scheduler_Get_by_id( scheduler_id );
|
||||
if ( scheduler == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,8 @@ rtems_status_code rtems_task_get_priority(
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
|
||||
scheduler = _Scheduler_Get_by_id( scheduler_id );
|
||||
if ( scheduler == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ rtems_status_code rtems_task_set_scheduler(
|
||||
Priority_Control core_priority;
|
||||
Status_Control status;
|
||||
|
||||
if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
|
||||
scheduler = _Scheduler_Get_by_id( scheduler_id );
|
||||
if ( scheduler == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
|
||||
@@ -828,18 +828,19 @@ RTEMS_INLINE_ROUTINE uint32_t _Scheduler_Get_index_by_id( Objects_Id id )
|
||||
return id - minimum_id;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _Scheduler_Get_by_id(
|
||||
Objects_Id id,
|
||||
const Scheduler_Control **scheduler_p
|
||||
RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get_by_id(
|
||||
Objects_Id id
|
||||
)
|
||||
{
|
||||
uint32_t index = _Scheduler_Get_index_by_id( id );
|
||||
const Scheduler_Control *scheduler = &_Scheduler_Table[ index ];
|
||||
uint32_t index;
|
||||
|
||||
*scheduler_p = scheduler;
|
||||
index = _Scheduler_Get_index_by_id( id );
|
||||
|
||||
return index < _Scheduler_Count
|
||||
&& _Scheduler_Get_processor_count( scheduler ) > 0;
|
||||
if ( index >= _Scheduler_Count ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &_Scheduler_Table[ index ];
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE uint32_t _Scheduler_Get_index(
|
||||
@@ -1205,8 +1206,13 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
|
||||
Priority_Control priority
|
||||
)
|
||||
{
|
||||
Scheduler_Node *new_scheduler_node;
|
||||
Scheduler_Node *old_scheduler_node;
|
||||
Scheduler_Node *new_scheduler_node;
|
||||
Scheduler_Node *old_scheduler_node;
|
||||
#if defined(RTEMS_SMP)
|
||||
ISR_lock_Context lock_context;
|
||||
const Scheduler_Control *old_scheduler;
|
||||
|
||||
#endif
|
||||
|
||||
if ( the_thread->Wait.queue != NULL ) {
|
||||
return STATUS_RESOURCE_IN_USE;
|
||||
@@ -1229,9 +1235,32 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
if ( !_Chain_Has_only_one_node( &the_thread->Scheduler.Wait_nodes ) ) {
|
||||
_Priority_Plain_insert(
|
||||
&old_scheduler_node->Wait.Priority,
|
||||
&the_thread->Real_priority,
|
||||
the_thread->Real_priority.priority
|
||||
);
|
||||
return STATUS_RESOURCE_IN_USE;
|
||||
}
|
||||
|
||||
old_scheduler = _Thread_Scheduler_get_home( the_thread );
|
||||
|
||||
_Scheduler_Acquire_critical( new_scheduler, &lock_context );
|
||||
|
||||
if ( _Scheduler_Get_processor_count( new_scheduler ) == 0 ) {
|
||||
_Scheduler_Release_critical( new_scheduler, &lock_context );
|
||||
_Priority_Plain_insert(
|
||||
&old_scheduler_node->Wait.Priority,
|
||||
&the_thread->Real_priority,
|
||||
the_thread->Real_priority.priority
|
||||
);
|
||||
return STATUS_UNSATISFIED;
|
||||
}
|
||||
|
||||
the_thread->Scheduler.home = new_scheduler;
|
||||
|
||||
_Scheduler_Release_critical( new_scheduler, &lock_context );
|
||||
|
||||
_Thread_Scheduler_process_requests( the_thread );
|
||||
new_scheduler_node = _Thread_Scheduler_get_node_by_index(
|
||||
the_thread,
|
||||
@@ -1249,47 +1278,40 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
|
||||
);
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
{
|
||||
const Scheduler_Control *old_scheduler;
|
||||
if ( old_scheduler != new_scheduler ) {
|
||||
States_Control current_state;
|
||||
|
||||
old_scheduler = _Thread_Scheduler_get_home( the_thread );
|
||||
current_state = the_thread->current_state;
|
||||
|
||||
if ( old_scheduler != new_scheduler ) {
|
||||
States_Control current_state;
|
||||
|
||||
current_state = the_thread->current_state;
|
||||
|
||||
if ( _States_Is_ready( current_state ) ) {
|
||||
_Scheduler_Block( the_thread );
|
||||
}
|
||||
|
||||
_Assert( old_scheduler_node->sticky_level == 0 );
|
||||
_Assert( new_scheduler_node->sticky_level == 0 );
|
||||
|
||||
_Chain_Extract_unprotected( &old_scheduler_node->Thread.Wait_node );
|
||||
_Assert( _Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
|
||||
_Chain_Initialize_one(
|
||||
&the_thread->Scheduler.Wait_nodes,
|
||||
&new_scheduler_node->Thread.Wait_node
|
||||
);
|
||||
_Chain_Extract_unprotected(
|
||||
&old_scheduler_node->Thread.Scheduler_node.Chain
|
||||
);
|
||||
_Assert( _Chain_Is_empty( &the_thread->Scheduler.Scheduler_nodes ) );
|
||||
_Chain_Initialize_one(
|
||||
&the_thread->Scheduler.Scheduler_nodes,
|
||||
&new_scheduler_node->Thread.Scheduler_node.Chain
|
||||
);
|
||||
|
||||
the_thread->Scheduler.home = new_scheduler;
|
||||
_Scheduler_Node_set_priority( new_scheduler_node, priority, false );
|
||||
|
||||
if ( _States_Is_ready( current_state ) ) {
|
||||
_Scheduler_Unblock( the_thread );
|
||||
}
|
||||
|
||||
return STATUS_SUCCESSFUL;
|
||||
if ( _States_Is_ready( current_state ) ) {
|
||||
_Scheduler_Block( the_thread );
|
||||
}
|
||||
|
||||
_Assert( old_scheduler_node->sticky_level == 0 );
|
||||
_Assert( new_scheduler_node->sticky_level == 0 );
|
||||
|
||||
_Chain_Extract_unprotected( &old_scheduler_node->Thread.Wait_node );
|
||||
_Assert( _Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
|
||||
_Chain_Initialize_one(
|
||||
&the_thread->Scheduler.Wait_nodes,
|
||||
&new_scheduler_node->Thread.Wait_node
|
||||
);
|
||||
_Chain_Extract_unprotected(
|
||||
&old_scheduler_node->Thread.Scheduler_node.Chain
|
||||
);
|
||||
_Assert( _Chain_Is_empty( &the_thread->Scheduler.Scheduler_nodes ) );
|
||||
_Chain_Initialize_one(
|
||||
&the_thread->Scheduler.Scheduler_nodes,
|
||||
&new_scheduler_node->Thread.Scheduler_node.Chain
|
||||
);
|
||||
|
||||
_Scheduler_Node_set_priority( new_scheduler_node, priority, false );
|
||||
|
||||
if ( _States_Is_ready( current_state ) ) {
|
||||
_Scheduler_Unblock( the_thread );
|
||||
}
|
||||
|
||||
return STATUS_SUCCESSFUL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ static void test(void)
|
||||
}
|
||||
|
||||
sc = rtems_scheduler_ident(SCHED_C, &scheduler_c_id);
|
||||
rtems_test_assert(sc == RTEMS_UNSATISFIED);
|
||||
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||
|
||||
sc = rtems_semaphore_create(
|
||||
rtems_build_name('C', 'M', 'T', 'X'),
|
||||
@@ -182,13 +182,16 @@ static void test(void)
|
||||
rtems_test_assert(sched_get_priority_min(SCHED_RR) == 1);
|
||||
rtems_test_assert(sched_get_priority_max(SCHED_RR) == 254);
|
||||
|
||||
sc = rtems_task_set_scheduler(task_id, scheduler_c_id, 1);
|
||||
rtems_test_assert(sc == RTEMS_UNSATISFIED);
|
||||
|
||||
sc = rtems_task_set_scheduler(task_id, scheduler_c_id + 1, 1);
|
||||
rtems_test_assert(sc == RTEMS_INVALID_ID);
|
||||
|
||||
if (cpu_count > 1) {
|
||||
sc = rtems_task_set_scheduler(task_id, scheduler_b_id, 1);
|
||||
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||
|
||||
sc = rtems_task_set_scheduler(task_id, scheduler_b_id + 1, 1);
|
||||
rtems_test_assert(sc == RTEMS_INVALID_ID);
|
||||
|
||||
sc = rtems_task_get_scheduler(task_id, &scheduler_id);
|
||||
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||
rtems_test_assert(scheduler_id == scheduler_b_id);
|
||||
|
||||
Reference in New Issue
Block a user