summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/schedulerstrongapa.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/src/schedulerstrongapa.c')
-rw-r--r--cpukit/score/src/schedulerstrongapa.c164
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;