From 2612a0bf5b9f0105315d62cbacfa9d29a5caa4b5 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 2 Nov 2016 06:36:13 +0100 Subject: 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. --- cpukit/rtems/include/rtems/rtems/tasks.h | 2 - cpukit/rtems/src/schedulergetprocessorset.c | 3 +- cpukit/rtems/src/schedulerident.c | 8 +- cpukit/rtems/src/semsetpriority.c | 3 +- cpukit/rtems/src/taskgetpriority.c | 3 +- cpukit/rtems/src/tasksetscheduler.c | 3 +- cpukit/score/include/rtems/score/schedulerimpl.h | 110 ++++++++++++++--------- testsuites/smptests/smpscheduler02/init.c | 11 ++- 8 files changed, 83 insertions(+), 60 deletions(-) diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h index 180e50eed7..3a94e348ed 100644 --- a/cpukit/rtems/include/rtems/rtems/tasks.h +++ b/cpukit/rtems/include/rtems/rtems/tasks.h @@ -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, diff --git a/cpukit/rtems/src/schedulergetprocessorset.c b/cpukit/rtems/src/schedulergetprocessorset.c index 016c3681cf..275c563090 100644 --- a/cpukit/rtems/src/schedulergetprocessorset.c +++ b/cpukit/rtems/src/schedulergetprocessorset.c @@ -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; } diff --git a/cpukit/rtems/src/schedulerident.c b/cpukit/rtems/src/schedulerident.c index ee18af009e..5bde8de8bc 100644 --- a/cpukit/rtems/src/schedulerident.c +++ b/cpukit/rtems/src/schedulerident.c @@ -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 { diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c index 37dea5da80..123f6277af 100644 --- a/cpukit/rtems/src/semsetpriority.c +++ b/cpukit/rtems/src/semsetpriority.c @@ -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; } diff --git a/cpukit/rtems/src/taskgetpriority.c b/cpukit/rtems/src/taskgetpriority.c index b6800e2133..8fb8ad3b4f 100644 --- a/cpukit/rtems/src/taskgetpriority.c +++ b/cpukit/rtems/src/taskgetpriority.c @@ -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; } diff --git a/cpukit/rtems/src/tasksetscheduler.c b/cpukit/rtems/src/tasksetscheduler.c index 3a860a197b..f3b7143d7b 100644 --- a/cpukit/rtems/src/tasksetscheduler.c +++ b/cpukit/rtems/src/tasksetscheduler.c @@ -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; } diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 0abc1a074c..8d804bb0e4 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -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; - - old_scheduler = _Thread_Scheduler_get_home( the_thread ); - - if ( old_scheduler != new_scheduler ) { - States_Control current_state; - - current_state = the_thread->current_state; + if ( old_scheduler != new_scheduler ) { + States_Control current_state; - if ( _States_Is_ready( current_state ) ) { - _Scheduler_Block( the_thread ); - } + current_state = the_thread->current_state; - _Assert( old_scheduler_node->sticky_level == 0 ); - _Assert( new_scheduler_node->sticky_level == 0 ); + if ( _States_Is_ready( current_state ) ) { + _Scheduler_Block( the_thread ); + } - _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 - ); + _Assert( old_scheduler_node->sticky_level == 0 ); + _Assert( new_scheduler_node->sticky_level == 0 ); - the_thread->Scheduler.home = new_scheduler; - _Scheduler_Node_set_priority( new_scheduler_node, priority, false ); + _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 + ); - if ( _States_Is_ready( current_state ) ) { - _Scheduler_Unblock( the_thread ); - } + _Scheduler_Node_set_priority( new_scheduler_node, priority, false ); - return STATUS_SUCCESSFUL; + if ( _States_Is_ready( current_state ) ) { + _Scheduler_Unblock( the_thread ); } + + return STATUS_SUCCESSFUL; } #endif diff --git a/testsuites/smptests/smpscheduler02/init.c b/testsuites/smptests/smpscheduler02/init.c index 7708576ae9..1492d4c881 100644 --- a/testsuites/smptests/smpscheduler02/init.c +++ b/testsuites/smptests/smpscheduler02/init.c @@ -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); -- cgit v1.2.3