diff options
Diffstat (limited to 'cpukit/score/include/rtems/score/schedulerimpl.h')
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerimpl.h | 139 |
1 files changed, 41 insertions, 98 deletions
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 90a9bcca68..53631ab4e5 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -113,6 +113,43 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Release_critical( #endif } +#if defined(RTEMS_SMP) +/** + * @brief Registers an ask for help request. + * + * The actual ask for help operation is carried out during + * _Thread_Do_dispatch() on a processor related to the thread. This yields a + * better separation of scheduler instances. A thread of one scheduler + * instance should not be forced to carry out too much work for threads on + * other scheduler instances. + * + * @param[in] the_thread The thread in need for help. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Ask_for_help( Thread_Control *the_thread ) +{ + _Assert( _Thread_State_is_owner( the_thread ) ); + + if ( the_thread->Scheduler.helping_nodes > 0 ) { + ISR_lock_Context lock_context; + Per_CPU_Control *cpu; + + _Thread_Scheduler_acquire_critical( the_thread, &lock_context ); + cpu = _Thread_Get_CPU( the_thread ); + _Per_CPU_Acquire( cpu ); + + _Chain_Append_unprotected( + &cpu->Threads_in_need_for_help, + &the_thread->Scheduler.Help_node + ); + + _Per_CPU_Release( cpu ); + _Thread_Scheduler_release_critical( the_thread, &lock_context ); + + _Thread_Dispatch_request( _Per_CPU_Get(), cpu ); + } +} +#endif + /** * The preferred method to add a new scheduler is to define the jump table * entries and add a case to the _Scheduler_Initialize routine. @@ -159,64 +196,17 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *the_thread ) */ RTEMS_INLINE_ROUTINE void _Scheduler_Yield( Thread_Control *the_thread ) { -#if defined(RTEMS_SMP) - Chain_Node *node; - const Chain_Node *tail; - Scheduler_Node *scheduler_node; const Scheduler_Control *scheduler; ISR_lock_Context lock_context; - bool needs_help; - - node = _Chain_First( &the_thread->Scheduler.Scheduler_nodes ); - tail = _Chain_Immutable_tail( &the_thread->Scheduler.Scheduler_nodes ); - - scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node ); - scheduler = _Scheduler_Node_get_scheduler( scheduler_node ); - - _Scheduler_Acquire_critical( scheduler, &lock_context ); - needs_help = ( *scheduler->Operations.yield )( - scheduler, - the_thread, - _Thread_Scheduler_get_home_node( the_thread ) - ); - _Scheduler_Release_critical( scheduler, &lock_context ); - - if ( !needs_help ) { - return; - } - - node = _Chain_Next( node ); - - while ( node != tail ) { - bool success; - - scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node ); - scheduler = _Scheduler_Node_get_scheduler( scheduler_node ); - - _Scheduler_Acquire_critical( scheduler, &lock_context ); - success = ( *scheduler->Operations.ask_for_help )( - scheduler, - the_thread, - scheduler_node - ); - _Scheduler_Release_critical( scheduler, &lock_context ); - - if ( success ) { - break; - } - - node = _Chain_Next( node ); - } -#else - const Scheduler_Control *scheduler; scheduler = _Thread_Scheduler_get_home( the_thread ); + _Scheduler_Acquire_critical( scheduler, &lock_context ); ( *scheduler->Operations.yield )( scheduler, the_thread, _Thread_Scheduler_get_home_node( the_thread ) ); -#endif + _Scheduler_Release_critical( scheduler, &lock_context ); } /** @@ -293,64 +283,17 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Block( Thread_Control *the_thread ) */ RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread ) { -#if defined(RTEMS_SMP) - Chain_Node *node; - const Chain_Node *tail; - Scheduler_Node *scheduler_node; const Scheduler_Control *scheduler; ISR_lock_Context lock_context; - bool needs_help; - - node = _Chain_First( &the_thread->Scheduler.Scheduler_nodes ); - tail = _Chain_Immutable_tail( &the_thread->Scheduler.Scheduler_nodes ); - - scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node ); - scheduler = _Scheduler_Node_get_scheduler( scheduler_node ); - - _Scheduler_Acquire_critical( scheduler, &lock_context ); - needs_help = ( *scheduler->Operations.unblock )( - scheduler, - the_thread, - scheduler_node - ); - _Scheduler_Release_critical( scheduler, &lock_context ); - - if ( !needs_help ) { - return; - } - - node = _Chain_Next( node ); - - while ( node != tail ) { - bool success; - - scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node ); - scheduler = _Scheduler_Node_get_scheduler( scheduler_node ); - - _Scheduler_Acquire_critical( scheduler, &lock_context ); - success = ( *scheduler->Operations.ask_for_help )( - scheduler, - the_thread, - scheduler_node - ); - _Scheduler_Release_critical( scheduler, &lock_context ); - - if ( success ) { - break; - } - - node = _Chain_Next( node ); - } -#else - const Scheduler_Control *scheduler; scheduler = _Thread_Scheduler_get_home( the_thread ); + _Scheduler_Acquire_critical( scheduler, &lock_context ); ( *scheduler->Operations.unblock )( scheduler, the_thread, _Thread_Scheduler_get_home_node( the_thread ) ); -#endif + _Scheduler_Release_critical( scheduler, &lock_context ); } /** |