summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-08 22:22:46 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-22 14:44:56 +0200
commit9bfad8cd519f17cbb26a672868169fcd304d5bd5 (patch)
tree3a07add3fb0cdf47fe4d5c9432ad931429c05d65 /cpukit/score/include
parentscore: Move _RBTree_Find() (diff)
downloadrtems-9bfad8cd519f17cbb26a672868169fcd304d5bd5.tar.bz2
score: Add thread priority to scheduler nodes
The thread priority is manifest in two independent areas. One area is the user visible thread priority along with a potential thread queue. The other is the scheduler. Currently, a thread priority update via _Thread_Change_priority() first updates the user visble thread priority and the thread queue, then the scheduler is notified if necessary. The priority is passed to the scheduler via a local variable. A generation counter ensures that the scheduler discards out-of-date priorities. This use of a local variable ties the update in these two areas close together. For later enhancements and the OMIP locking protocol implementation we need more flexibility. Add a thread priority information block to Scheduler_Node and synchronize priority value updates via a sequence lock on SMP configurations. Update #2556.
Diffstat (limited to '')
-rw-r--r--cpukit/score/include/rtems/score/scheduler.h74
-rw-r--r--cpukit/score/include/rtems/score/schedulercbs.h6
-rw-r--r--cpukit/score/include/rtems/score/scheduleredf.h27
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h133
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriority.h30
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h17
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityimpl.h1
-rw-r--r--cpukit/score/include/rtems/score/schedulerprioritysmp.h18
-rw-r--r--cpukit/score/include/rtems/score/schedulersimple.h9
-rw-r--r--cpukit/score/include/rtems/score/schedulersimplesmp.h18
-rw-r--r--cpukit/score/include/rtems/score/schedulersmpimpl.h53
-rw-r--r--cpukit/score/include/rtems/score/schedulerstrongapa.h18
-rw-r--r--cpukit/score/include/rtems/score/thread.h16
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h5
14 files changed, 217 insertions, 208 deletions
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index 73e2873de6..9f31d7ad1f 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -20,6 +20,7 @@
#define _RTEMS_SCORE_SCHEDULER_H
#include <rtems/score/priority.h>
+#include <rtems/score/smplockseq.h>
#include <rtems/score/thread.h>
#if defined(__RTEMS_HAVE_SYS_CPUSET_H__) && defined(RTEMS_SMP)
#include <sys/cpuset.h>
@@ -83,12 +84,10 @@ typedef struct {
Thread_Control *
);
- /** @see _Scheduler_Change_priority() */
- Scheduler_Void_or_thread ( *change_priority )(
+ /** @see _Scheduler_Update_priority() */
+ Scheduler_Void_or_thread ( *update_priority )(
const Scheduler_Control *,
- Thread_Control *,
- Priority_Control,
- bool
+ Thread_Control *
);
/** @see _Scheduler_Map_priority() */
@@ -129,18 +128,15 @@ typedef struct {
#endif
/** @see _Scheduler_Node_initialize() */
- void ( *node_initialize )( const Scheduler_Control *, Thread_Control * );
-
- /** @see _Scheduler_Node_destroy() */
- void ( *node_destroy )( const Scheduler_Control *, Thread_Control * );
-
- /** @see _Scheduler_Update_priority() */
- void ( *update_priority )(
+ void ( *node_initialize )(
const Scheduler_Control *,
Thread_Control *,
Priority_Control
);
+ /** @see _Scheduler_Node_destroy() */
+ void ( *node_destroy )( const Scheduler_Control *, Thread_Control * );
+
/** @see _Scheduler_Release_job() */
void ( *release_job ) (
const Scheduler_Control *,
@@ -338,6 +334,41 @@ struct Scheduler_Node {
*/
Thread_Control *accepts_help;
#endif
+
+ /**
+ * @brief The thread priority information used by the scheduler.
+ *
+ * The thread priority is manifest in two independent areas. One area is the
+ * user visible thread priority along with a potential thread queue. The
+ * other is the scheduler. During a thread priority change, the user visible
+ * thread priority and the thread queue are first updated and the thread
+ * priority value here is changed. Once this is done the scheduler is
+ * notified via the update priority operation, so that it can update its
+ * internal state and honour a new thread priority value.
+ */
+ struct {
+ /**
+ * @brief The thread priority value of this scheduler node.
+ *
+ * The producer of this value is _Thread_Change_priority(). The consumer
+ * is the scheduler via the unblock and update priority operations.
+ */
+ Priority_Control value;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Sequence lock to synchronize priority value updates.
+ */
+ SMP_sequence_lock_Control Lock;
+#endif
+
+ /**
+ * @brief In case a priority update is necessary and 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.
+ */
+ bool prepend_it;
+ } Priority;
};
/**
@@ -464,14 +495,16 @@ void _Scheduler_default_Schedule(
);
/**
- * @brief Does nothing.
+ * @brief Performs the scheduler base node initialization.
*
* @param[in] scheduler Unused.
* @param[in] the_thread Unused.
+ * @param[in] priority The thread priority.
*/
void _Scheduler_default_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Priority_Control priority
);
/**
@@ -490,19 +523,6 @@ void _Scheduler_default_Node_destroy(
*
* @param[in] scheduler Unused.
* @param[in] the_thread Unused.
- * @param[in] new_priority Unused.
- */
-void _Scheduler_default_Update_priority(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority
-);
-
-/**
- * @brief Does nothing.
- *
- * @param[in] scheduler Unused.
- * @param[in] the_thread Unused.
* @param[in] deadline Unused.
*/
void _Scheduler_default_Release_job(
diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h
index fea10d54ce..91e69d09da 100644
--- a/cpukit/score/include/rtems/score/schedulercbs.h
+++ b/cpukit/score/include/rtems/score/schedulercbs.h
@@ -54,13 +54,12 @@ 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_EDF_Update_priority, /* update priority entry point */ \
_Scheduler_EDF_Map_priority, /* map priority entry point */ \
_Scheduler_EDF_Unmap_priority, /* unmap priority entry point */ \
SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
_Scheduler_CBS_Node_initialize, /* node initialize entry point */ \
_Scheduler_default_Node_destroy, /* node destroy entry point */ \
- _Scheduler_EDF_Update_priority, /* update priority entry point */ \
_Scheduler_CBS_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
_Scheduler_default_Start_idle /* start idle entry point */ \
@@ -346,7 +345,8 @@ void _Scheduler_CBS_Budget_callout(
*/
void _Scheduler_CBS_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Priority_Control priority
);
#ifdef __cplusplus
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index 4eb5f49d4b..e1dce6f395 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -47,13 +47,12 @@ 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_Update_priority, /* update priority entry point */ \
_Scheduler_EDF_Map_priority, /* map priority entry point */ \
_Scheduler_EDF_Unmap_priority, /* unmap priority entry point */ \
SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
_Scheduler_EDF_Node_initialize, /* node initialize entry point */ \
_Scheduler_default_Node_destroy, /* node destroy entry point */ \
- _Scheduler_EDF_Update_priority, /* update priority entry point */ \
_Scheduler_EDF_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
_Scheduler_default_Start_idle /* start idle entry point */ \
@@ -156,26 +155,12 @@ void _Scheduler_EDF_Schedule(
*
* @param[in] scheduler The scheduler instance.
* @param[in] the_thread being initialized.
+ * @param[in] priority The thread priority.
*/
void _Scheduler_EDF_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-);
-
-/**
- * @brief Updates position in the ready queue of @a the_thread.
- *
- * This routine updates position in the ready queue of @a the_thread.
- *
- * @param[in] scheduler The scheduler instance.
- * @param[in] the_thread will have its scheduler specific information
- * structure updated.
- * @param[in] new_priority is the desired new priority.
- */
-void _Scheduler_EDF_Update_priority(
- const Scheduler_Control *scheduler,
Thread_Control *the_thread,
- Priority_Control new_priority
+ Priority_Control priority
);
/**
@@ -193,11 +178,9 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
Thread_Control *the_thread
);
-Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
+Scheduler_Void_or_thread _Scheduler_EDF_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *the_thread
);
Priority_Control _Scheduler_EDF_Map_priority(
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index edad0d3fd4..11347fe047 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -341,12 +341,12 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Block( Thread_Control *the_thread )
/**
* @brief Unblocks a thread with respect to the scheduler.
*
- * This routine adds @a the_thread to the scheduling decision for
- * the scheduler. The primary task is to add the thread to the
- * ready queue per the schedulering policy and update any appropriate
- * scheduling variables, for example the heir thread.
+ * This operation must fetch the latest thread priority value for this
+ * scheduler instance and update its internal state if necessary.
*
* @param[in] the_thread The thread.
+ *
+ * @see _Scheduler_Node_get_priority().
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread )
{
@@ -374,24 +374,18 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread )
/**
* @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.
+ * On uni-processor configurations, this operation must evaluate the thread
+ * state. In case the thread is not ready, then the priority update should be
+ * deferred to the next scheduler unblock operation.
*
* The operation must update the heir and thread dispatch necessary variables
* in case the set of scheduled threads changes.
*
* @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.
+ *
+ * @see _Scheduler_Node_get_priority().
*/
-RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
-)
+RTEMS_INLINE_ROUTINE void _Scheduler_Update_priority( Thread_Control *the_thread )
{
const Scheduler_Control *own_scheduler;
ISR_lock_Context lock_context;
@@ -405,12 +399,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
#if defined(RTEMS_SMP)
needs_help =
#endif
- ( *own_scheduler->Operations.change_priority )(
- own_scheduler,
- the_thread,
- new_priority,
- prepend_it
- );
+ ( *own_scheduler->Operations.update_priority )( own_scheduler, the_thread );
#if defined(RTEMS_SMP)
_Scheduler_Ask_for_help_if_necessary( needs_help );
@@ -466,13 +455,19 @@ RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Unmap_priority(
*
* @param[in] scheduler The scheduler instance.
* @param[in] the_thread The thread containing the scheduler node.
+ * @param[in] priority The thread priority.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Priority_Control priority
)
{
- return ( *scheduler->Operations.node_initialize )( scheduler, the_thread );
+ ( *scheduler->Operations.node_initialize )(
+ scheduler,
+ the_thread,
+ priority
+ );
}
/**
@@ -493,32 +488,6 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_destroy(
}
/**
- * @brief Updates the scheduler about a priority change of a not ready thread.
- *
- * @param[in] the_thread The thread.
- * @param[in] new_priority The new priority of the thread.
- */
-RTEMS_INLINE_ROUTINE void _Scheduler_Update_priority(
- Thread_Control *the_thread,
- Priority_Control new_priority
-)
-{
- const Scheduler_Control *scheduler;
- ISR_lock_Context lock_context;
-
- scheduler = _Scheduler_Get( the_thread );
- _Scheduler_Acquire_critical( scheduler, &lock_context );
-
- ( *scheduler->Operations.update_priority )(
- scheduler,
- the_thread,
- new_priority
- );
-
- _Scheduler_Release_critical( scheduler, &lock_context );
-}
-
-/**
* @brief Releases a job of a thread with respect to the scheduler.
*
* @param[in] the_thread The thread.
@@ -639,8 +608,11 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Set(
_Scheduler_Node_destroy( current_scheduler, the_thread );
the_thread->Scheduler.own_control = scheduler;
the_thread->Scheduler.control = scheduler;
- _Scheduler_Node_initialize( scheduler, the_thread );
- _Scheduler_Update_priority( the_thread, the_thread->current_priority );
+ _Scheduler_Node_initialize(
+ scheduler,
+ the_thread,
+ the_thread->current_priority
+ );
if ( _States_Is_ready( current_state ) ) {
_Scheduler_Unblock( the_thread );
@@ -827,22 +799,73 @@ RTEMS_INLINE_ROUTINE Scheduler_Node *_Scheduler_Thread_get_node(
}
RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize(
- Scheduler_Node *node,
- Thread_Control *the_thread
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
)
{
+ node->Priority.value = priority;
+ node->Priority.prepend_it = false;
+
#if defined(RTEMS_SMP)
node->user = the_thread;
node->help_state = SCHEDULER_HELP_YOURSELF;
node->owner = the_thread;
node->idle = NULL;
node->accepts_help = the_thread;
+ _SMP_sequence_lock_Initialize( &node->Priority.Lock );
#else
- (void) node;
(void) the_thread;
#endif
}
+RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Node_get_priority(
+ Scheduler_Node *node,
+ bool *prepend_it_p
+)
+{
+ Priority_Control priority;
+ bool prepend_it;
+
+#if defined(RTEMS_SMP)
+ unsigned int seq;
+
+ do {
+ seq = _SMP_sequence_lock_Read_begin( &node->Priority.Lock );
+#endif
+
+ priority = node->Priority.value;
+ prepend_it = node->Priority.prepend_it;
+
+#if defined(RTEMS_SMP)
+ } while ( _SMP_sequence_lock_Read_retry( &node->Priority.Lock, seq ) );
+#endif
+
+ *prepend_it_p = prepend_it;
+
+ return priority;
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Node_set_priority(
+ Scheduler_Node *node,
+ Priority_Control new_priority,
+ bool prepend_it
+)
+{
+#if defined(RTEMS_SMP)
+ unsigned int seq;
+
+ seq = _SMP_sequence_lock_Write_begin( &node->Priority.Lock );
+#endif
+
+ node->Priority.value = new_priority;
+ node->Priority.prepend_it = prepend_it;
+
+#if defined(RTEMS_SMP)
+ _SMP_sequence_lock_Write_end( &node->Priority.Lock, seq );
+#endif
+}
+
#if defined(RTEMS_SMP)
/**
* @brief Gets an idle thread from the scheduler instance.
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index d5e73c19fc..f2e045903e 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -44,13 +44,12 @@ extern "C" {
_Scheduler_priority_Yield, /* yield entry point */ \
_Scheduler_priority_Block, /* block entry point */ \
_Scheduler_priority_Unblock, /* unblock entry point */ \
- _Scheduler_priority_Change_priority, /* change priority entry point */ \
+ _Scheduler_priority_Update_priority, /* update priority entry point */ \
_Scheduler_default_Map_priority, /* map priority entry point */ \
_Scheduler_default_Unmap_priority, /* unmap priority entry point */ \
SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
- _Scheduler_default_Node_initialize, /* node initialize entry point */ \
+ _Scheduler_priority_Node_initialize, /* node initialize entry point */ \
_Scheduler_default_Node_destroy, /* node destroy entry point */ \
- _Scheduler_priority_Update_priority, /* update priority entry point */ \
_Scheduler_default_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
_Scheduler_default_Start_idle /* start idle entry point */ \
@@ -78,6 +77,11 @@ typedef struct {
* @brief Data for ready queue operations.
*/
typedef struct {
+ /**
+ * @brief The thread priority currently used by the scheduler.
+ */
+ unsigned int current_priority;
+
/** This field points to the Ready FIFO for this thread's priority. */
Chain_Control *ready_chain;
@@ -134,16 +138,6 @@ void _Scheduler_priority_Schedule(
);
/**
- * @brief Updates the scheduler node to reflect the new priority of the
- * thread.
- */
-void _Scheduler_priority_Update_priority(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority
-);
-
-/**
* @brief Add @a the_thread to the scheduling decision.
*
* This routine adds @a the_thread to the scheduling decision,
@@ -158,11 +152,15 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock(
Thread_Control *the_thread
);
-Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
+Scheduler_Void_or_thread _Scheduler_priority_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+);
+
+void _Scheduler_priority_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Priority_Control priority
);
/**
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
index b0a704478c..2c9b49671e 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
@@ -54,13 +54,12 @@ extern "C" {
_Scheduler_priority_SMP_Yield, \
_Scheduler_priority_affinity_SMP_Block, \
_Scheduler_priority_affinity_SMP_Unblock, \
- _Scheduler_priority_affinity_SMP_Change_priority, \
+ _Scheduler_priority_affinity_SMP_Update_priority, \
_Scheduler_default_Map_priority, \
_Scheduler_default_Unmap_priority, \
_Scheduler_priority_affinity_SMP_Ask_for_help, \
_Scheduler_priority_affinity_SMP_Node_initialize, \
_Scheduler_default_Node_destroy, \
- _Scheduler_priority_SMP_Update_priority, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
_Scheduler_SMP_Start_idle, \
@@ -76,10 +75,12 @@ extern "C" {
* @param[in] scheduler points to the scheduler specific information.
* @param[in] thread is the thread the scheduler is allocating
* management memory for.
+ * @param[in] priority is the thread priority.
*/
void _Scheduler_priority_affinity_SMP_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *thread
+ Thread_Control *the_thread,
+ Priority_Control priority
);
/**
@@ -127,18 +128,14 @@ bool _Scheduler_priority_affinity_SMP_Get_affinity(
);
/**
- * @brief Change priority for the priority affinity SMP scheduler.
+ * @brief Update priority for the priority affinity SMP scheduler.
*
* @param[in] scheduler The scheduler of the thread.
* @param[in] the_thread The associated thread.
- * @param[in] new_priority The new priority for the thread.
- * @param[in] prepend_it Append or prepend the thread to its priority FIFO.
*/
-Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority(
+Thread_Control *_Scheduler_priority_affinity_SMP_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *the_thread
);
Thread_Control *_Scheduler_priority_affinity_SMP_Ask_for_help(
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
index d709818473..0f576b6d93 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
@@ -210,6 +210,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_update(
Chain_Control *ready_queues
)
{
+ ready_queue->current_priority = new_priority;
ready_queue->ready_chain = &ready_queues[ new_priority ];
_Priority_bit_map_Initialize_information(
diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
index 0af7000808..051e44f8af 100644
--- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
@@ -83,13 +83,12 @@ typedef struct {
_Scheduler_priority_SMP_Yield, \
_Scheduler_priority_SMP_Block, \
_Scheduler_priority_SMP_Unblock, \
- _Scheduler_priority_SMP_Change_priority, \
+ _Scheduler_priority_SMP_Update_priority, \
_Scheduler_default_Map_priority, \
_Scheduler_default_Unmap_priority, \
_Scheduler_priority_SMP_Ask_for_help, \
_Scheduler_priority_SMP_Node_initialize, \
_Scheduler_default_Node_destroy, \
- _Scheduler_priority_SMP_Update_priority, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
_Scheduler_SMP_Start_idle \
@@ -100,7 +99,8 @@ void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler );
void _Scheduler_priority_SMP_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *thread
+ Thread_Control *the_thread,
+ Priority_Control priority
);
void _Scheduler_priority_SMP_Block(
@@ -113,11 +113,9 @@ Thread_Control *_Scheduler_priority_SMP_Unblock(
Thread_Control *thread
);
-Thread_Control *_Scheduler_priority_SMP_Change_priority(
+Thread_Control *_Scheduler_priority_SMP_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *the_thread
);
Thread_Control *_Scheduler_priority_SMP_Ask_for_help(
@@ -126,12 +124,6 @@ Thread_Control *_Scheduler_priority_SMP_Ask_for_help(
Thread_Control *offers_help
);
-void _Scheduler_priority_SMP_Update_priority(
- const Scheduler_Control *scheduler,
- Thread_Control *thread,
- Priority_Control new_priority
-);
-
Thread_Control *_Scheduler_priority_SMP_Yield(
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 00f8dd790f..3fa4b333f9 100644
--- a/cpukit/score/include/rtems/score/schedulersimple.h
+++ b/cpukit/score/include/rtems/score/schedulersimple.h
@@ -44,13 +44,12 @@ 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_simple_Update_priority, /* update priority entry point */ \
_Scheduler_default_Map_priority, /* map priority entry point */ \
_Scheduler_default_Unmap_priority, /* unmap priority entry point */ \
SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
_Scheduler_default_Node_initialize, /* node initialize entry point */ \
_Scheduler_default_Node_destroy, /* node destroy entry point */ \
- _Scheduler_default_Update_priority, /* update priority entry point */ \
_Scheduler_default_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
_Scheduler_default_Start_idle /* start idle entry point */ \
@@ -145,11 +144,9 @@ Scheduler_Void_or_thread _Scheduler_simple_Unblock(
Thread_Control *the_thread
);
-Scheduler_Void_or_thread _Scheduler_simple_Change_priority(
+Scheduler_Void_or_thread _Scheduler_simple_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *the_thread
);
/**@}*/
diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h
index 31c837d00d..0a05546c46 100644
--- a/cpukit/score/include/rtems/score/schedulersimplesmp.h
+++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h
@@ -66,13 +66,12 @@ typedef struct {
_Scheduler_simple_SMP_Yield, \
_Scheduler_simple_SMP_Block, \
_Scheduler_simple_SMP_Unblock, \
- _Scheduler_simple_SMP_Change_priority, \
+ _Scheduler_simple_SMP_Update_priority, \
_Scheduler_default_Map_priority, \
_Scheduler_default_Unmap_priority, \
_Scheduler_simple_SMP_Ask_for_help, \
_Scheduler_simple_SMP_Node_initialize, \
_Scheduler_default_Node_destroy, \
- _Scheduler_simple_SMP_Update_priority, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
_Scheduler_SMP_Start_idle \
@@ -83,7 +82,8 @@ void _Scheduler_simple_SMP_Initialize( const Scheduler_Control *scheduler );
void _Scheduler_simple_SMP_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Priority_Control priority
);
void _Scheduler_simple_SMP_Block(
@@ -96,11 +96,9 @@ Thread_Control *_Scheduler_simple_SMP_Unblock(
Thread_Control *thread
);
-Thread_Control *_Scheduler_simple_SMP_Change_priority(
+Thread_Control *_Scheduler_simple_SMP_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *the_thread
);
Thread_Control *_Scheduler_simple_SMP_Ask_for_help(
@@ -109,12 +107,6 @@ Thread_Control *_Scheduler_simple_SMP_Ask_for_help(
Thread_Control *needs_help
);
-void _Scheduler_simple_SMP_Update_priority(
- const Scheduler_Control *scheduler,
- Thread_Control *thread,
- Priority_Control new_priority
-);
-
Thread_Control *_Scheduler_simple_SMP_Yield(
const Scheduler_Control *scheduler,
Thread_Control *thread
diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h
index a395f2c0ba..a6796a5a98 100644
--- a/cpukit/score/include/rtems/score/schedulersmpimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h
@@ -387,11 +387,13 @@ static inline Scheduler_SMP_Node *_Scheduler_SMP_Node_downcast(
static inline void _Scheduler_SMP_Node_initialize(
Scheduler_SMP_Node *node,
- Thread_Control *thread
+ Thread_Control *thread,
+ Priority_Control priority
)
{
- _Scheduler_Node_do_initialize( &node->Base, thread );
+ _Scheduler_Node_do_initialize( &node->Base, thread, priority );
node->state = SCHEDULER_SMP_NODE_BLOCKED;
+ node->priority = priority;
}
static inline void _Scheduler_SMP_Node_update_priority(
@@ -889,23 +891,38 @@ static inline void _Scheduler_SMP_Block(
}
static inline Thread_Control *_Scheduler_SMP_Unblock(
- Scheduler_Context *context,
- Thread_Control *thread,
- Scheduler_SMP_Enqueue enqueue_fifo
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_SMP_Update update,
+ Scheduler_SMP_Enqueue enqueue_fifo
)
{
- Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node( thread );
- bool is_scheduled = node->state == SCHEDULER_SMP_NODE_SCHEDULED;
- bool unblock = _Scheduler_Unblock_node(
+ Scheduler_SMP_Node *node;
+ bool is_scheduled;
+ bool unblock;
+ Thread_Control *needs_help;
+
+ node = _Scheduler_SMP_Thread_get_node( thread );
+ is_scheduled = ( node->state == SCHEDULER_SMP_NODE_SCHEDULED );
+ unblock = _Scheduler_Unblock_node(
context,
thread,
&node->Base,
is_scheduled,
_Scheduler_SMP_Release_idle_thread
);
- Thread_Control *needs_help;
if ( unblock ) {
+ Priority_Control new_priority;
+ bool prepend_it;
+
+ new_priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
+ (void) prepend_it;
+
+ if ( new_priority != node->priority ) {
+ ( *update )( context, &node->Base, new_priority );
+ }
+
if ( node->state == SCHEDULER_SMP_NODE_BLOCKED ) {
_Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
@@ -931,11 +948,9 @@ static inline Thread_Control *_Scheduler_SMP_Unblock(
return needs_help;
}
-static inline Thread_Control *_Scheduler_SMP_Change_priority(
+static inline Thread_Control *_Scheduler_SMP_Update_priority(
Scheduler_Context *context,
Thread_Control *thread,
- Priority_Control new_priority,
- bool prepend_it,
Scheduler_SMP_Extract extract_from_ready,
Scheduler_SMP_Update update,
Scheduler_SMP_Enqueue enqueue_fifo,
@@ -944,8 +959,18 @@ static inline Thread_Control *_Scheduler_SMP_Change_priority(
Scheduler_SMP_Enqueue_scheduled enqueue_scheduled_lifo
)
{
- Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( thread );
- Thread_Control *needs_help;
+ Scheduler_SMP_Node *node;
+ Thread_Control *needs_help;
+ Priority_Control new_priority;
+ bool prepend_it;
+
+ node = _Scheduler_SMP_Thread_get_own_node( thread );
+ new_priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
+
+ if ( new_priority == node->priority ) {
+ /* Nothing to do */
+ return NULL;
+ }
if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
_Scheduler_SMP_Extract_from_scheduled( &node->Base );
diff --git a/cpukit/score/include/rtems/score/schedulerstrongapa.h b/cpukit/score/include/rtems/score/schedulerstrongapa.h
index d7c3888d5a..e2a33afed7 100644
--- a/cpukit/score/include/rtems/score/schedulerstrongapa.h
+++ b/cpukit/score/include/rtems/score/schedulerstrongapa.h
@@ -83,13 +83,12 @@ typedef struct {
_Scheduler_strong_APA_Yield, \
_Scheduler_strong_APA_Block, \
_Scheduler_strong_APA_Unblock, \
- _Scheduler_strong_APA_Change_priority, \
+ _Scheduler_strong_APA_Update_priority, \
_Scheduler_default_Map_priority, \
_Scheduler_default_Unmap_priority, \
_Scheduler_strong_APA_Ask_for_help, \
_Scheduler_strong_APA_Node_initialize, \
_Scheduler_default_Node_destroy, \
- _Scheduler_strong_APA_Update_priority, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
_Scheduler_SMP_Start_idle \
@@ -100,7 +99,8 @@ void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler );
void _Scheduler_strong_APA_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Priority_Control priority
);
void _Scheduler_strong_APA_Block(
@@ -113,11 +113,9 @@ Thread_Control *_Scheduler_strong_APA_Unblock(
Thread_Control *the_thread
);
-Thread_Control *_Scheduler_strong_APA_Change_priority(
+Thread_Control *_Scheduler_strong_APA_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *the_thread
);
Thread_Control *_Scheduler_strong_APA_Ask_for_help(
@@ -126,12 +124,6 @@ Thread_Control *_Scheduler_strong_APA_Ask_for_help(
Thread_Control *offers_help
);
-void _Scheduler_strong_APA_Update_priority(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority
-);
-
Thread_Control *_Scheduler_strong_APA_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index cde31b48c1..4d498e5f3f 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -363,14 +363,6 @@ typedef struct {
Priority_Control real_priority;
/**
- * @brief Generation of the current priority value.
- *
- * It is used in _Thread_Change_priority() to serialize the update of
- * priority related data structures.
- */
- uint32_t priority_generation;
-
- /**
* @brief Hints if a priority restore is necessary once the resource count
* changes from one to zero.
*
@@ -744,14 +736,6 @@ struct _Thread_Control {
Priority_Control real_priority;
/**
- * @brief Generation of the current priority value.
- *
- * It is used in _Thread_Change_priority() to serialize the update of
- * priority related data structures.
- */
- uint32_t priority_generation;
-
- /**
* @brief Hints if a priority restore is necessary once the resource count
* changes from one to zero.
*
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 164773ac2f..6bb78158e3 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -253,6 +253,11 @@ void _Thread_Cancel(
*/
void _Thread_Close( Thread_Control *the_thread, Thread_Control *executing );
+RTEMS_INLINE_ROUTINE bool _Thread_Is_ready( const Thread_Control *the_thread )
+{
+ return _States_Is_ready( the_thread->current_state );
+}
+
States_Control _Thread_Clear_state_locked(
Thread_Control *the_thread,
States_Control state