summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-05-14 13:50:48 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-05-15 12:18:44 +0200
commitf39f667a69cf5c4bc0dd4555537615022767f0f9 (patch)
treef8a48b3c7bf443001b036ddcab6ed104210e6134 /cpukit/score/include/rtems
parentscore: Add and use _Scheduler_Get_context() (diff)
downloadrtems-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/include/rtems')
-rw-r--r--cpukit/score/include/rtems/score/scheduler.h17
-rw-r--r--cpukit/score/include/rtems/score/schedulercbs.h4
-rw-r--r--cpukit/score/include/rtems/score/scheduleredf.h50
-rw-r--r--cpukit/score/include/rtems/score/scheduleredfimpl.h25
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h70
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriority.h54
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h6
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityimpl.h13
-rw-r--r--cpukit/score/include/rtems/score/schedulerprioritysmp.h23
-rw-r--r--cpukit/score/include/rtems/score/schedulersimple.h71
-rw-r--r--cpukit/score/include/rtems/score/schedulersimpleimpl.h28
-rw-r--r--cpukit/score/include/rtems/score/schedulersimplesmp.h19
-rw-r--r--cpukit/score/include/rtems/score/schedulersmp.h21
-rw-r--r--cpukit/score/include/rtems/score/schedulersmpimpl.h180
-rw-r--r--cpukit/score/include/rtems/score/statesimpl.h17
15 files changed, 198 insertions, 400 deletions
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index 7f0b43ae52..b1e8f8ac4f 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -63,6 +63,14 @@ typedef struct {
/** @see _Scheduler_Unblock() */
void ( *unblock )( const Scheduler_Control *, Thread_Control * );
+ /** @see _Scheduler_Change_priority() */
+ void ( *change_priority )(
+ const Scheduler_Control *,
+ Thread_Control *,
+ Priority_Control,
+ bool
+ );
+
/** @see _Scheduler_Allocate() */
bool ( *allocate )( const Scheduler_Control *, Thread_Control * );
@@ -72,15 +80,6 @@ typedef struct {
/** @see _Scheduler_Update() */
void ( *update )( const Scheduler_Control *, Thread_Control * );
- /** @see _Scheduler_Enqueue() */
- void ( *enqueue )( const Scheduler_Control *, Thread_Control * );
-
- /** @see _Scheduler_Enqueue_first() */
- void ( *enqueue_first )( const Scheduler_Control *, Thread_Control * );
-
- /** @see _Scheduler_Extract() */
- void ( *extract )( const Scheduler_Control *, Thread_Control * );
-
/** @see _Scheduler_Priority_compare() */
int ( *priority_compare )(
Priority_Control,
diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h
index 6cfdfbe959..46db8e5609 100644
--- a/cpukit/score/include/rtems/score/schedulercbs.h
+++ b/cpukit/score/include/rtems/score/schedulercbs.h
@@ -52,12 +52,10 @@ extern "C" {
_Scheduler_EDF_Yield, /* yield entry point */ \
_Scheduler_EDF_Block, /* block entry point */ \
_Scheduler_CBS_Unblock, /* unblock entry point */ \
+ _Scheduler_EDF_Change_priority, /* change priority entry point */ \
_Scheduler_CBS_Allocate, /* allocate entry point */ \
_Scheduler_default_Free, /* free entry point */ \
_Scheduler_EDF_Update, /* update entry point */ \
- _Scheduler_EDF_Enqueue, /* enqueue entry point */ \
- _Scheduler_EDF_Enqueue_first, /* enqueue_first entry point */ \
- _Scheduler_EDF_Extract, /* extract entry point */ \
_Scheduler_EDF_Priority_compare, /* compares two priorities */ \
_Scheduler_CBS_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index 95be94c802..301940c91d 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -45,12 +45,10 @@ extern "C" {
_Scheduler_EDF_Yield, /* yield entry point */ \
_Scheduler_EDF_Block, /* block entry point */ \
_Scheduler_EDF_Unblock, /* unblock entry point */ \
+ _Scheduler_EDF_Change_priority, /* change priority entry point */ \
_Scheduler_EDF_Allocate, /* allocate entry point */ \
_Scheduler_default_Free, /* free entry point */ \
_Scheduler_EDF_Update, /* update entry point */ \
- _Scheduler_EDF_Enqueue, /* enqueue entry point */ \
- _Scheduler_EDF_Enqueue_first, /* enqueue_first entry point */ \
- _Scheduler_EDF_Extract, /* extract entry point */ \
_Scheduler_EDF_Priority_compare, /* compares two priorities */ \
_Scheduler_EDF_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
@@ -187,6 +185,13 @@ void _Scheduler_EDF_Unblock(
Thread_Control *the_thread
);
+void _Scheduler_EDF_Change_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ bool prepend_it
+);
+
/**
* @brief invoked when a thread wishes to voluntarily
* transfer control of the processor to another thread
@@ -208,45 +213,6 @@ void _Scheduler_EDF_Yield(
);
/**
- * @brief Put @a the_thread to the rbtree ready queue.
- *
- * This routine puts @a the_thread to the rbtree ready queue.
- *
- * @param[in] the_thread will be enqueued to the ready queue.
- */
-void _Scheduler_EDF_Enqueue(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
- * @brief Enqueue a thread to the ready queue.
- *
- * This routine puts @a the_thread to the rbtree ready queue.
- * For the EDF scheduler this is the same as @a _Scheduler_EDF_Enqueue.
- *
- * @param[in] the_thread will be enqueued to the ready queue.
- */
-void _Scheduler_EDF_Enqueue_first(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
- * @brief Remove a specific thread from the scheduler's set
- * of ready threads.
- *
- * This routine removes a specific thread from the scheduler's set
- * of ready threads.
- *
- * @param[in] the_thread will be extracted from the ready set.
- */
-void _Scheduler_EDF_Extract(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
* @brief Explicitly compare absolute dedlines (priorities) of threads.
*
* This routine explicitly compares absolute dedlines (priorities) of threads.
diff --git a/cpukit/score/include/rtems/score/scheduleredfimpl.h b/cpukit/score/include/rtems/score/scheduleredfimpl.h
index 8c4cd2c4bd..d424370a45 100644
--- a/cpukit/score/include/rtems/score/scheduleredfimpl.h
+++ b/cpukit/score/include/rtems/score/scheduleredfimpl.h
@@ -44,6 +44,31 @@ RTEMS_INLINE_ROUTINE Scheduler_EDF_Node *_Scheduler_EDF_Node_get(
return (Scheduler_EDF_Node *) _Scheduler_Node_get( the_thread );
}
+RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Enqueue(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+)
+{
+ Scheduler_EDF_Context *context =
+ _Scheduler_EDF_Get_context( scheduler );
+ Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
+
+ _RBTree_Insert( &context->Ready, &node->Node );
+ node->queue_state = SCHEDULER_EDF_QUEUE_STATE_YES;
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Extract(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+)
+{
+ Scheduler_EDF_Context *context =
+ _Scheduler_EDF_Get_context( scheduler );
+ Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
+
+ _RBTree_Extract( &context->Ready, &node->Node );
+}
+
RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Schedule_body(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 2129493b0a..f37a3553ff 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -144,6 +144,35 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Unblock(
}
/**
+ * @brief Propagates a priority change of a thread to the scheduler.
+ *
+ * The caller must ensure that the thread is in the ready state. The caller
+ * must ensure that the priority value actually changed and is not equal to the
+ * current priority value.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] the_thread The thread changing its priority.
+ * @param[in] new_priority The new thread priority.
+ * @param[in] prepend_it In case this is true, then enqueue the thread as the
+ * first of its priority group, otherwise enqueue the thread as the last of its
+ * priority group.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ bool prepend_it
+)
+{
+ ( *scheduler->Operations.change_priority )(
+ scheduler,
+ the_thread,
+ new_priority,
+ prepend_it
+ );
+}
+
+/**
* @brief Scheduler allocate.
*
* This routine allocates @a the_thread->scheduler
@@ -183,47 +212,6 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Update(
}
/**
- * @brief Enqueues a thread as the last of its priority group.
- *
- * @param[in] scheduler The scheduler instance.
- * @param[in] the_thread The thread to enqueue.
- */
-RTEMS_INLINE_ROUTINE void _Scheduler_Enqueue(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-)
-{
- ( *scheduler->Operations.enqueue )( scheduler, the_thread );
-}
-
-/**
- * @brief Enqueues a thread as the first of its priority group.
- *
- * @param[in] scheduler The scheduler instance.
- * @param[in] the_thread The thread to enqueue.
- */
-RTEMS_INLINE_ROUTINE void _Scheduler_Enqueue_first(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-)
-{
- ( *scheduler->Operations.enqueue_first )( scheduler, the_thread );
-}
-
-/**
- * @brief Scheduler extract.
- *
- * This routine extract @a the_thread->scheduler
- */
-RTEMS_INLINE_ROUTINE void _Scheduler_Extract(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-)
-{
- ( *scheduler->Operations.extract )( scheduler, the_thread );
-}
-
-/**
* @brief Compares two priority values.
*
* @param[in] scheduler The scheduler instance.
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index 134dcd715b..b3c1466066 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -52,12 +52,10 @@ extern "C" {
_Scheduler_priority_Yield, /* yield entry point */ \
_Scheduler_priority_Block, /* block entry point */ \
_Scheduler_priority_Unblock, /* unblock entry point */ \
- _Scheduler_default_Allocate, /* allocate entry point */ \
- _Scheduler_default_Free, /* free entry point */ \
+ _Scheduler_priority_Change_priority, /* change priority entry point */ \
+ _Scheduler_default_Allocate, /* allocate entry point */ \
+ _Scheduler_default_Free, /* free entry point */ \
_Scheduler_priority_Update, /* update entry point */ \
- _Scheduler_priority_Enqueue, /* enqueue entry point */ \
- _Scheduler_priority_Enqueue_first, /* enqueue_first entry point */ \
- _Scheduler_priority_Extract, /* extract entry point */ \
_Scheduler_priority_Priority_compare, /* compares two priorities */ \
_Scheduler_default_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
@@ -167,6 +165,13 @@ void _Scheduler_priority_Unblock(
Thread_Control *the_thread
);
+void _Scheduler_priority_Change_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ bool prepend_it
+);
+
/**
* @brief The specified THREAD yields.
*
@@ -192,45 +197,6 @@ void _Scheduler_priority_Yield(
);
/**
- * @brief Puts @a the_thread on to the priority-based ready queue.
- *
- * This routine puts @a the_thread on to the priority-based ready queue.
- *
- * @param[in] the_thread will be enqueued at the TAIL of its priority.
- */
-void _Scheduler_priority_Enqueue(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
- * @brief Puts @a the_thread to the head of the ready queue.
- *
- * This routine puts @a the_thread to the head of the ready queue.
- * For priority-based ready queues, the thread will be the first thread
- * at its priority level.
- *
- * @param[in] the_thread will be enqueued at the HEAD of its priority.
- */
-void _Scheduler_priority_Enqueue_first(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
- * @brief Remove a specific thread from scheduler.
- *
- * This routine removes a specific thread from the scheduler's set
- * of ready threads.
- *
- * @param[in] the_thread will be extracted from the ready set.
- */
-void _Scheduler_priority_Extract(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
* @brief Compare two priorities.
*
* This routine compares two priorities.
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
index e86fd35c6f..c21d066f5b 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
@@ -53,13 +53,11 @@ extern "C" {
_Scheduler_priority_SMP_Schedule, \
_Scheduler_priority_SMP_Yield, \
_Scheduler_priority_SMP_Block, \
- _Scheduler_priority_SMP_Enqueue_fifo, \
+ _Scheduler_priority_SMP_Unblock, \
+ _Scheduler_priority_SMP_Change_priority, \
_Scheduler_priority_affinity_SMP_Allocate, \
_Scheduler_default_Free, \
_Scheduler_priority_SMP_Update, \
- _Scheduler_priority_SMP_Enqueue_fifo, \
- _Scheduler_priority_SMP_Enqueue_lifo, \
- _Scheduler_priority_SMP_Extract, \
_Scheduler_priority_Priority_compare, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
index ae0cd1ad9b..95d8e6ae34 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
@@ -196,28 +196,27 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
}
/**
- * @brief Updates the specified ready queue data according to the current
- * priority of the thread.
+ * @brief Updates the specified ready queue data according to the new priority
+ * value.
*
- * @param[in] the_thread The thread.
* @param[in] ready_queue The ready queue.
+ * @param[in] new_priority The new priority.
* @param[in] bit_map The priority bit map of the scheduler instance.
* @param[in] ready_queues The ready queues of the scheduler instance.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_update(
- Thread_Control *the_thread,
Scheduler_priority_Ready_queue *ready_queue,
+ Priority_Control new_priority,
Priority_bit_map_Control *bit_map,
Chain_Control *ready_queues
)
{
- Priority_Control priority = the_thread->current_priority;
- ready_queue->ready_chain = &ready_queues[ priority ];
+ ready_queue->ready_chain = &ready_queues[ new_priority ];
_Priority_bit_map_Initialize_information(
bit_map,
&ready_queue->Priority_map,
- priority
+ new_priority
);
}
diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
index 3e7d22f81d..a22b323e93 100644
--- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -82,13 +82,11 @@ typedef struct {
_Scheduler_priority_SMP_Schedule, \
_Scheduler_priority_SMP_Yield, \
_Scheduler_priority_SMP_Block, \
- _Scheduler_priority_SMP_Enqueue_fifo, \
+ _Scheduler_priority_SMP_Unblock, \
+ _Scheduler_priority_SMP_Change_priority, \
_Scheduler_priority_SMP_Allocate, \
_Scheduler_default_Free, \
_Scheduler_priority_SMP_Update, \
- _Scheduler_priority_SMP_Enqueue_fifo, \
- _Scheduler_priority_SMP_Enqueue_lifo, \
- _Scheduler_priority_SMP_Extract, \
_Scheduler_priority_Priority_compare, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
@@ -114,22 +112,19 @@ void _Scheduler_priority_SMP_Block(
Thread_Control *thread
);
-void _Scheduler_priority_SMP_Update(
+void _Scheduler_priority_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread
);
-void _Scheduler_priority_SMP_Enqueue_fifo(
+void _Scheduler_priority_SMP_Change_priority(
const Scheduler_Control *scheduler,
- Thread_Control *thread
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ bool prepend_it
);
-void _Scheduler_priority_SMP_Enqueue_lifo(
- const Scheduler_Control *scheduler,
- Thread_Control *thread
-);
-
-void _Scheduler_priority_SMP_Extract(
+void _Scheduler_priority_SMP_Update(
const Scheduler_Control *scheduler,
Thread_Control *thread
);
diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h
index 213bbb2709..6b59a0ab9e 100644
--- a/cpukit/score/include/rtems/score/schedulersimple.h
+++ b/cpukit/score/include/rtems/score/schedulersimple.h
@@ -42,12 +42,10 @@ extern "C" {
_Scheduler_simple_Yield, /* yield entry point */ \
_Scheduler_simple_Block, /* block entry point */ \
_Scheduler_simple_Unblock, /* unblock entry point */ \
+ _Scheduler_simple_Change_priority, /* change priority entry point */ \
_Scheduler_default_Allocate, /* allocate entry point */ \
_Scheduler_default_Free, /* free entry point */ \
_Scheduler_default_Update, /* update entry point */ \
- _Scheduler_simple_Enqueue, /* enqueue entry point */ \
- _Scheduler_simple_Enqueue_first, /* enqueue_first entry point */ \
- _Scheduler_simple_Extract, /* extract entry point */ \
_Scheduler_priority_Priority_compare, /* compares two priorities */ \
_Scheduler_default_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
@@ -136,70 +134,11 @@ void _Scheduler_simple_Unblock(
Thread_Control *the_thread
);
-/**
- * @brief Removes a simple-priority-based thread from a simple queue.
- *
- * This routine removes a specific thread from the specified
- * simple-based ready queue.
- *
- * @param[in] the_thread is the thread to be blocked
- */
-void _Scheduler_simple_Extract(
+void _Scheduler_simple_Change_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
- * @brief Puts simple-priority-based thread onto the ready queue.
- *
- * This routine puts @a the_thread on to the ready queue.
- *
- * @param[in] the_thread is the thread to be enqueued
- */
-void _Scheduler_simple_Enqueue(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
- * @brief Put simple-priority-based @a the_thread to
- * the head of the ready queue.
- *
- * This routine puts @a the_thread to the head of the ready queue.
- * The thread will be the first thread at its priority level.
- *
- * @param[in] the_thread is the thread to be blocked
- */
-void _Scheduler_simple_Enqueue_first(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
- * _Scheduler_simple_Ready_queue_enqueue
- *
- * This routine puts @a the_thread on the ready queue
- * at the end of its priority group.
- *
- * @param[in] the_thread - pointer to a thread control block
- */
-void _Scheduler_simple_Ready_queue_enqueue(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
- * @brief Puts simple-priority-based @a the_thread on to the ready queue
- * at the beginning of its priority group.
- *
- * This routine puts @a the_thread on to the ready queue
- * at the beginning of its priority group.
- *
- * @param[in] the_thread - pointer to a thread control block
- */
-void _Scheduler_simple_Ready_queue_enqueue_first(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ bool prepend_it
);
/**@}*/
diff --git a/cpukit/score/include/rtems/score/schedulersimpleimpl.h b/cpukit/score/include/rtems/score/schedulersimpleimpl.h
index c256071a8f..b73a1b2c78 100644
--- a/cpukit/score/include/rtems/score/schedulersimpleimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersimpleimpl.h
@@ -38,24 +38,6 @@ RTEMS_INLINE_ROUTINE Scheduler_simple_Context *
return (Scheduler_simple_Context *) _Scheduler_Get_context( scheduler );
}
-/**
- * This routine puts @a the_thread on to the ready queue.
- *
- * @param[in] the_ready_queue is a pointer to the ready queue head
- * @param[in] the_thread is the thread to be blocked
- */
-RTEMS_INLINE_ROUTINE void _Scheduler_simple_Ready_queue_requeue(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-)
-{
- /* extract */
- _Chain_Extract_unprotected( &the_thread->Object.Node );
-
- /* enqueue */
- _Scheduler_simple_Ready_queue_enqueue( scheduler, the_thread );
-}
-
RTEMS_INLINE_ROUTINE bool _Scheduler_simple_Insert_priority_lifo_order(
const Chain_Node *to_insert,
const Chain_Node *next
@@ -102,6 +84,16 @@ RTEMS_INLINE_ROUTINE void _Scheduler_simple_Insert_priority_fifo(
);
}
+RTEMS_INLINE_ROUTINE void _Scheduler_simple_Extract(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+)
+{
+ (void) scheduler;
+
+ _Chain_Extract_unprotected( &the_thread->Object.Node );
+}
+
RTEMS_INLINE_ROUTINE void _Scheduler_simple_Schedule_body(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h
index 1e712251c8..32e998d59a 100644
--- a/cpukit/score/include/rtems/score/schedulersimplesmp.h
+++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h
@@ -63,13 +63,11 @@ typedef struct {
_Scheduler_simple_SMP_Schedule, \
_Scheduler_simple_SMP_Yield, \
_Scheduler_simple_SMP_Block, \
- _Scheduler_simple_SMP_Enqueue_priority_fifo, \
+ _Scheduler_simple_SMP_Unblock, \
+ _Scheduler_simple_SMP_Change_priority, \
_Scheduler_simple_SMP_Allocate, \
_Scheduler_default_Free, \
_Scheduler_default_Update, \
- _Scheduler_simple_SMP_Enqueue_priority_fifo, \
- _Scheduler_simple_SMP_Enqueue_priority_lifo, \
- _Scheduler_simple_SMP_Extract, \
_Scheduler_priority_Priority_compare, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
@@ -90,19 +88,16 @@ void _Scheduler_simple_SMP_Block(
Thread_Control *thread
);
-void _Scheduler_simple_SMP_Enqueue_priority_fifo(
+void _Scheduler_simple_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread
);
-void _Scheduler_simple_SMP_Enqueue_priority_lifo(
+void _Scheduler_simple_SMP_Change_priority(
const Scheduler_Control *scheduler,
- Thread_Control *thread
-);
-
-void _Scheduler_simple_SMP_Extract(
- const Scheduler_Control *scheduler,
- Thread_Control *thread
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ bool prepend_it
);
void _Scheduler_simple_SMP_Yield(
diff --git a/cpukit/score/include/rtems/score/schedulersmp.h b/cpukit/score/include/rtems/score/schedulersmp.h
index ee1b087ff8..db8798dcd0 100644
--- a/cpukit/score/include/rtems/score/schedulersmp.h
+++ b/cpukit/score/include/rtems/score/schedulersmp.h
@@ -69,8 +69,8 @@ typedef enum {
*
* A scheduler node is scheduled if the corresponding thread is ready and the
* scheduler allocated a processor for it. A scheduled node is assigned to
- * exactly one processor. The sum of scheduled and in the air nodes equals
- * the processor count owned by a scheduler instance.
+ * exactly one processor. The count of scheduled nodes in this scheduler
+ * instance equals the processor count owned by the scheduler instance.
*/
SCHEDULER_SMP_NODE_SCHEDULED,
@@ -80,22 +80,7 @@ typedef enum {
* A scheduler node is ready if the corresponding thread is ready and the
* scheduler did not allocate a processor for it.
*/
- SCHEDULER_SMP_NODE_READY,
-
- /**
- * @brief This scheduler node is in the air.
- *
- * A scheduled node is in the air if it has an allocated processor and the
- * corresponding thread is in a transient state. Such a node is not an
- * element of the set of scheduled nodes. The extract operation on a
- * scheduled node will produce a scheduler node in the air (see also
- * _Thread_Set_transient()). The next enqueue or schedule operation will
- * decide what to do based on this state indication. It can either place the
- * scheduler node back on the set of scheduled nodes and the thread can keep
- * its allocated processor, or it can take the processor away from the thread
- * and give the processor to another thread of higher priority.
- */
- SCHEDULER_SMP_NODE_IN_THE_AIR
+ SCHEDULER_SMP_NODE_READY
} Scheduler_SMP_Node_state;
/**
diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h
index 161f742d18..365edbb845 100644
--- a/cpukit/score/include/rtems/score/schedulersmpimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h
@@ -37,14 +37,12 @@ extern "C" {
*
* The scheduler nodes can be in four states
* - @ref SCHEDULER_SMP_NODE_BLOCKED,
- * - @ref SCHEDULER_SMP_NODE_SCHEDULED,
- * - @ref SCHEDULER_SMP_NODE_READY, and
- * - @ref SCHEDULER_SMP_NODE_IN_THE_AIR.
+ * - @ref SCHEDULER_SMP_NODE_SCHEDULED, and
+ * - @ref SCHEDULER_SMP_NODE_READY.
*
- * State transitions are triggered via basic three operations
- * - _Scheduler_SMP_Enqueue_ordered(),
- * - _Scheduler_SMP_Extract(), and
- * - _Scheduler_SMP_Schedule().
+ * State transitions are triggered via basic operations
+ * - _Scheduler_SMP_Enqueue_ordered(), and
+ * - _Scheduler_SMP_Block().
*
* @dot
* digraph {
@@ -53,39 +51,26 @@ extern "C" {
* bs [label="BLOCKED"];
* ss [label="SCHEDULED", fillcolor="green"];
* rs [label="READY", fillcolor="red"];
- * as [label="IN THE AIR", fillcolor="orange"];
*
* edge [label="enqueue"];
* edge [fontcolor="darkgreen", color="darkgreen"];
*
* bs -> ss;
- * as -> ss;
*
- * edge [label="enqueue"];
* edge [fontcolor="red", color="red"];
*
* bs -> rs;
- * as -> rs;
*
* edge [label="enqueue other"];
*
* ss -> rs;
*
- * edge [label="schedule"];
- * edge [fontcolor="black", color="black"];
- *
- * as -> bs;
- *
- * edge [label="extract"];
- * edge [fontcolor="brown", color="brown"];
- *
- * ss -> as;
- *
+ * edge [label="block"];
* edge [fontcolor="black", color="black"];
*
* rs -> bs;
*
- * edge [label="enqueue other\nschedule other"];
+ * edge [label="block other"];
* edge [fontcolor="darkgreen", color="darkgreen"];
*
* rs -> ss;
@@ -216,38 +201,7 @@ extern "C" {
* }
* @enddot
*
- * Lets do something with A. This can be a blocking operation or a priority
- * change. For this an extract operation is performed first.
- *
- * @dot
- * digraph {
- * node [style="filled"];
- * edge [dir="none"];
- *
- * subgraph {
- * rank = same;
- *
- * b [label="B (2)", fillcolor="green"];
- * a [label="A (1)", fillcolor="orange"];
- * c [label="C (3)", fillcolor="red"];
- * i [label="I (5)", fillcolor="red"];
- * j [label="J (5)", fillcolor="red"];
- * c -> i -> j;
- * }
- *
- * subgraph {
- * rank = same;
- *
- * p0 [label="PROCESSOR 0", shape="box"];
- * p1 [label="PROCESSOR 1", shape="box"];
- * }
- *
- * b -> p0;
- * a -> p1;
- * }
- * @enddot
- *
- * Lets change the priority of thread A to 4 and enqueue it.
+ * Lets change the priority of thread A to 4.
*
* @dot
* digraph {
@@ -278,8 +232,9 @@ extern "C" {
* }
* @enddot
*
- * Alternatively we can also do a blocking operation with thread A. In this
- * case schedule will be called.
+ * Now perform a blocking operation with thread B. Please note that thread A
+ * migrated now from processor 0 to processor 1 and thread C still executes on
+ * processor 1.
*
* @dot
* digraph {
@@ -289,12 +244,12 @@ extern "C" {
* subgraph {
* rank = same;
*
- * b [label="B (2)", fillcolor="green"];
* c [label="C (3)", fillcolor="green"];
+ * a [label="A (4)", fillcolor="green"];
* i [label="I (5)", fillcolor="red"];
* j [label="J (5)", fillcolor="red"];
- * a [label="A (1)"];
- * b -> c;
+ * b [label="B (2)"];
+ * c -> a;
* i -> j;
* }
*
@@ -305,7 +260,7 @@ extern "C" {
* p1 [label="PROCESSOR 1", shape="box"];
* }
*
- * b -> p0;
+ * a -> p0;
* c -> p1;
* }
* @enddot
@@ -332,6 +287,18 @@ typedef void ( *Scheduler_SMP_Move )(
Thread_Control *thread_to_move
);
+typedef void ( *Scheduler_SMP_Update )(
+ Scheduler_Context *context,
+ Scheduler_Node *node,
+ Priority_Control new_priority
+);
+
+typedef void ( *Scheduler_SMP_Enqueue )(
+ Scheduler_Context *context,
+ Thread_Control *thread_to_enqueue,
+ bool has_processor_allocated
+);
+
static inline Scheduler_SMP_Context *_Scheduler_SMP_Get_self(
Scheduler_Context *context
)
@@ -360,7 +327,7 @@ static inline void _Scheduler_SMP_Node_initialize(
node->state = SCHEDULER_SMP_NODE_BLOCKED;
}
-extern const bool _Scheduler_SMP_Node_valid_state_changes[ 4 ][ 4 ];
+extern const bool _Scheduler_SMP_Node_valid_state_changes[ 3 ][ 3 ];
static inline void _Scheduler_SMP_Node_change_state(
Scheduler_SMP_Node *node,
@@ -467,6 +434,7 @@ static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
*
* @param[in] context The scheduler instance context.
* @param[in] thread The thread to enqueue.
+ * @param[in] has_processor_allocated The thread has a processor allocated.
* @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
@@ -481,6 +449,7 @@ static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
static inline void _Scheduler_SMP_Enqueue_ordered(
Scheduler_Context *context,
Thread_Control *thread,
+ bool has_processor_allocated,
Chain_Node_order order,
Scheduler_SMP_Get_highest_ready get_highest_ready,
Scheduler_SMP_Insert insert_ready,
@@ -492,19 +461,18 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
- if ( node->state == SCHEDULER_SMP_NODE_IN_THE_AIR ) {
+ if ( has_processor_allocated) {
Thread_Control *highest_ready = ( *get_highest_ready )( &self->Base );
+ _Assert( highest_ready != NULL);
+
/*
* 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 )
- ) {
+ if ( !( *order )( &thread->Object.Node, &highest_ready->Object.Node ) ) {
_Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
_Scheduler_SMP_Allocate_processor( self, highest_ready, thread );
( *insert_ready )( &self->Base, thread );
@@ -517,14 +485,9 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
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 )
- ) {
+ _Assert( lowest_scheduled != NULL);
+
+ if ( ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) {
Scheduler_SMP_Node *lowest_scheduled_node =
_Scheduler_SMP_Node_get( lowest_scheduled );
@@ -542,6 +505,11 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
}
}
+static inline void _Scheduler_SMP_Extract_from_scheduled( Thread_Control *thread )
+{
+ _Chain_Extract_unprotected( &thread->Object.Node );
+}
+
static inline void _Scheduler_SMP_Schedule_highest_ready(
Scheduler_Context *context,
Thread_Control *victim,
@@ -558,25 +526,31 @@ static inline void _Scheduler_SMP_Schedule_highest_ready(
}
/**
- * @brief Finalize a scheduling operation.
+ * @brief Blocks a thread.
*
* @param[in] context The scheduler instance context.
* @param[in] thread The thread of the scheduling operation.
+ * @param[in] extract_from_ready Function to extract a node from the set of
+ * ready nodes.
* @param[in] get_highest_ready Function to get the highest ready node.
* @param[in] move_from_ready_to_scheduled Function to move a node from the set
* of ready nodes to the set of scheduled nodes.
*/
-static inline void _Scheduler_SMP_Schedule(
+static inline void _Scheduler_SMP_Block(
Scheduler_Context *context,
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_Node *node = _Scheduler_SMP_Node_get( thread );
+ bool is_scheduled = node->state == SCHEDULER_SMP_NODE_SCHEDULED;
+
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
- if ( node->state == SCHEDULER_SMP_NODE_IN_THE_AIR ) {
- _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
+ if ( is_scheduled ) {
+ _Scheduler_SMP_Extract_from_scheduled( thread );
_Scheduler_SMP_Schedule_highest_ready(
context,
@@ -584,42 +558,38 @@ static inline void _Scheduler_SMP_Schedule(
get_highest_ready,
move_from_ready_to_scheduled
);
+ } else {
+ ( *extract_from_ready )( context, thread );
}
}
-static inline void _Scheduler_SMP_Block(
+static inline void _Scheduler_SMP_Change_priority(
Scheduler_Context *context,
Thread_Control *thread,
- Scheduler_SMP_Extract extract,
- Scheduler_SMP_Get_highest_ready get_highest_ready,
- Scheduler_SMP_Move move_from_ready_to_scheduled
+ Priority_Control new_priority,
+ bool prepend_it,
+ Scheduler_SMP_Extract extract_from_ready,
+ Scheduler_SMP_Update update,
+ Scheduler_SMP_Enqueue enqueue_fifo,
+ Scheduler_SMP_Enqueue enqueue_lifo
)
{
- ( *extract )( context, thread );
+ Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
+ bool has_processor_allocated = node->state == SCHEDULER_SMP_NODE_SCHEDULED;
- _Scheduler_SMP_Schedule(
- context,
- thread,
- get_highest_ready,
- move_from_ready_to_scheduled
- );
-}
+ if ( has_processor_allocated ) {
+ _Scheduler_SMP_Extract_from_scheduled( thread );
+ } else {
+ ( *extract_from_ready )( context, thread );
+ }
-/**
- * @brief Extracts a thread from the set of scheduled or ready nodes.
- *
- * @param[in] context The scheduler instance context.
- * @param[in] thread The thread to extract.
- * @param[in] extract Function to extract a node from the set of scheduled or
- * ready nodes.
- */
-static inline void _Scheduler_SMP_Extract(
- Scheduler_Context *context,
- Thread_Control *thread,
- Scheduler_SMP_Extract extract
-)
-{
- ( *extract )( context, thread );
+ ( *update )( context, &node->Base, new_priority );
+
+ if ( prepend_it ) {
+ ( *enqueue_lifo )( context, thread, has_processor_allocated );
+ } else {
+ ( *enqueue_fifo )( context, thread, has_processor_allocated );
+ }
}
static inline void _Scheduler_SMP_Insert_scheduled_lifo(
diff --git a/cpukit/score/include/rtems/score/statesimpl.h b/cpukit/score/include/rtems/score/statesimpl.h
index 00d1092dfb..4251b3c84d 100644
--- a/cpukit/score/include/rtems/score/statesimpl.h
+++ b/cpukit/score/include/rtems/score/statesimpl.h
@@ -42,8 +42,6 @@ extern "C" {
#define STATES_DORMANT 0x00001
/** This macro corresponds to a task being suspended. */
#define STATES_SUSPENDED 0x00002
-/** This macro corresponds to a task being in an internal state transition. */
-#define STATES_TRANSIENT 0x00004
/** This macro corresponds to a task which is waiting for a timeout. */
#define STATES_DELAYING 0x00008
/** This macro corresponds to a task waiting until a specific TOD. */
@@ -215,21 +213,6 @@ RTEMS_INLINE_ROUTINE bool _States_Is_suspended (
}
/**
- * This function returns true if the TRANSIENT state is set in
- * the_states, and false otherwise.
- *
- * @param[in] the_states is the task state set to test
- *
- * @return This method returns true if the desired state condition is set.
- */
-RTEMS_INLINE_ROUTINE bool _States_Is_transient (
- States_Control the_states
-)
-{
- return (the_states & STATES_TRANSIENT);
-}
-
-/**
* This function returns true if the DELAYING state is set in
* the_states, and false otherwise.
*