From 088acbb01fc5060f687e4776f8fc6862060d3aa8 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 7 Mar 2017 13:07:02 +0100 Subject: score: Fix scheduler yield in SMP configurations Check that no ask help request is registered during unblock and yield scheduler operations. There is no need to ask for help if a scheduled thread yields, since this is already covered by the pre-emption detection. Update #2556. --- cpukit/score/Makefile.am | 1 + cpukit/score/include/rtems/score/schedulerimpl.h | 23 +++---------- .../score/include/rtems/score/schedulersmpimpl.h | 4 +-- cpukit/score/src/schedulersmp.c | 38 ++++++++++++++++++++++ 4 files changed, 46 insertions(+), 20 deletions(-) create mode 100644 cpukit/score/src/schedulersmp.c diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 953f1eb195..0288c5393a 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -161,6 +161,7 @@ libscore_a_SOURCES += src/cpusetprintsupport.c libscore_a_SOURCES += src/schedulerdefaultaskforhelp.c libscore_a_SOURCES += src/schedulerdefaultgetaffinity.c libscore_a_SOURCES += src/schedulerdefaultsetaffinity.c +libscore_a_SOURCES += src/schedulersmp.c libscore_a_SOURCES += src/schedulersmpstartidle.c endif diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 53631ab4e5..c7c8bf05a0 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -10,7 +10,7 @@ /* * Copyright (C) 2010 Gedare Bloom. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). - * Copyright (c) 2014, 2016 embedded brains GmbH + * Copyright (c) 2014, 2017 embedded brains GmbH * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -114,8 +114,10 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Release_critical( } #if defined(RTEMS_SMP) +void _Scheduler_Request_ask_for_help( Thread_Control *the_thread ); + /** - * @brief Registers an ask for help request. + * @brief Registers an ask for help request if necessary. * * The actual ask for help operation is carried out during * _Thread_Do_dispatch() on a processor related to the thread. This yields a @@ -130,22 +132,7 @@ 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 ); + _Scheduler_Request_ask_for_help( the_thread ); } } #endif diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h index 7a281277fa..d91a62c3ca 100644 --- a/cpukit/score/include/rtems/score/schedulersmpimpl.h +++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h @@ -1085,8 +1085,8 @@ static inline void _Scheduler_SMP_Yield( if ( node_state == SCHEDULER_SMP_NODE_SCHEDULED ) { _Scheduler_SMP_Extract_from_scheduled( node ); - - needs_help = ( *enqueue_scheduled_fifo )( context, node ); + ( *enqueue_scheduled_fifo )( context, node ); + needs_help = false; } else if ( node_state == SCHEDULER_SMP_NODE_READY ) { ( *extract_from_ready )( context, node ); diff --git a/cpukit/score/src/schedulersmp.c b/cpukit/score/src/schedulersmp.c new file mode 100644 index 0000000000..d68ac4fc8b --- /dev/null +++ b/cpukit/score/src/schedulersmp.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, 2017 embedded brains GmbH. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +void _Scheduler_Request_ask_for_help( Thread_Control *the_thread ) +{ + ISR_lock_Context lock_context; + + _Thread_Scheduler_acquire_critical( the_thread, &lock_context ); + + if ( _Chain_Is_node_off_chain( &the_thread->Scheduler.Help_node ) ) { + Per_CPU_Control *cpu; + + 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_Dispatch_request( _Per_CPU_Get(), cpu ); + } + + _Thread_Scheduler_release_critical( the_thread, &lock_context ); +} -- cgit v1.2.3