diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-06-08 22:22:46 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-06-22 14:44:56 +0200 |
commit | 9bfad8cd519f17cbb26a672868169fcd304d5bd5 (patch) | |
tree | 3a07add3fb0cdf47fe4d5c9432ad931429c05d65 /cpukit/score/include/rtems | |
parent | score: Move _RBTree_Find() (diff) | |
download | rtems-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.h | 74 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulercbs.h | 6 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/scheduleredf.h | 27 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerimpl.h | 133 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerpriority.h | 30 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h | 17 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerpriorityimpl.h | 1 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerprioritysmp.h | 18 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulersimple.h | 9 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulersimplesmp.h | 18 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulersmpimpl.h | 53 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerstrongapa.h | 18 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/thread.h | 16 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadimpl.h | 5 |
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 |