forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
38
cpukit/score/src/schedulersmp.c
Normal file
38
cpukit/score/src/schedulersmp.c
Normal file
@@ -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 <rtems/score/schedulersmpimpl.h>
|
||||
|
||||
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 );
|
||||
}
|
||||
Reference in New Issue
Block a user