summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/schedulerimpl.h
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-10-10 11:46:07 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-11-02 10:05:43 +0100
commit6a82f1ae8c1cd3d24b4ad6dc78431ffffb214151 (patch)
treeb993ecd480c257431c658c86d126cf1111d7abf6 /cpukit/score/include/rtems/score/schedulerimpl.h
parentscore: Add new SMP scheduler helping protocol (diff)
downloadrtems-6a82f1ae8c1cd3d24b4ad6dc78431ffffb214151.tar.bz2
score: Yield support for new SMP helping protocol
Update #2556.
Diffstat (limited to 'cpukit/score/include/rtems/score/schedulerimpl.h')
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h58
1 files changed, 47 insertions, 11 deletions
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 );
}
/**