From 48c4a556a26279f887f4c66056695cb04a986a72 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 13 Aug 2013 13:13:25 +0200 Subject: smp: Generalize Simple SMP scheduler --- cpukit/score/src/schedulersimplesmp.c | 160 ++++++++++++++++------------------ 1 file changed, 75 insertions(+), 85 deletions(-) (limited to 'cpukit/score/src/schedulersimplesmp.c') diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c index a46f58e673..0aa26170cf 100644 --- a/cpukit/score/src/schedulersimplesmp.c +++ b/cpukit/score/src/schedulersimplesmp.c @@ -19,7 +19,6 @@ #endif #include -#include #include #include @@ -72,121 +71,111 @@ static void _Scheduler_simple_smp_Move_from_ready_to_scheduled( ); } -static void _Scheduler_simple_smp_Insert( - Chain_Control *chain, - Thread_Control *thread, - Chain_Node_order order +static void _Scheduler_simple_smp_Insert_ready_lifo( + Scheduler_SMP_Control *self, + Thread_Control *thread ) { - _Chain_Insert_ordered_unprotected( chain, &thread->Object.Node, order ); + _Chain_Insert_ordered_unprotected( + &self->ready[ 0 ], + &thread->Object.Node, + _Scheduler_simple_Insert_priority_lifo_order + ); } -static void _Scheduler_simple_smp_Schedule_highest_ready( +static void _Scheduler_simple_smp_Insert_ready_fifo( Scheduler_SMP_Control *self, - Thread_Control *victim + Thread_Control *thread ) { - Thread_Control *highest_ready = - (Thread_Control *) _Chain_First( &self->ready[ 0 ] ); - - _Scheduler_SMP_Allocate_processor( highest_ready, victim ); - - _Scheduler_simple_smp_Move_from_ready_to_scheduled( self, highest_ready ); + _Chain_Insert_ordered_unprotected( + &self->ready[ 0 ], + &thread->Object.Node, + _Scheduler_simple_Insert_priority_fifo_order + ); } -static void _Scheduler_simple_smp_Enqueue_ordered( - Thread_Control *thread, - Chain_Node_order order +static void _Scheduler_simple_smp_Do_extract( + Scheduler_SMP_Control *self, + Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + ( void ) self; - if ( thread->is_in_the_air ) { - Thread_Control *highest_ready = - _Scheduler_simple_smp_Get_highest_ready( self ); - - thread->is_in_the_air = false; - - /* - * The thread has been extracted from the scheduled chain. We have to - * place it now on the scheduled or ready chain. - * - * NOTE: Do not exchange parameters to do the negation of the order check. - */ - if ( - highest_ready != NULL - && !( *order )( &thread->Object.Node, &highest_ready->Object.Node ) - ) { - _Scheduler_SMP_Allocate_processor( highest_ready, thread ); - - _Scheduler_simple_smp_Insert( &self->ready[ 0 ], thread, order ); - - _Scheduler_simple_smp_Move_from_ready_to_scheduled( - self, - highest_ready - ); - } else { - thread->is_scheduled = true; - - _Scheduler_simple_smp_Insert( &self->scheduled, thread, order ); - } - } else { - Thread_Control *lowest_scheduled = _Scheduler_SMP_Get_lowest_scheduled( self ); - - /* - * The scheduled chain is empty if nested interrupts change the priority of - * all scheduled threads. These threads are in the air. - */ - if ( - lowest_scheduled != NULL - && ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) - ) { - _Scheduler_SMP_Allocate_processor( thread, lowest_scheduled ); - - _Scheduler_simple_smp_Insert( &self->scheduled, thread, order ); - - _Scheduler_simple_smp_Move_from_scheduled_to_ready( - self, - lowest_scheduled - ); - } else { - _Scheduler_simple_smp_Insert( &self->ready[ 0 ], thread, order ); - } - } + thread->is_in_the_air = thread->is_scheduled; + thread->is_scheduled = false; + + _Chain_Extract_unprotected( &thread->Object.Node ); } void _Scheduler_simple_smp_Block( Thread_Control *thread ) { - _Chain_Extract_unprotected( &thread->Object.Node ); + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); - if ( thread->is_scheduled ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + _Scheduler_SMP_Block( + self, + thread, + _Scheduler_simple_smp_Do_extract, + _Scheduler_simple_smp_Get_highest_ready, + _Scheduler_simple_smp_Move_from_ready_to_scheduled + ); +} - _Scheduler_simple_smp_Schedule_highest_ready( self, thread ); - } +static void _Scheduler_simple_smp_Enqueue_ordered( + Scheduler_SMP_Control *self, + Thread_Control *thread, + Chain_Node_order order, + Scheduler_SMP_Insert insert_ready, + Scheduler_SMP_Insert insert_scheduled +) +{ + _Scheduler_SMP_Enqueue_ordered( + self, + thread, + order, + _Scheduler_simple_smp_Get_highest_ready, + insert_ready, + insert_scheduled, + _Scheduler_simple_smp_Move_from_ready_to_scheduled, + _Scheduler_simple_smp_Move_from_scheduled_to_ready + ); } void _Scheduler_simple_smp_Enqueue_priority_lifo( Thread_Control *thread ) { + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + _Scheduler_simple_smp_Enqueue_ordered( + self, thread, - _Scheduler_simple_Insert_priority_lifo_order + _Scheduler_simple_Insert_priority_lifo_order, + _Scheduler_simple_smp_Insert_ready_lifo, + _Scheduler_SMP_Insert_scheduled_lifo ); } void _Scheduler_simple_smp_Enqueue_priority_fifo( Thread_Control *thread ) { + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + _Scheduler_simple_smp_Enqueue_ordered( + self, thread, - _Scheduler_simple_Insert_priority_fifo_order + _Scheduler_simple_Insert_priority_fifo_order, + _Scheduler_simple_smp_Insert_ready_fifo, + _Scheduler_SMP_Insert_scheduled_fifo ); } void _Scheduler_simple_smp_Extract( Thread_Control *thread ) { - thread->is_in_the_air = true; + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); - _Chain_Extract_unprotected( &thread->Object.Node ); + _Scheduler_SMP_Extract( + self, + thread, + _Scheduler_simple_smp_Do_extract + ); } void _Scheduler_simple_smp_Yield( Thread_Control *thread ) @@ -203,11 +192,12 @@ void _Scheduler_simple_smp_Yield( Thread_Control *thread ) void _Scheduler_simple_smp_Schedule( Thread_Control *thread ) { - if ( thread->is_in_the_air ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); - - thread->is_in_the_air = false; + Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); - _Scheduler_simple_smp_Schedule_highest_ready( self, thread ); - } + _Scheduler_SMP_Schedule( + self, + thread, + _Scheduler_simple_smp_Get_highest_ready, + _Scheduler_simple_smp_Move_from_ready_to_scheduled + ); } -- cgit v1.2.3