diff options
Diffstat (limited to 'cpukit/score/src/schedulerstrongapa.c')
-rw-r--r-- | cpukit/score/src/schedulerstrongapa.c | 164 |
1 files changed, 145 insertions, 19 deletions
diff --git a/cpukit/score/src/schedulerstrongapa.c b/cpukit/score/src/schedulerstrongapa.c index 2d138bc7c3..b38a0f96f0 100644 --- a/cpukit/score/src/schedulerstrongapa.c +++ b/cpukit/score/src/schedulerstrongapa.c @@ -31,12 +31,14 @@ * _Scheduler_strong_APA_Set_affinity(), * _Scheduler_strong_APA_Set_scheduled(), _Scheduler_strong_APA_Start_idle(), * _Scheduler_strong_APA_Unblock(), _Scheduler_strong_APA_Update_priority(), - * _Scheduler_strong_APA_Withdraw_node(), and _Scheduler_strong_APA_Yield(). + * _Scheduler_strong_APA_Withdraw_node(), + * _Scheduler_strong_APA_Make_sticky(), _Scheduler_strong_APA_Clean_sticky(), + * and _Scheduler_strong_APA_Yield(). */ /* * Copyright (C) 2020 Richi Dubey - * Copyright (C) 2013, 2016 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2013, 2016 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -155,25 +157,21 @@ static inline Scheduler_Node *_Scheduler_strong_APA_Get_scheduled( static inline void _Scheduler_strong_APA_Allocate_processor( Scheduler_Context *context, Scheduler_Node *scheduled_base, - Scheduler_Node *victim_base, - Per_CPU_Control *victim_cpu + Per_CPU_Control *cpu ) { Scheduler_strong_APA_Node *scheduled; Scheduler_strong_APA_Context *self; - (void) victim_base; - scheduled = _Scheduler_strong_APA_Node_downcast( scheduled_base ); self = _Scheduler_strong_APA_Get_self( context ); - _Scheduler_strong_APA_Set_scheduled( self, scheduled_base, victim_cpu ); + _Scheduler_strong_APA_Set_scheduled( self, scheduled_base, cpu ); _Scheduler_SMP_Allocate_processor_exact( context, &( scheduled->Base.Base ), - NULL, - victim_cpu + cpu ); } @@ -268,6 +266,63 @@ static inline Scheduler_Node * _Scheduler_strong_APA_Find_highest_ready( return highest_ready; } +static inline Scheduler_Node *_Scheduler_strong_APA_Get_idle( void *arg ) +{ + Scheduler_strong_APA_Context *self; + Scheduler_strong_APA_Node *lowest_ready = NULL; + Priority_Control max_priority_num; + const Chain_Node *tail; + Chain_Node *next; + + self = _Scheduler_strong_APA_Get_self( arg ); + tail = _Chain_Immutable_tail( &self->Ready ); + next = _Chain_First( &self->Ready ); + max_priority_num = 0; + + while ( next != tail ) { + Scheduler_strong_APA_Node *node; + Scheduler_SMP_Node_state curr_state; + + node = (Scheduler_strong_APA_Node*) STRONG_SCHEDULER_NODE_OF_CHAIN( next ); + curr_state = _Scheduler_SMP_Node_state( &node->Base.Base ); + + if ( curr_state == SCHEDULER_SMP_NODE_READY ) { + Priority_Control curr_priority; + + curr_priority = _Scheduler_Node_get_priority( &node->Base.Base ); + + if ( curr_priority > max_priority_num ) { + max_priority_num = curr_priority; + lowest_ready = node; + } + } + + next = _Chain_Next( next ); + } + + _Assert( lowest_ready != NULL ); + _Chain_Extract_unprotected( &lowest_ready->Ready_node ); + _Chain_Set_off_chain( &lowest_ready->Ready_node ); + + return &lowest_ready->Base.Base; +} + +static inline void _Scheduler_strong_APA_Release_idle( + Scheduler_Node *node_base, + void *arg +) +{ + Scheduler_strong_APA_Context *self; + Scheduler_strong_APA_Node *node; + + self = _Scheduler_strong_APA_Get_self( arg ); + node = _Scheduler_strong_APA_Node_downcast( node_base ); + + if ( _Chain_Is_node_off_chain( &node->Ready_node ) ) { + _Chain_Append_unprotected( &self->Ready, &node->Ready_node ); + } +} + static inline void _Scheduler_strong_APA_Move_from_ready_to_scheduled( Scheduler_Context *context, Scheduler_Node *ready_to_scheduled @@ -384,16 +439,24 @@ static inline Scheduler_Node *_Scheduler_strong_APA_Get_highest_ready( * So there is need for task shifting. */ while ( node->cpu_to_preempt != filter_cpu ) { + Thread_Control *next_node_idle; + curr_node = &node->Base.Base; next_node = _Scheduler_strong_APA_Get_scheduled( self, node->cpu_to_preempt ); + next_node_idle = _Scheduler_Release_idle_thread_if_necessary( + next_node, + _Scheduler_strong_APA_Release_idle, + context + ); (void) _Scheduler_SMP_Preempt( context, curr_node, next_node, + next_node_idle, _Scheduler_strong_APA_Allocate_processor ); @@ -585,6 +648,8 @@ static inline bool _Scheduler_strong_APA_Do_enqueue( self = _Scheduler_strong_APA_Get_self( context ); CPU = self->CPU; + _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY ); + node_priority = _Scheduler_Node_get_priority( node ); node_priority = SCHEDULER_PRIORITY_PURIFY( node_priority ); @@ -631,7 +696,10 @@ static inline bool _Scheduler_strong_APA_Do_enqueue( next_node, _Scheduler_SMP_Insert_scheduled, _Scheduler_strong_APA_Move_from_scheduled_to_ready, - _Scheduler_strong_APA_Allocate_processor + _Scheduler_strong_APA_Move_from_ready_to_scheduled, + _Scheduler_strong_APA_Allocate_processor, + _Scheduler_strong_APA_Get_idle, + _Scheduler_strong_APA_Release_idle ); curr_node = next_node; @@ -639,13 +707,21 @@ static inline bool _Scheduler_strong_APA_Do_enqueue( curr_strong_node = _Scheduler_strong_APA_Node_downcast( curr_node ); while ( curr_node != lowest_reachable ) { + Thread_Control *next_node_idle; + curr_CPU = curr_strong_node->cpu_to_preempt; next_node = _Scheduler_strong_APA_Get_scheduled( self, curr_CPU ); + next_node_idle = _Scheduler_Release_idle_thread_if_necessary( + next_node, + _Scheduler_strong_APA_Release_idle, + context + ); /* curr_node preempts the next_node; */ _Scheduler_SMP_Preempt( context, curr_node, next_node, + next_node_idle, _Scheduler_strong_APA_Allocate_processor ); @@ -737,13 +813,13 @@ static inline bool _Scheduler_strong_APA_Enqueue( ); } -static inline bool _Scheduler_strong_APA_Enqueue_scheduled( +static inline void _Scheduler_strong_APA_Enqueue_scheduled( Scheduler_Context *context, Scheduler_Node *node, Priority_Control insert_priority ) { - return _Scheduler_SMP_Enqueue_scheduled( + _Scheduler_SMP_Enqueue_scheduled( context, node, insert_priority, @@ -753,7 +829,9 @@ static inline bool _Scheduler_strong_APA_Enqueue_scheduled( _Scheduler_strong_APA_Insert_ready, _Scheduler_SMP_Insert_scheduled, _Scheduler_strong_APA_Move_from_ready_to_scheduled, - _Scheduler_strong_APA_Allocate_processor + _Scheduler_strong_APA_Allocate_processor, + _Scheduler_strong_APA_Get_idle, + _Scheduler_strong_APA_Release_idle ); } @@ -772,7 +850,8 @@ static inline bool _Scheduler_strong_APA_Do_ask_for_help( _Scheduler_SMP_Insert_scheduled, _Scheduler_strong_APA_Move_from_scheduled_to_ready, _Scheduler_strong_APA_Get_lowest_scheduled, - _Scheduler_strong_APA_Allocate_processor + _Scheduler_strong_APA_Allocate_processor, + _Scheduler_strong_APA_Release_idle ); } @@ -809,6 +888,7 @@ void _Scheduler_strong_APA_Yield( context, thread, node, + _Scheduler_strong_APA_Extract_from_scheduled, _Scheduler_strong_APA_Extract_from_ready, _Scheduler_strong_APA_Enqueue, _Scheduler_strong_APA_Enqueue_scheduled @@ -839,7 +919,8 @@ void _Scheduler_strong_APA_Block( _Scheduler_strong_APA_Extract_from_ready, _Scheduler_strong_APA_Get_highest_ready, _Scheduler_strong_APA_Move_from_ready_to_scheduled, - _Scheduler_strong_APA_Allocate_processor + _Scheduler_strong_APA_Allocate_processor, + _Scheduler_strong_APA_Get_idle ); } @@ -856,7 +937,8 @@ void _Scheduler_strong_APA_Unblock( thread, node, _Scheduler_strong_APA_Do_update, - _Scheduler_strong_APA_Enqueue + _Scheduler_strong_APA_Enqueue, + _Scheduler_strong_APA_Release_idle ); } @@ -872,6 +954,7 @@ void _Scheduler_strong_APA_Update_priority( context, thread, node, + _Scheduler_strong_APA_Extract_from_scheduled, _Scheduler_strong_APA_Extract_from_ready, _Scheduler_strong_APA_Do_update, _Scheduler_strong_APA_Enqueue, @@ -925,10 +1008,47 @@ void _Scheduler_strong_APA_Withdraw_node( the_thread, node, next_state, + _Scheduler_strong_APA_Extract_from_scheduled, + _Scheduler_strong_APA_Extract_from_ready, + _Scheduler_strong_APA_Get_highest_ready, + _Scheduler_strong_APA_Move_from_ready_to_scheduled, + _Scheduler_strong_APA_Allocate_processor, + _Scheduler_strong_APA_Get_idle + ); +} + +void _Scheduler_strong_APA_Make_sticky( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *node +) +{ + _Scheduler_SMP_Make_sticky( + scheduler, + the_thread, + node, + _Scheduler_strong_APA_Do_update, + _Scheduler_strong_APA_Enqueue + ); +} + +void _Scheduler_strong_APA_Clean_sticky( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *node +) +{ + _Scheduler_SMP_Clean_sticky( + scheduler, + the_thread, + node, + _Scheduler_SMP_Extract_from_scheduled, _Scheduler_strong_APA_Extract_from_ready, _Scheduler_strong_APA_Get_highest_ready, _Scheduler_strong_APA_Move_from_ready_to_scheduled, - _Scheduler_strong_APA_Allocate_processor + _Scheduler_strong_APA_Allocate_processor, + _Scheduler_strong_APA_Get_idle, + _Scheduler_strong_APA_Release_idle ); } @@ -988,8 +1108,11 @@ Thread_Control *_Scheduler_strong_APA_Remove_processor( return _Scheduler_SMP_Remove_processor( context, cpu, + _Scheduler_strong_APA_Extract_from_scheduled, _Scheduler_strong_APA_Extract_from_ready, - _Scheduler_strong_APA_Enqueue + _Scheduler_strong_APA_Enqueue, + _Scheduler_strong_APA_Get_idle, + _Scheduler_strong_APA_Release_idle ); } @@ -1045,11 +1168,14 @@ Status_Control _Scheduler_strong_APA_Set_affinity( node_base, &local_affinity, _Scheduler_strong_APA_Do_set_affinity, + _Scheduler_strong_APA_Extract_from_scheduled, _Scheduler_strong_APA_Extract_from_ready, _Scheduler_strong_APA_Get_highest_ready, _Scheduler_strong_APA_Move_from_ready_to_scheduled, _Scheduler_strong_APA_Enqueue, - _Scheduler_strong_APA_Allocate_processor + _Scheduler_strong_APA_Allocate_processor, + _Scheduler_strong_APA_Get_idle, + _Scheduler_strong_APA_Release_idle ); return STATUS_SUCCESSFUL; |