From 6a82f1ae8c1cd3d24b4ad6dc78431ffffb214151 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 10 Oct 2016 11:46:07 +0200 Subject: score: Yield support for new SMP helping protocol Update #2556. --- cpukit/score/include/rtems/score/schedulerimpl.h | 58 +++++++++++++++++++----- 1 file changed, 47 insertions(+), 11 deletions(-) (limited to 'cpukit/score/include/rtems/score/schedulerimpl.h') diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index dbb17a8392..ea32e00a65 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -288,29 +288,65 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Ask_for_help_if_necessary( */ 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; -#if defined(RTEMS_SMP) Thread_Control *needs_help; -#endif - scheduler = _Scheduler_Get( the_thread ); + 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_Ask_for_help_if_necessary( needs_help ); + _Scheduler_Release_critical( scheduler, &lock_context ); -#if defined(RTEMS_SMP) - needs_help = -#endif + if ( needs_help != the_thread ) { + 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 = _Scheduler_Get( the_thread ); ( *scheduler->Operations.yield )( scheduler, the_thread, _Thread_Scheduler_get_home_node( the_thread ) ); - -#if defined(RTEMS_SMP) - _Scheduler_Ask_for_help_if_necessary( needs_help ); #endif - - _Scheduler_Release_critical( scheduler, &lock_context ); } /** -- cgit v1.2.3