diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-05-14 13:50:48 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-05-15 12:18:44 +0200 |
commit | f39f667a69cf5c4bc0dd4555537615022767f0f9 (patch) | |
tree | f8a48b3c7bf443001b036ddcab6ed104210e6134 /cpukit/score/src | |
parent | score: Add and use _Scheduler_Get_context() (diff) | |
download | rtems-f39f667a69cf5c4bc0dd4555537615022767f0f9.tar.bz2 |
score: Simplify _Thread_Change_priority()
The function to change a thread priority was too complex. Simplify it
with a new scheduler operation. This increases the average case
performance due to the simplified logic. The interrupt disabled
critical section is a bit prolonged since now the extract, update and
enqueue steps are executed atomically. This should however not impact
the worst-case interrupt latency since at least for the Deterministic
Priority Scheduler this sequence can be carried out with a wee bit of
instructions and no loops.
Add _Scheduler_Change_priority() to replace the sequence of
- _Thread_Set_transient(),
- _Scheduler_Extract(),
- _Scheduler_Enqueue(), and
- _Scheduler_Enqueue_first().
Delete STATES_TRANSIENT, _States_Is_transient() and
_Thread_Set_transient() since this state is now superfluous.
With this change it is possible to get rid of the
SCHEDULER_SMP_NODE_IN_THE_AIR state. This considerably simplifies the
implementation of the new SMP locking protocols.
Diffstat (limited to 'cpukit/score/src')
22 files changed, 264 insertions, 550 deletions
diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c index 411e6cef27..1a374f64a6 100644 --- a/cpukit/score/src/schedulercbsunblock.c +++ b/cpukit/score/src/schedulercbsunblock.c @@ -20,6 +20,7 @@ #endif #include <rtems/score/schedulercbsimpl.h> +#include <rtems/score/scheduleredfimpl.h> #include <rtems/score/schedulerimpl.h> #include <rtems/score/threadimpl.h> #include <rtems/score/watchdogimpl.h> diff --git a/cpukit/score/src/scheduleredfextract.c b/cpukit/score/src/scheduleredfchangepriority.c index 94fde0a05c..dfcfef52d1 100644 --- a/cpukit/score/src/scheduleredfextract.c +++ b/cpukit/score/src/scheduleredfchangepriority.c @@ -20,9 +20,11 @@ #include <rtems/score/scheduleredfimpl.h> -void _Scheduler_EDF_Extract( +void _Scheduler_EDF_Change_priority( const Scheduler_Control *scheduler, - Thread_Control *the_thread + Thread_Control *the_thread, + Priority_Control new_priority, + bool prepend_it ) { Scheduler_EDF_Context *context = @@ -30,5 +32,5 @@ void _Scheduler_EDF_Extract( Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread ); _RBTree_Extract( &context->Ready, &node->Node ); - node->queue_state = SCHEDULER_EDF_QUEUE_STATE_NOT_PRESENTLY; + _RBTree_Insert( &context->Ready, &node->Node ); } diff --git a/cpukit/score/src/scheduleredfenqueue.c b/cpukit/score/src/scheduleredfenqueue.c deleted file mode 100644 index 8973d8b32c..0000000000 --- a/cpukit/score/src/scheduleredfenqueue.c +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file - * - * @brief Scheduler EDF Enqueue - * @ingroup ScoreScheduler - */ - -/* - * Copyright (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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/score/scheduleredfimpl.h> - -void _Scheduler_EDF_Enqueue( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - Scheduler_EDF_Context *context = - _Scheduler_EDF_Get_context( scheduler ); - Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread ); - - _RBTree_Insert( &context->Ready, &node->Node ); - node->queue_state = SCHEDULER_EDF_QUEUE_STATE_YES; -} diff --git a/cpukit/score/src/scheduleredfenqueuefirst.c b/cpukit/score/src/scheduleredfenqueuefirst.c deleted file mode 100644 index aafc9b4a21..0000000000 --- a/cpukit/score/src/scheduleredfenqueuefirst.c +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @file - * - * @brief Enqueues a thread to the ready queue - * - * @ingroup ScoreScheduler - */ - -/* - * Copyright (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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/system.h> -#include <rtems/config.h> -#include <rtems/score/scheduleredf.h> - -void _Scheduler_EDF_Enqueue_first( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - _Scheduler_EDF_Enqueue( scheduler, the_thread ); -} diff --git a/cpukit/score/src/scheduleredfunblock.c b/cpukit/score/src/scheduleredfunblock.c index 7418b64e6a..30fa4f0163 100644 --- a/cpukit/score/src/scheduleredfunblock.c +++ b/cpukit/score/src/scheduleredfunblock.c @@ -18,7 +18,7 @@ #include "config.h" #endif -#include <rtems/score/scheduleredf.h> +#include <rtems/score/scheduleredfimpl.h> #include <rtems/score/schedulerimpl.h> #include <rtems/score/thread.h> diff --git a/cpukit/score/src/schedulerprioritychangepriority.c b/cpukit/score/src/schedulerprioritychangepriority.c new file mode 100644 index 0000000000..448c603861 --- /dev/null +++ b/cpukit/score/src/schedulerprioritychangepriority.c @@ -0,0 +1,61 @@ +/** + * @file + * + * @brief Removes Thread from Thread Queue + * + * @ingroup ScoreScheduler + */ + +/* + * 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.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/score/schedulerpriorityimpl.h> + +void _Scheduler_priority_Change_priority( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Priority_Control new_priority, + bool prepend_it +) +{ + Scheduler_priority_Context *context = + _Scheduler_priority_Get_context( scheduler ); + Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread ); + + _Scheduler_priority_Ready_queue_extract( + the_thread, + &node->Ready_queue, + &context->Bit_map + ); + + _Scheduler_priority_Ready_queue_update( + &node->Ready_queue, + new_priority, + &context->Bit_map, + &context->Ready[ 0 ] + ); + + if ( prepend_it ) { + _Scheduler_priority_Ready_queue_enqueue_first( + the_thread, + &node->Ready_queue, + &context->Bit_map + ); + } else { + _Scheduler_priority_Ready_queue_enqueue( + the_thread, + &node->Ready_queue, + &context->Bit_map + ); + } +} diff --git a/cpukit/score/src/schedulerpriorityenqueue.c b/cpukit/score/src/schedulerpriorityenqueue.c deleted file mode 100644 index aa901cc978..0000000000 --- a/cpukit/score/src/schedulerpriorityenqueue.c +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file - * - * @brief Scheduler Priority Enqueue - * @ingroup ScoreScheduler - */ - -/* - * 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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/score/schedulerpriorityimpl.h> - -void _Scheduler_priority_Enqueue( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - Scheduler_priority_Context *context = - _Scheduler_priority_Get_context( scheduler ); - Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread ); - - _Scheduler_priority_Ready_queue_enqueue( - the_thread, - &node->Ready_queue, - &context->Bit_map - ); -} diff --git a/cpukit/score/src/schedulerpriorityenqueuefirst.c b/cpukit/score/src/schedulerpriorityenqueuefirst.c deleted file mode 100644 index 1714fe57f0..0000000000 --- a/cpukit/score/src/schedulerpriorityenqueuefirst.c +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file - * - * @brief Scheduler Priority Enqueue First - * @ingroup ScoreScheduler - */ - -/* - * 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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/score/schedulerpriorityimpl.h> - -void _Scheduler_priority_Enqueue_first( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - Scheduler_priority_Context *context = - _Scheduler_priority_Get_context( scheduler ); - Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread ); - - _Scheduler_priority_Ready_queue_enqueue_first( - the_thread, - &node->Ready_queue, - &context->Bit_map - ); -} - diff --git a/cpukit/score/src/schedulerpriorityextract.c b/cpukit/score/src/schedulerpriorityextract.c deleted file mode 100644 index 84dbaa4280..0000000000 --- a/cpukit/score/src/schedulerpriorityextract.c +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @file - * - * @brief Removes Thread from Thread Queue - * - * @ingroup ScoreScheduler - */ - -/* - * 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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/score/schedulerpriorityimpl.h> - -void _Scheduler_priority_Extract( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - _Scheduler_priority_Extract_body( scheduler, the_thread ); -} diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c index 8133956fbd..dbf7b0c38b 100644 --- a/cpukit/score/src/schedulerprioritysmp.c +++ b/cpukit/score/src/schedulerprioritysmp.c @@ -27,7 +27,6 @@ #include <rtems/score/schedulerprioritysmp.h> #include <rtems/score/schedulerpriorityimpl.h> #include <rtems/score/schedulersmpimpl.h> -#include <rtems/score/wkspace.h> static Scheduler_priority_SMP_Context * _Scheduler_priority_SMP_Get_context( const Scheduler_Control *scheduler ) @@ -48,6 +47,13 @@ static Scheduler_priority_SMP_Node *_Scheduler_priority_SMP_Node_get( return (Scheduler_priority_SMP_Node *) _Scheduler_Node_get( thread ); } +static Scheduler_priority_SMP_Node *_Scheduler_priority_SMP_Node_downcast( + Scheduler_Node *node +) +{ + return (Scheduler_priority_SMP_Node *) node; +} + void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler ) { Scheduler_priority_SMP_Context *self = @@ -70,40 +76,47 @@ bool _Scheduler_priority_SMP_Allocate( return true; } -void _Scheduler_priority_SMP_Update( - const Scheduler_Control *scheduler, - Thread_Control *thread +static void _Scheduler_priority_SMP_Do_update( + Scheduler_Context *context, + Scheduler_Node *base_node, + Priority_Control new_priority ) { Scheduler_priority_SMP_Context *self = - _Scheduler_priority_SMP_Get_context( scheduler ); + _Scheduler_priority_SMP_Get_self( context ); Scheduler_priority_SMP_Node *node = - _Scheduler_priority_SMP_Node_get( thread ); + _Scheduler_priority_SMP_Node_downcast( base_node ); _Scheduler_priority_Ready_queue_update( - thread, &node->Ready_queue, + new_priority, &self->Bit_map, &self->Ready[ 0 ] ); } +void _Scheduler_priority_SMP_Update( + const Scheduler_Control *scheduler, + Thread_Control *thread +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + Scheduler_Node *node = _Scheduler_Node_get( thread ); + + _Scheduler_priority_SMP_Do_update( context, node, thread->current_priority ); +} + static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready( Scheduler_Context *context ) { Scheduler_priority_SMP_Context *self = _Scheduler_priority_SMP_Get_self( context ); - Thread_Control *highest_ready = NULL; - - if ( !_Priority_bit_map_Is_empty( &self->Bit_map ) ) { - highest_ready = _Scheduler_priority_Ready_queue_first( - &self->Bit_map, - &self->Ready[ 0 ] - ); - } - return highest_ready; + return _Scheduler_priority_Ready_queue_first( + &self->Bit_map, + &self->Ready[ 0 ] + ); } static void _Scheduler_priority_SMP_Move_from_scheduled_to_ready( @@ -179,7 +192,7 @@ static void _Scheduler_priority_SMP_Insert_ready_fifo( ); } -static void _Scheduler_priority_SMP_Do_extract( +static void _Scheduler_priority_SMP_Extract_from_ready( Scheduler_Context *context, Thread_Control *thread ) @@ -189,23 +202,11 @@ static void _Scheduler_priority_SMP_Do_extract( Scheduler_priority_SMP_Node *node = _Scheduler_priority_SMP_Node_get( thread ); - if ( node->Base.state == SCHEDULER_SMP_NODE_SCHEDULED ) { - _Scheduler_SMP_Node_change_state( - &node->Base, - SCHEDULER_SMP_NODE_IN_THE_AIR - ); - _Chain_Extract_unprotected( &thread->Object.Node ); - } else { - _Scheduler_SMP_Node_change_state( - &node->Base, - SCHEDULER_SMP_NODE_BLOCKED - ); - _Scheduler_priority_Ready_queue_extract( - thread, - &node->Ready_queue, - &self->Bit_map - ); - } + _Scheduler_priority_Ready_queue_extract( + thread, + &node->Ready_queue, + &self->Bit_map + ); } void _Scheduler_priority_SMP_Block( @@ -213,13 +214,12 @@ void _Scheduler_priority_SMP_Block( Thread_Control *thread ) { - Scheduler_priority_SMP_Context *self = - _Scheduler_priority_SMP_Get_context( scheduler ); + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); _Scheduler_SMP_Block( - &self->Base.Base, + context, thread, - _Scheduler_priority_SMP_Do_extract, + _Scheduler_priority_SMP_Extract_from_ready, _Scheduler_priority_SMP_Get_highest_ready, _Scheduler_priority_SMP_Move_from_ready_to_scheduled ); @@ -228,6 +228,7 @@ void _Scheduler_priority_SMP_Block( static void _Scheduler_priority_SMP_Enqueue_ordered( Scheduler_Context *context, Thread_Control *thread, + bool has_processor_allocated, Chain_Node_order order, Scheduler_SMP_Insert insert_ready, Scheduler_SMP_Insert insert_scheduled @@ -236,6 +237,7 @@ static void _Scheduler_priority_SMP_Enqueue_ordered( _Scheduler_SMP_Enqueue_ordered( context, thread, + has_processor_allocated, order, _Scheduler_priority_SMP_Get_highest_ready, insert_ready, @@ -245,52 +247,66 @@ static void _Scheduler_priority_SMP_Enqueue_ordered( ); } -void _Scheduler_priority_SMP_Enqueue_lifo( - const Scheduler_Control *scheduler, - Thread_Control *thread +static void _Scheduler_priority_SMP_Enqueue_lifo( + Scheduler_Context *context, + Thread_Control *thread, + bool has_processor_allocated ) { - Scheduler_priority_SMP_Context *self = - _Scheduler_priority_SMP_Get_context( scheduler ); - _Scheduler_priority_SMP_Enqueue_ordered( - &self->Base.Base, + context, thread, + has_processor_allocated, _Scheduler_simple_Insert_priority_lifo_order, _Scheduler_priority_SMP_Insert_ready_lifo, _Scheduler_SMP_Insert_scheduled_lifo ); } -void _Scheduler_priority_SMP_Enqueue_fifo( - const Scheduler_Control *scheduler, - Thread_Control *thread +static void _Scheduler_priority_SMP_Enqueue_fifo( + Scheduler_Context *context, + Thread_Control *thread, + bool has_processor_allocated ) { - Scheduler_priority_SMP_Context *self = - _Scheduler_priority_SMP_Get_context( scheduler ); - _Scheduler_priority_SMP_Enqueue_ordered( - &self->Base.Base, + context, thread, + has_processor_allocated, _Scheduler_simple_Insert_priority_fifo_order, _Scheduler_priority_SMP_Insert_ready_fifo, _Scheduler_SMP_Insert_scheduled_fifo ); } -void _Scheduler_priority_SMP_Extract( +void _Scheduler_priority_SMP_Unblock( const Scheduler_Control *scheduler, Thread_Control *thread ) { - Scheduler_priority_SMP_Context *self = - _Scheduler_priority_SMP_Get_context( scheduler ); + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - _Scheduler_SMP_Extract( - &self->Base.Base, + _Scheduler_priority_SMP_Enqueue_fifo( context, thread, false ); +} + +void _Scheduler_priority_SMP_Change_priority( + const Scheduler_Control *scheduler, + Thread_Control *thread, + Priority_Control new_priority, + bool prepend_it +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + _Scheduler_SMP_Change_priority( + context, thread, - _Scheduler_priority_SMP_Do_extract + new_priority, + prepend_it, + _Scheduler_priority_SMP_Extract_from_ready, + _Scheduler_priority_SMP_Do_update, + _Scheduler_priority_SMP_Enqueue_fifo, + _Scheduler_priority_SMP_Enqueue_lifo ); } @@ -299,12 +315,13 @@ void _Scheduler_priority_SMP_Yield( Thread_Control *thread ) { + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); ISR_Level level; _ISR_Disable( level ); - _Scheduler_priority_SMP_Extract( scheduler, thread ); - _Scheduler_priority_SMP_Enqueue_fifo( scheduler, thread ); + _Scheduler_SMP_Extract_from_scheduled( thread ); + _Scheduler_priority_SMP_Enqueue_fifo( context, thread, true ); _ISR_Enable( level ); } @@ -314,15 +331,8 @@ void _Scheduler_priority_SMP_Schedule( Thread_Control *thread ) { - Scheduler_priority_SMP_Context *self = - _Scheduler_priority_SMP_Get_context( scheduler ); - - _Scheduler_SMP_Schedule( - &self->Base.Base, - thread, - _Scheduler_priority_SMP_Get_highest_ready, - _Scheduler_priority_SMP_Move_from_ready_to_scheduled - ); + (void) scheduler; + (void) thread; } void _Scheduler_priority_SMP_Start_idle( @@ -331,8 +341,7 @@ void _Scheduler_priority_SMP_Start_idle( Per_CPU_Control *cpu ) { - Scheduler_priority_SMP_Context *self = - _Scheduler_priority_SMP_Get_context( scheduler ); + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - _Scheduler_SMP_Start_idle( &self->Base.Base, thread, cpu ); + _Scheduler_SMP_Start_idle( context, thread, cpu ); } diff --git a/cpukit/score/src/schedulerpriorityupdate.c b/cpukit/score/src/schedulerpriorityupdate.c index 8a22ee662d..e58a6091a3 100644 --- a/cpukit/score/src/schedulerpriorityupdate.c +++ b/cpukit/score/src/schedulerpriorityupdate.c @@ -30,8 +30,8 @@ void _Scheduler_priority_Update( Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread ); _Scheduler_priority_Ready_queue_update( - the_thread, &node->Ready_queue, + the_thread->current_priority, &context->Bit_map, &context->Ready[ 0 ] ); diff --git a/cpukit/score/src/schedulersimplereadyqueueenqueue.c b/cpukit/score/src/schedulersimplechangepriority.c index 8e5f12d6ee..010f1dfc79 100644 --- a/cpukit/score/src/schedulersimplereadyqueueenqueue.c +++ b/cpukit/score/src/schedulersimplechangepriority.c @@ -1,7 +1,8 @@ /** * @file * - * @brief Scheduler Simple Priority Enqueue Ready Thread + * @brief Removes a Thread from the Simple Queue + * * @ingroup ScoreScheduler */ @@ -20,13 +21,21 @@ #include <rtems/score/schedulersimpleimpl.h> -void _Scheduler_simple_Ready_queue_enqueue( +void _Scheduler_simple_Change_priority( const Scheduler_Control *scheduler, - Thread_Control *the_thread + Thread_Control *the_thread, + Priority_Control new_priority, + bool prepend_it ) { Scheduler_simple_Context *context = _Scheduler_simple_Get_context( scheduler ); - _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread ); + _Scheduler_simple_Extract( scheduler, the_thread ); + + if ( prepend_it ) { + _Scheduler_simple_Insert_priority_lifo( &context->Ready, the_thread ); + } else { + _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread ); + } } diff --git a/cpukit/score/src/schedulersimpleenqueue.c b/cpukit/score/src/schedulersimpleenqueue.c deleted file mode 100644 index 5dc88948da..0000000000 --- a/cpukit/score/src/schedulersimpleenqueue.c +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @file - * - * @brief Puts Thread onto the Ready Queue - * - * @ingroup ScoreScheduler - */ - -/* - * 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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/score/schedulersimpleimpl.h> - -void _Scheduler_simple_Enqueue( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - _Scheduler_simple_Ready_queue_enqueue( scheduler, the_thread ); -} diff --git a/cpukit/score/src/schedulersimpleenqueuefirst.c b/cpukit/score/src/schedulersimpleenqueuefirst.c deleted file mode 100644 index 2ea0a15917..0000000000 --- a/cpukit/score/src/schedulersimpleenqueuefirst.c +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @file - * - * @brief Scheduler Simple Enqueue First - * @ingroup ScoreScheduler - */ - -/* - * 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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/score/schedulersimple.h> - -void _Scheduler_simple_Enqueue_first( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - _Scheduler_simple_Ready_queue_enqueue_first( scheduler, the_thread ); -} diff --git a/cpukit/score/src/schedulersimpleextract.c b/cpukit/score/src/schedulersimpleextract.c deleted file mode 100644 index 6b89c99881..0000000000 --- a/cpukit/score/src/schedulersimpleextract.c +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @file - * - * @brief Removes a Thread from the Simple Queue - * - * @ingroup ScoreScheduler - */ - -/* - * 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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/score/schedulersimpleimpl.h> - -void _Scheduler_simple_Extract( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - (void) scheduler; - - _Chain_Extract_unprotected( &the_thread->Object.Node ); -} diff --git a/cpukit/score/src/schedulersimplereadyqueueenqueuefirst.c b/cpukit/score/src/schedulersimplereadyqueueenqueuefirst.c deleted file mode 100644 index c5f1e68597..0000000000 --- a/cpukit/score/src/schedulersimplereadyqueueenqueuefirst.c +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @file - * - * @brief Scheduler Simple Ready Queue Enqueue First - * @ingroup ScoreScheduler - */ - -/* - * 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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/score/schedulersimpleimpl.h> - -void _Scheduler_simple_Ready_queue_enqueue_first( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - Scheduler_simple_Context *context = - _Scheduler_simple_Get_context( scheduler ); - - _Scheduler_simple_Insert_priority_lifo( &context->Ready, the_thread ); -} diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c index 8436659df4..a971ee1b64 100644 --- a/cpukit/score/src/schedulersimplesmp.c +++ b/cpukit/score/src/schedulersimplesmp.c @@ -20,7 +20,6 @@ #include <rtems/score/schedulersimplesmp.h> #include <rtems/score/schedulersmpimpl.h> -#include <rtems/score/wkspace.h> static Scheduler_simple_SMP_Context * _Scheduler_simple_SMP_Get_context( const Scheduler_Control *scheduler ) @@ -55,20 +54,25 @@ bool _Scheduler_simple_SMP_Allocate( return true; } +static void _Scheduler_simple_SMP_Do_update( + Scheduler_Context *context, + Scheduler_Node *node, + Priority_Control new_priority +) +{ + (void) context; + (void) node; + (void) new_priority; +} + static Thread_Control *_Scheduler_simple_SMP_Get_highest_ready( Scheduler_Context *context ) { Scheduler_simple_SMP_Context *self = _Scheduler_simple_SMP_Get_self( context ); - Thread_Control *highest_ready = NULL; - Chain_Control *ready = &self->Ready; - if ( !_Chain_Is_empty( ready ) ) { - highest_ready = (Thread_Control *) _Chain_First( ready ); - } - - return highest_ready; + return (Thread_Control *) _Chain_First( &self->Ready ); } static void _Scheduler_simple_SMP_Move_from_scheduled_to_ready( @@ -131,21 +135,13 @@ static void _Scheduler_simple_SMP_Insert_ready_fifo( ); } -static void _Scheduler_simple_SMP_Do_extract( +static void _Scheduler_simple_SMP_Extract_from_ready( Scheduler_Context *context, Thread_Control *thread ) { - Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread ); - (void) context; - if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) { - _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_IN_THE_AIR ); - } else { - _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED ); - } - _Chain_Extract_unprotected( &thread->Object.Node ); } @@ -154,13 +150,12 @@ void _Scheduler_simple_SMP_Block( Thread_Control *thread ) { - Scheduler_simple_SMP_Context *self = - _Scheduler_simple_SMP_Get_context( scheduler ); + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); _Scheduler_SMP_Block( - &self->Base.Base, + context, thread, - _Scheduler_simple_SMP_Do_extract, + _Scheduler_simple_SMP_Extract_from_ready, _Scheduler_simple_SMP_Get_highest_ready, _Scheduler_simple_SMP_Move_from_ready_to_scheduled ); @@ -169,6 +164,7 @@ void _Scheduler_simple_SMP_Block( static void _Scheduler_simple_SMP_Enqueue_ordered( Scheduler_Context *context, Thread_Control *thread, + bool has_processor_allocated, Chain_Node_order order, Scheduler_SMP_Insert insert_ready, Scheduler_SMP_Insert insert_scheduled @@ -177,6 +173,7 @@ static void _Scheduler_simple_SMP_Enqueue_ordered( _Scheduler_SMP_Enqueue_ordered( context, thread, + has_processor_allocated, order, _Scheduler_simple_SMP_Get_highest_ready, insert_ready, @@ -186,52 +183,66 @@ static void _Scheduler_simple_SMP_Enqueue_ordered( ); } -void _Scheduler_simple_SMP_Enqueue_priority_lifo( - const Scheduler_Control *scheduler, - Thread_Control *thread +static void _Scheduler_simple_SMP_Enqueue_lifo( + Scheduler_Context *context, + Thread_Control *thread, + bool has_processor_allocated ) { - Scheduler_simple_SMP_Context *self = - _Scheduler_simple_SMP_Get_context( scheduler ); - _Scheduler_simple_SMP_Enqueue_ordered( - &self->Base.Base, + context, thread, + has_processor_allocated, _Scheduler_simple_Insert_priority_lifo_order, _Scheduler_simple_SMP_Insert_ready_lifo, _Scheduler_SMP_Insert_scheduled_lifo ); } -void _Scheduler_simple_SMP_Enqueue_priority_fifo( - const Scheduler_Control *scheduler, - Thread_Control *thread +static void _Scheduler_simple_SMP_Enqueue_fifo( + Scheduler_Context *context, + Thread_Control *thread, + bool has_processor_allocated ) { - Scheduler_simple_SMP_Context *self = - _Scheduler_simple_SMP_Get_context( scheduler ); - _Scheduler_simple_SMP_Enqueue_ordered( - &self->Base.Base, + context, thread, + has_processor_allocated, _Scheduler_simple_Insert_priority_fifo_order, _Scheduler_simple_SMP_Insert_ready_fifo, _Scheduler_SMP_Insert_scheduled_fifo ); } -void _Scheduler_simple_SMP_Extract( +void _Scheduler_simple_SMP_Unblock( const Scheduler_Control *scheduler, Thread_Control *thread ) { - Scheduler_simple_SMP_Context *self = - _Scheduler_simple_SMP_Get_context( scheduler ); + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + _Scheduler_simple_SMP_Enqueue_fifo( context, thread, false ); +} - _Scheduler_SMP_Extract( - &self->Base.Base, +void _Scheduler_simple_SMP_Change_priority( + const Scheduler_Control *scheduler, + Thread_Control *thread, + Priority_Control new_priority, + bool prepend_it +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + _Scheduler_SMP_Change_priority( + context, thread, - _Scheduler_simple_SMP_Do_extract + new_priority, + prepend_it, + _Scheduler_simple_SMP_Extract_from_ready, + _Scheduler_simple_SMP_Do_update, + _Scheduler_simple_SMP_Enqueue_fifo, + _Scheduler_simple_SMP_Enqueue_lifo ); } @@ -240,12 +251,13 @@ void _Scheduler_simple_SMP_Yield( Thread_Control *thread ) { + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); ISR_Level level; _ISR_Disable( level ); - _Scheduler_simple_SMP_Extract( scheduler, thread ); - _Scheduler_simple_SMP_Enqueue_priority_fifo( scheduler, thread ); + _Scheduler_SMP_Extract_from_scheduled( thread ); + _Scheduler_simple_SMP_Enqueue_fifo( context, thread, true ); _ISR_Enable( level ); } @@ -255,15 +267,8 @@ void _Scheduler_simple_SMP_Schedule( Thread_Control *thread ) { - Scheduler_simple_SMP_Context *self = - _Scheduler_simple_SMP_Get_context( scheduler ); - - _Scheduler_SMP_Schedule( - &self->Base.Base, - thread, - _Scheduler_simple_SMP_Get_highest_ready, - _Scheduler_simple_SMP_Move_from_ready_to_scheduled - ); + (void) scheduler; + (void) thread; } void _Scheduler_simple_SMP_Start_idle( @@ -272,8 +277,7 @@ void _Scheduler_simple_SMP_Start_idle( Per_CPU_Control *cpu ) { - Scheduler_simple_SMP_Context *self = - _Scheduler_simple_SMP_Get_context( scheduler ); + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - _Scheduler_SMP_Start_idle( &self->Base.Base, thread, cpu ); + _Scheduler_SMP_Start_idle( context, thread, cpu ); } diff --git a/cpukit/score/src/schedulersimpleunblock.c b/cpukit/score/src/schedulersimpleunblock.c index 3a9528fba5..4e49bd6697 100644 --- a/cpukit/score/src/schedulersimpleunblock.c +++ b/cpukit/score/src/schedulersimpleunblock.c @@ -26,7 +26,10 @@ void _Scheduler_simple_Unblock( Thread_Control *the_thread ) { - _Scheduler_simple_Ready_queue_enqueue( scheduler, the_thread ); + Scheduler_simple_Context *context = + _Scheduler_simple_Get_context( scheduler ); + + _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread ); /* * If the thread that was unblocked is more important than the heir, diff --git a/cpukit/score/src/schedulersimpleyield.c b/cpukit/score/src/schedulersimpleyield.c index ea41892ad0..65578d0bbb 100644 --- a/cpukit/score/src/schedulersimpleyield.c +++ b/cpukit/score/src/schedulersimpleyield.c @@ -26,11 +26,14 @@ void _Scheduler_simple_Yield( Thread_Control *the_thread ) { + Scheduler_simple_Context *context = + _Scheduler_simple_Get_context( scheduler ); ISR_Level level; _ISR_Disable( level ); - _Scheduler_simple_Ready_queue_requeue( scheduler, the_thread ); + _Chain_Extract_unprotected( &the_thread->Object.Node ); + _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread ); _ISR_Flash( level ); diff --git a/cpukit/score/src/schedulersmpvalidstatechanges.c b/cpukit/score/src/schedulersmpvalidstatechanges.c index 61f6a7e2d5..6a5dcc6de4 100644 --- a/cpukit/score/src/schedulersmpvalidstatechanges.c +++ b/cpukit/score/src/schedulersmpvalidstatechanges.c @@ -30,10 +30,9 @@ * Table with all valid state transitions. It is used in * _Scheduler_SMP_Node_change_state() in case RTEMS_DEBUG is defined. */ -const bool _Scheduler_SMP_Node_valid_state_changes[ 4 ][ 4 ] = { - /* BLOCKED SCHEDULED READY IN THE AIR */ - /* BLOCKED */ { false, true, true, false }, - /* SCHEDULED */ { false, false, true, true }, - /* READY */ { true, true, false, false }, - /* IN THE AIR */ { true, true, true, false } +const bool _Scheduler_SMP_Node_valid_state_changes[ 3 ][ 3 ] = { + /* FROM / TO BLOCKED SCHEDULED READY */ + /* BLOCKED */ { false, true, true }, + /* SCHEDULED */ { true, false, true }, + /* READY */ { true, true, false } }; diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c index 68eb3e89fa..4480b536d0 100644 --- a/cpukit/score/src/threadchangepriority.c +++ b/cpukit/score/src/threadchangepriority.c @@ -29,79 +29,40 @@ void _Thread_Change_priority( bool prepend_it ) { - const Scheduler_Control *scheduler = _Scheduler_Get( the_thread ); - ISR_Level level; - States_Control state, original_state; - - /* - * Save original state - */ - original_state = the_thread->current_state; - - /* - * Set a transient state for the thread so it is pulled off the Ready chains. - * This will prevent it from being scheduled no matter what happens in an - * ISR. - */ - _Thread_Set_transient( the_thread ); - /* * Do not bother recomputing all the priority related information if * we are not REALLY changing priority. */ - if ( the_thread->current_priority != new_priority ) - _Thread_Set_priority( the_thread, new_priority ); - - _ISR_Disable( level ); - - /* - * If the thread has more than STATES_TRANSIENT set, then it is blocked, - * If it is blocked on a thread queue, then we need to requeue it. - */ - state = the_thread->current_state; - if ( state != STATES_TRANSIENT ) { - /* Only clear the transient state if it wasn't set already */ - if ( ! _States_Is_transient( original_state ) ) - the_thread->current_state = _States_Clear( STATES_TRANSIENT, state ); - - /* - * The thread may have new blocking states added by interrupt service - * routines after the change into the transient state. This will not - * result in a _Scheduler_Block() operation. Make sure we select an heir - * now. - */ - _Scheduler_Schedule( scheduler, the_thread ); - - _ISR_Enable( level ); - if ( _States_Is_waiting_on_thread_queue( state ) ) { - _Thread_queue_Requeue( the_thread->Wait.queue, the_thread ); + if ( the_thread->current_priority != new_priority ) { + ISR_Level level; + const Scheduler_Control *scheduler; + + _ISR_Disable( level ); + + scheduler = _Scheduler_Get( the_thread ); + the_thread->current_priority = new_priority; + + if ( _States_Is_ready( the_thread->current_state ) ) { + _Scheduler_Change_priority( + scheduler, + the_thread, + new_priority, + prepend_it + ); + + _ISR_Flash( level ); + + /* + * We altered the set of thread priorities. So let's figure out + * who is the heir and if we need to switch to them. + */ + scheduler = _Scheduler_Get( the_thread ); + _Scheduler_Schedule( scheduler, the_thread ); + } else { + _Scheduler_Update( scheduler, the_thread ); } - return; - } - - /* Only clear the transient state if it wasn't set already */ - if ( ! _States_Is_transient( original_state ) ) { - /* - * Interrupts are STILL disabled. - * We now know the thread will be in the READY state when we remove - * the TRANSIENT state. So we have to place it on the appropriate - * Ready Queue with interrupts off. - */ - the_thread->current_state = _States_Clear( STATES_TRANSIENT, state ); + _ISR_Enable( level ); - if ( prepend_it ) - _Scheduler_Enqueue_first( scheduler, the_thread ); - else - _Scheduler_Enqueue( scheduler, the_thread ); + _Thread_queue_Requeue( the_thread->Wait.queue, the_thread ); } - - _ISR_Flash( level ); - - /* - * We altered the set of thread priorities. So let's figure out - * who is the heir and if we need to switch to them. - */ - _Scheduler_Schedule( scheduler, the_thread ); - - _ISR_Enable( level ); } diff --git a/cpukit/score/src/threadsettransient.c b/cpukit/score/src/threadsettransient.c deleted file mode 100644 index ead3c452a3..0000000000 --- a/cpukit/score/src/threadsettransient.c +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @file - * - * @brief Sets the Transient State for a Thread - * - * @ingroup ScoreThread - */ - -/* - * COPYRIGHT (c) 1989-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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/score/threadimpl.h> -#include <rtems/score/isrlevel.h> -#include <rtems/score/schedulerimpl.h> - -void _Thread_Set_transient( - Thread_Control *the_thread -) -{ - ISR_Level level; - uint32_t old_state; - - _ISR_Disable( level ); - - old_state = the_thread->current_state; - the_thread->current_state = _States_Set( STATES_TRANSIENT, old_state ); - - if ( _States_Is_ready( old_state ) ) { - _Scheduler_Extract( _Scheduler_Get( the_thread ), the_thread ); - } - - _ISR_Enable( level ); - -} |