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/schedulerprioritysmp.c | |
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/schedulerprioritysmp.c')
-rw-r--r-- | cpukit/score/src/schedulerprioritysmp.c | 153 |
1 files changed, 81 insertions, 72 deletions
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 ); } |