summaryrefslogtreecommitdiff
path: root/cpukit/score/include/rtems/score/schedulersmpimpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/include/rtems/score/schedulersmpimpl.h')
-rw-r--r--cpukit/score/include/rtems/score/schedulersmpimpl.h113
1 files changed, 80 insertions, 33 deletions
diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h
index bb7c41e8c0..c3b0ab3864 100644
--- a/cpukit/score/include/rtems/score/schedulersmpimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h
@@ -275,7 +275,14 @@ extern "C" {
*/
typedef Thread_Control *( *Scheduler_SMP_Get_highest_ready )(
- Scheduler_Context *context
+ Scheduler_Context *context,
+ Thread_Control *blocking
+);
+
+typedef Thread_Control *( *Scheduler_SMP_Get_lowest_scheduled )(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Chain_Node_order order
);
typedef void ( *Scheduler_SMP_Extract )(
@@ -304,6 +311,12 @@ typedef void ( *Scheduler_SMP_Enqueue )(
Thread_Control *thread_to_enqueue
);
+typedef void ( *Scheduler_SMP_Allocate_processor )(
+ Scheduler_SMP_Context *self,
+ Thread_Control *scheduled,
+ Thread_Control *victim
+);
+
static inline Scheduler_SMP_Context *_Scheduler_SMP_Get_self(
Scheduler_Context *context
)
@@ -382,7 +395,7 @@ static inline void _Scheduler_SMP_Update_heir(
}
}
-static inline void _Scheduler_SMP_Allocate_processor(
+static void _Scheduler_SMP_Allocate_processor(
Scheduler_SMP_Context *self,
Thread_Control *scheduled,
Thread_Control *victim
@@ -420,10 +433,13 @@ static inline void _Scheduler_SMP_Allocate_processor(
}
}
-static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
- Scheduler_SMP_Context *self
+static Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
+ Scheduler_Context *context,
+ Thread_Control *filter,
+ Chain_Node_order order
)
{
+ Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
Thread_Control *lowest_ready = NULL;
Chain_Control *scheduled = &self->Scheduled;
@@ -431,6 +447,12 @@ static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
lowest_ready = (Thread_Control *) _Chain_Last( scheduled );
}
+ /*
+ * _Scheduler_SMP_Enqueue_ordered() assumes that get_lowest_scheduled
+ * helpers may return NULL. But this method never should.
+ */
+ _Assert( lowest_ready != NULL );
+
return lowest_ready;
}
@@ -443,28 +465,45 @@ static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
* @param[in] thread The thread to enqueue.
* @param[in] order The order function.
* @param[in] insert_ready Function to insert a node into the set of ready
- * nodes.
+ * nodes.
* @param[in] insert_scheduled Function to insert a node into the set of
- * scheduled nodes.
+ * scheduled nodes.
* @param[in] move_from_scheduled_to_ready Function to move a node from the set
- * of scheduled nodes to the set of ready nodes.
+ * of scheduled nodes to the set of ready nodes.
+ * @param[in] get_lowest_scheduled Function to select the thread from the
+ * scheduled nodes to replace. It may not be possible to find one.
+ * @param[in] allocate_processor Function to allocate a processor to a thread
+ * based on the rules of the scheduler.
*/
static inline void _Scheduler_SMP_Enqueue_ordered(
- Scheduler_Context *context,
- Thread_Control *thread,
- Chain_Node_order order,
- Scheduler_SMP_Insert insert_ready,
- Scheduler_SMP_Insert insert_scheduled,
- Scheduler_SMP_Move move_from_scheduled_to_ready
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Chain_Node_order order,
+ Scheduler_SMP_Insert insert_ready,
+ Scheduler_SMP_Insert insert_scheduled,
+ Scheduler_SMP_Move move_from_scheduled_to_ready,
+ Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
)
{
Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
Thread_Control *lowest_scheduled =
- _Scheduler_SMP_Get_lowest_scheduled( self );
+ ( *get_lowest_scheduled )( context, thread, order );
- _Assert( lowest_scheduled != NULL );
+ /*
+ * get_lowest_scheduled can return a NULL if no scheduled threads
+ * should be removed from their processor based on the selection
+ * criteria. For example, this can occur when the affinity of the
+ * thread being enqueued schedules it against higher priority threads.
+ * A low priority thread with affinity can only consider the threads
+ * which are on the cores if has affinity for.
+ *
+ * The get_lowest_scheduled helper should assert on not returning NULL
+ * if that is not possible for that scheduler.
+ */
- if ( ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) {
+ if ( lowest_scheduled &&
+ ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) {
Scheduler_SMP_Node *lowest_scheduled_node =
_Scheduler_SMP_Node_get( lowest_scheduled );
@@ -472,7 +511,7 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
lowest_scheduled_node,
SCHEDULER_SMP_NODE_READY
);
- _Scheduler_SMP_Allocate_processor( self, thread, lowest_scheduled );
+ ( *allocate_processor )( self, thread, lowest_scheduled );
( *insert_scheduled )( &self->Base, thread );
( *move_from_scheduled_to_ready )( &self->Base, lowest_scheduled );
} else {
@@ -489,25 +528,29 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
* @param[in] order The order function.
* @param[in] get_highest_ready Function to get the highest ready node.
* @param[in] insert_ready Function to insert a node into the set of ready
- * nodes.
+ * nodes.
* @param[in] insert_scheduled Function to insert a node into the set of
- * scheduled nodes.
+ * scheduled nodes.
* @param[in] move_from_ready_to_scheduled Function to move a node from the set
- * of ready nodes to the set of scheduled nodes.
+ * of ready nodes to the set of scheduled nodes.
+ * @param[in] allocate_processor Function to allocate a processor to a thread
+ * based on the rules of the scheduler.
*/
static inline void _Scheduler_SMP_Enqueue_scheduled_ordered(
Scheduler_Context *context,
- Thread_Control *thread,
- Chain_Node_order order,
- Scheduler_SMP_Get_highest_ready get_highest_ready,
- Scheduler_SMP_Insert insert_ready,
- Scheduler_SMP_Insert insert_scheduled,
- Scheduler_SMP_Move move_from_ready_to_scheduled
+ Thread_Control *thread,
+ Chain_Node_order order,
+ Scheduler_SMP_Get_highest_ready get_highest_ready,
+ Scheduler_SMP_Insert insert_ready,
+ Scheduler_SMP_Insert insert_scheduled,
+ Scheduler_SMP_Move move_from_ready_to_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
)
{
Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
- Thread_Control *highest_ready = ( *get_highest_ready )( &self->Base );
+ Thread_Control *highest_ready =
+ ( *get_highest_ready )( &self->Base, thread );
_Assert( highest_ready != NULL );
@@ -519,7 +562,7 @@ static inline void _Scheduler_SMP_Enqueue_scheduled_ordered(
( *insert_scheduled )( &self->Base, thread );
} else {
_Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
- _Scheduler_SMP_Allocate_processor( self, highest_ready, thread );
+ ( *allocate_processor) ( self, highest_ready, thread );
( *insert_ready )( &self->Base, thread );
( *move_from_ready_to_scheduled )( &self->Base, highest_ready );
}
@@ -536,13 +579,15 @@ static inline void _Scheduler_SMP_Schedule_highest_ready(
Scheduler_Context *context,
Thread_Control *victim,
Scheduler_SMP_Get_highest_ready get_highest_ready,
- Scheduler_SMP_Move move_from_ready_to_scheduled
+ Scheduler_SMP_Move move_from_ready_to_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
)
{
Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
- Thread_Control *highest_ready = ( *get_highest_ready )( &self->Base );
+ Thread_Control *highest_ready =
+ ( *get_highest_ready )( &self->Base, victim );
- _Scheduler_SMP_Allocate_processor( self, highest_ready, victim );
+ ( *allocate_processor )( self, highest_ready, victim );
( *move_from_ready_to_scheduled )( &self->Base, highest_ready );
}
@@ -563,7 +608,8 @@ static inline void _Scheduler_SMP_Block(
Thread_Control *thread,
Scheduler_SMP_Extract extract_from_ready,
Scheduler_SMP_Get_highest_ready get_highest_ready,
- Scheduler_SMP_Move move_from_ready_to_scheduled
+ Scheduler_SMP_Move move_from_ready_to_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
)
{
Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
@@ -578,7 +624,8 @@ static inline void _Scheduler_SMP_Block(
context,
thread,
get_highest_ready,
- move_from_ready_to_scheduled
+ move_from_ready_to_scheduled,
+ allocate_processor
);
} else {
( *extract_from_ready )( context, thread );