diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-11-02 06:36:13 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-11-09 15:27:29 +0100 |
commit | 2612a0bf5b9f0105315d62cbacfa9d29a5caa4b5 (patch) | |
tree | f27e6300271c5a5d47f6ef41a6d5c4780b715fc7 /cpukit | |
parent | score: Fix _MRSP_Initialize() (diff) | |
download | rtems-2612a0bf5b9f0105315d62cbacfa9d29a5caa4b5.tar.bz2 |
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.
Diffstat (limited to 'cpukit')
-rw-r--r-- | cpukit/rtems/include/rtems/rtems/tasks.h | 2 | ||||
-rw-r--r-- | cpukit/rtems/src/schedulergetprocessorset.c | 3 | ||||
-rw-r--r-- | cpukit/rtems/src/schedulerident.c | 8 | ||||
-rw-r--r-- | cpukit/rtems/src/semsetpriority.c | 3 | ||||
-rw-r--r-- | cpukit/rtems/src/taskgetpriority.c | 3 | ||||
-rw-r--r-- | cpukit/rtems/src/tasksetscheduler.c | 3 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerimpl.h | 110 |
7 files changed, 76 insertions, 56 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 |