From e5ca54c99682a264568d95d8a5db555ea8357e9c Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 7 Aug 2013 21:19:55 +0200 Subject: score: PR2136: Fix _Thread_Change_priority() Add call to _Scheduler_Schedule() in missing path after _Thread_Set_transient() in _Thread_Change_priority(). See also sptests/spintrcritical19. Add thread parameter to _Scheduler_Schedule(). This parameter is currently unused but may be used in future SMP schedulers. Do heir selection in _Scheduler_Schedule(). Use _Scheduler_Update_heir() for this in the particular scheduler implementation. Add and use _Scheduler_Generic_block(). --- cpukit/score/include/rtems/score/scheduler.h | 2 +- cpukit/score/include/rtems/score/scheduleredf.h | 2 +- .../score/include/rtems/score/scheduleredfimpl.h | 56 ++++++++++++++++++++++ cpukit/score/include/rtems/score/schedulerimpl.h | 35 +++++++++++++- .../score/include/rtems/score/schedulerpriority.h | 2 +- .../include/rtems/score/schedulerpriorityimpl.h | 12 ++++- cpukit/score/include/rtems/score/schedulersimple.h | 2 +- .../include/rtems/score/schedulersimpleimpl.h | 16 ++++++- .../score/include/rtems/score/schedulersimplesmp.h | 2 +- cpukit/score/include/rtems/score/threadimpl.h | 10 ---- 10 files changed, 119 insertions(+), 20 deletions(-) create mode 100644 cpukit/score/include/rtems/score/scheduleredfimpl.h (limited to 'cpukit/score/include') diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h index a34387d8c7..10a2a974af 100644 --- a/cpukit/score/include/rtems/score/scheduler.h +++ b/cpukit/score/include/rtems/score/scheduler.h @@ -46,7 +46,7 @@ typedef struct { void ( *initialize )(void); /** Implements the scheduling decision logic (policy). */ - void ( *schedule )(void); + void ( *schedule )( Thread_Control *thread ); /** * @brief Voluntarily yields the processor per the scheduling policy. diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h index b28bed1363..01f91e6c26 100644 --- a/cpukit/score/include/rtems/score/scheduleredf.h +++ b/cpukit/score/include/rtems/score/scheduleredf.h @@ -129,7 +129,7 @@ void _Scheduler_EDF_Block( * This kernel routine sets the heir thread to be the next ready thread * in the rbtree ready queue. */ -void _Scheduler_EDF_Schedule( void ); +void _Scheduler_EDF_Schedule( Thread_Control *thread ); /** * @brief Allocates EDF specific information of @a the_thread. diff --git a/cpukit/score/include/rtems/score/scheduleredfimpl.h b/cpukit/score/include/rtems/score/scheduleredfimpl.h new file mode 100644 index 0000000000..04201bcdfc --- /dev/null +++ b/cpukit/score/include/rtems/score/scheduleredfimpl.h @@ -0,0 +1,56 @@ +/** + * @file + * + * @ingroup ScoreSchedulerEDF + * + * @brief EDF Scheduler Implementation + */ + +/* + * Copryight (c) 2011 Petr Benes. + * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef _RTEMS_SCORE_SCHEDULEREDFIMPL_H +#define _RTEMS_SCORE_SCHEDULEREDFIMPL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ScoreSchedulerEDF EDF + * + * @{ + */ + +RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Schedule_body( + Thread_Control *thread, + bool force_dispatch +) +{ + RBTree_Node *first = _RBTree_First(&_Scheduler_EDF_Ready_queue, RBT_LEFT); + Scheduler_EDF_Per_thread *sched_info = + _RBTree_Container_of(first, Scheduler_EDF_Per_thread, Node); + Thread_Control *heir = (Thread_Control *) sched_info->thread; + + ( void ) thread; + + _Scheduler_Update_heir( heir, force_dispatch ); +} + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 5ea4bb8b74..2d9957a62a 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -20,6 +20,7 @@ #define _RTEMS_SCORE_SCHEDULERIMPL_H #include +#include #ifdef __cplusplus extern "C" { @@ -59,10 +60,12 @@ void _Scheduler_Handler_initialization( void ); * * This kernel routine implements the scheduling decision logic for * the scheduler. It does NOT dispatch. + * + * @param[in] thread The thread which state changed previously. */ -RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( void ) +RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *thread ) { - _Scheduler.Operations.schedule(); + _Scheduler.Operations.schedule( thread ); } /** @@ -237,6 +240,34 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Start_idle( ( *_Scheduler.Operations.start_idle )( thread, processor ); } +RTEMS_INLINE_ROUTINE void _Scheduler_Update_heir( + Thread_Control *heir, + bool force_dispatch +) +{ + Thread_Control *executing = _Thread_Executing; + + _Thread_Heir = heir; + + if ( executing != heir && ( force_dispatch || executing->is_preemptible ) ) + _Thread_Dispatch_necessary = true; +} + +RTEMS_INLINE_ROUTINE void _Scheduler_Generic_block( + void ( *extract )( Thread_Control *thread ), + void ( *schedule )( Thread_Control *thread, bool force_dispatch ), + Thread_Control *thread +) +{ + ( *extract )( thread ); + + /* TODO: flash critical section? */ + + if ( _Thread_Is_executing( thread ) || _Thread_Is_heir( thread ) ) { + ( *schedule )( thread, true ); + } +} + /** * Macro testing whether @a p1 has lower priority than @a p2 * in the intuitive sense of priority. diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h index 69649435bd..cbe0066d8d 100644 --- a/cpukit/score/include/rtems/score/schedulerpriority.h +++ b/cpukit/score/include/rtems/score/schedulerpriority.h @@ -93,7 +93,7 @@ void _Scheduler_priority_Block( * This kernel routine sets the heir thread to be the next ready thread * by invoking the_scheduler->ready_queue->operations->first(). */ -void _Scheduler_priority_Schedule(void); +void _Scheduler_priority_Schedule( Thread_Control *thread ); /** * @brief Allocates @a the_thread->scheduler. diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h index 8a8917ca1b..73c635dced 100644 --- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h +++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -182,11 +183,18 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_requeue( * This kernel routine implements scheduling decision logic * for priority-based scheduling. */ -RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(void) +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body( + Thread_Control *thread, + bool force_dispatch +) { - _Thread_Heir = _Scheduler_priority_Ready_queue_first( + Thread_Control *heir = _Scheduler_priority_Ready_queue_first( (Chain_Control *) _Scheduler.information ); + + ( void ) thread; + + _Scheduler_Update_heir( heir, force_dispatch ); } /** diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h index 5180d36087..477ea2c026 100644 --- a/cpukit/score/include/rtems/score/schedulersimple.h +++ b/cpukit/score/include/rtems/score/schedulersimple.h @@ -66,7 +66,7 @@ void _Scheduler_simple_Initialize( void ); * on the ready queue by getting the first node in the scheduler * information. */ -void _Scheduler_simple_Schedule( void ); +void _Scheduler_simple_Schedule( Thread_Control *thread ); /** * @brief Invoked when a thread wishes to voluntarily diff --git a/cpukit/score/include/rtems/score/schedulersimpleimpl.h b/cpukit/score/include/rtems/score/schedulersimpleimpl.h index 076d1a9258..51d37741b1 100644 --- a/cpukit/score/include/rtems/score/schedulersimpleimpl.h +++ b/cpukit/score/include/rtems/score/schedulersimpleimpl.h @@ -21,7 +21,7 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { @@ -96,6 +96,20 @@ RTEMS_INLINE_ROUTINE void _Scheduler_simple_Insert_priority_fifo( ); } +RTEMS_INLINE_ROUTINE void _Scheduler_simple_Schedule_body( + Thread_Control *thread, + bool force_dispatch +) +{ + Thread_Control *heir = (Thread_Control *) _Chain_First( + (Chain_Control *) _Scheduler.information + ); + + ( void ) thread; + + _Scheduler_Update_heir( heir, force_dispatch ); +} + /** @} */ #ifdef __cplusplus diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h index 1b827cbabe..6cc87f3dec 100644 --- a/cpukit/score/include/rtems/score/schedulersimplesmp.h +++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h @@ -85,7 +85,7 @@ void _Scheduler_simple_smp_Extract( Thread_Control *thread ); void _Scheduler_simple_smp_Yield( Thread_Control *thread ); -void _Scheduler_simple_smp_Schedule( void ); +void _Scheduler_simple_smp_Schedule( Thread_Control *thread ); void _Scheduler_simple_smp_Start_idle( Thread_Control *thread, diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 717f00b4e8..e07b39266d 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -497,16 +497,6 @@ RTEMS_INLINE_ROUTINE bool _Thread_Is_heir ( return ( the_thread == _Thread_Heir ); } -/** - * This function returns true if the currently executing thread - * is also the heir thread, and false otherwise. - */ - -RTEMS_INLINE_ROUTINE bool _Thread_Is_executing_also_the_heir( void ) -{ - return ( _Thread_Executing == _Thread_Heir ); -} - /** * This routine clears any blocking state for the_thread. It performs * any necessary scheduling operations including the selection of -- cgit v1.2.3