summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/schedulerimpl.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h133
1 files changed, 78 insertions, 55 deletions
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.