From 9bfad8cd519f17cbb26a672868169fcd304d5bd5 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 8 Jun 2016 22:22:46 +0200 Subject: 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. --- cpukit/score/Makefile.am | 3 - cpukit/score/include/rtems/score/scheduler.h | 74 +++++++----- cpukit/score/include/rtems/score/schedulercbs.h | 6 +- cpukit/score/include/rtems/score/scheduleredf.h | 27 +---- cpukit/score/include/rtems/score/schedulerimpl.h | 133 ++++++++++++--------- .../score/include/rtems/score/schedulerpriority.h | 30 +++-- .../rtems/score/schedulerpriorityaffinitysmp.h | 17 ++- .../include/rtems/score/schedulerpriorityimpl.h | 1 + .../include/rtems/score/schedulerprioritysmp.h | 18 +-- cpukit/score/include/rtems/score/schedulersimple.h | 9 +- .../score/include/rtems/score/schedulersimplesmp.h | 18 +-- .../score/include/rtems/score/schedulersmpimpl.h | 53 +++++--- .../score/include/rtems/score/schedulerstrongapa.h | 18 +-- cpukit/score/include/rtems/score/thread.h | 16 --- cpukit/score/include/rtems/score/threadimpl.h | 5 + cpukit/score/src/schedulercbsnodeinit.c | 5 +- cpukit/score/src/schedulercbsunblock.c | 4 +- cpukit/score/src/schedulerdefaultnodeinit.c | 5 +- cpukit/score/src/schedulerdefaultupdate.c | 33 ----- cpukit/score/src/scheduleredfchangepriority.c | 31 +++-- cpukit/score/src/scheduleredfnodeinit.c | 5 +- cpukit/score/src/scheduleredfunblock.c | 14 ++- cpukit/score/src/scheduleredfupdate.c | 38 ------ cpukit/score/src/schedulerpriority.c | 21 ++++ cpukit/score/src/schedulerpriorityaffinitysmp.c | 20 ++-- cpukit/score/src/schedulerprioritychangepriority.c | 30 +++-- cpukit/score/src/schedulerprioritysmp.c | 42 +++---- cpukit/score/src/schedulerpriorityunblock.c | 28 +++-- cpukit/score/src/schedulerpriorityupdate.c | 39 ------ cpukit/score/src/schedulersimplechangepriority.c | 20 +++- cpukit/score/src/schedulersimplesmp.c | 28 ++--- cpukit/score/src/schedulerstrongapa.c | 42 +++---- cpukit/score/src/thread.c | 1 - cpukit/score/src/threadchangepriority.c | 21 +--- cpukit/score/src/threadinitialize.c | 4 +- 35 files changed, 398 insertions(+), 461 deletions(-) delete mode 100644 cpukit/score/src/schedulerdefaultupdate.c delete mode 100644 cpukit/score/src/scheduleredfupdate.c delete mode 100644 cpukit/score/src/schedulerpriorityupdate.c (limited to 'cpukit') diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index a58aedcc09..f2ebac2d1d 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -234,7 +234,6 @@ libscore_a_SOURCES += src/schedulerdefaultreleasejob.c libscore_a_SOURCES += src/schedulerdefaultschedule.c libscore_a_SOURCES += src/schedulerdefaultstartidle.c libscore_a_SOURCES += src/schedulerdefaulttick.c -libscore_a_SOURCES += src/schedulerdefaultupdate.c ## SCHEDULERPRIORITY_C_FILES libscore_a_SOURCES += src/schedulerpriority.c \ @@ -242,7 +241,6 @@ libscore_a_SOURCES += src/schedulerpriority.c \ src/schedulerprioritychangepriority.c \ src/schedulerpriorityschedule.c \ src/schedulerpriorityunblock.c \ - src/schedulerpriorityupdate.c \ src/schedulerpriorityyield.c ## SCHEDULERSIMPLE_C_FILES @@ -261,7 +259,6 @@ libscore_a_SOURCES += src/scheduleredf.c \ src/scheduleredfreleasejob.c \ src/scheduleredfschedule.c \ src/scheduleredfunblock.c \ - src/scheduleredfupdate.c \ src/scheduleredfyield.c ## SCHEDULERCBS_C_FILES 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 +#include #include #if defined(__RTEMS_HAVE_SYS_CPUSET_H__) && defined(RTEMS_SMP) #include @@ -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 ); /** @@ -485,19 +518,6 @@ void _Scheduler_default_Node_destroy( Thread_Control *the_thread ); -/** - * @brief Does nothing. - * - * @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. * 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 + ); } /** @@ -492,32 +487,6 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_destroy( ( *scheduler->Operations.node_destroy )( scheduler, the_thread ); } -/** - * @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. * @@ -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; @@ -133,16 +137,6 @@ void _Scheduler_priority_Schedule( Thread_Control *the_thread ); -/** - * @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. * @@ -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 @@ -362,14 +362,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. @@ -743,14 +735,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 diff --git a/cpukit/score/src/schedulercbsnodeinit.c b/cpukit/score/src/schedulercbsnodeinit.c index df679b6588..3aa825bd12 100644 --- a/cpukit/score/src/schedulercbsnodeinit.c +++ b/cpukit/score/src/schedulercbsnodeinit.c @@ -22,12 +22,13 @@ void _Scheduler_CBS_Node_initialize( const Scheduler_Control *scheduler, - Thread_Control *the_thread + Thread_Control *the_thread, + Priority_Control priority ) { Scheduler_CBS_Node *node; - _Scheduler_EDF_Node_initialize( scheduler, the_thread ); + _Scheduler_EDF_Node_initialize( scheduler, the_thread, priority ); node = _Scheduler_CBS_Thread_get_node( the_thread ); node->cbs_server = NULL; diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c index 3f5bd33623..70db651080 100644 --- a/cpukit/score/src/schedulercbsunblock.c +++ b/cpukit/score/src/schedulercbsunblock.c @@ -34,11 +34,13 @@ Scheduler_Void_or_thread _Scheduler_CBS_Unblock( Scheduler_CBS_Node *node; Scheduler_CBS_Server *serv_info; Priority_Control priority; + bool prepend_it; context = _Scheduler_EDF_Get_context( scheduler ); node = _Scheduler_CBS_Thread_get_node( the_thread ); serv_info = node->cbs_server; - priority = node->Base.current_priority; + priority = _Scheduler_Node_get_priority( &node->Base.Base, &prepend_it ); + (void) prepend_it; /* * Late unblock rule for deadline-driven tasks. The remaining time to diff --git a/cpukit/score/src/schedulerdefaultnodeinit.c b/cpukit/score/src/schedulerdefaultnodeinit.c index a96a528ee4..de2b6c8dd3 100644 --- a/cpukit/score/src/schedulerdefaultnodeinit.c +++ b/cpukit/score/src/schedulerdefaultnodeinit.c @@ -23,12 +23,13 @@ void _Scheduler_default_Node_initialize( const Scheduler_Control *scheduler, - Thread_Control *the_thread + Thread_Control *the_thread, + Priority_Control priority ) { Scheduler_Node *node = _Scheduler_Thread_get_own_node( the_thread ); (void) scheduler; - _Scheduler_Node_do_initialize( node, the_thread ); + _Scheduler_Node_do_initialize( node, the_thread, priority ); } diff --git a/cpukit/score/src/schedulerdefaultupdate.c b/cpukit/score/src/schedulerdefaultupdate.c deleted file mode 100644 index fcdc838502..0000000000 --- a/cpukit/score/src/schedulerdefaultupdate.c +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * - * @brief Scheduler Default Update Operation - * - * @ingroup ScoreScheduler - */ - -/* - * COPYRIGHT (c) 2011. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -void _Scheduler_default_Update_priority( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Priority_Control new_priority -) -{ - (void) scheduler; - (void) the_thread; - (void) new_priority; -} diff --git a/cpukit/score/src/scheduleredfchangepriority.c b/cpukit/score/src/scheduleredfchangepriority.c index a0f5ec7061..9a73128e4c 100644 --- a/cpukit/score/src/scheduleredfchangepriority.c +++ b/cpukit/score/src/scheduleredfchangepriority.c @@ -36,31 +36,42 @@ Priority_Control _Scheduler_EDF_Unmap_priority( return priority & ~SCHEDULER_EDF_PRIO_MSB; } -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 ) { Scheduler_EDF_Context *context; Scheduler_EDF_Node *node; + Priority_Control priority; + bool prepend_it; + + if ( !_Thread_Is_ready( the_thread ) ) { + /* Nothing to do */ + SCHEDULER_RETURN_VOID_OR_NULL; + } - context = _Scheduler_EDF_Get_context( scheduler ); node = _Scheduler_EDF_Thread_get_node( the_thread ); + priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it ); - if ( ( new_priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) { - node->background_priority = new_priority; + if ( priority == node->current_priority ) { + /* Nothing to do */ + SCHEDULER_RETURN_VOID_OR_NULL; } - node->current_priority = new_priority; + if ( ( priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) { + node->background_priority = priority; + } + + node->current_priority = priority; + context = _Scheduler_EDF_Get_context( scheduler ); _Scheduler_EDF_Extract( context, node ); if ( prepend_it ) { - _Scheduler_EDF_Enqueue_first( context, node, new_priority ); + _Scheduler_EDF_Enqueue_first( context, node, priority ); } else { - _Scheduler_EDF_Enqueue( context, node, new_priority ); + _Scheduler_EDF_Enqueue( context, node, priority ); } _Scheduler_EDF_Schedule_body( scheduler, the_thread, false ); diff --git a/cpukit/score/src/scheduleredfnodeinit.c b/cpukit/score/src/scheduleredfnodeinit.c index ec6d9bae7c..6005fa0538 100644 --- a/cpukit/score/src/scheduleredfnodeinit.c +++ b/cpukit/score/src/scheduleredfnodeinit.c @@ -22,14 +22,15 @@ void _Scheduler_EDF_Node_initialize( const Scheduler_Control *scheduler, - Thread_Control *the_thread + Thread_Control *the_thread, + Priority_Control priority ) { Scheduler_EDF_Node *node = _Scheduler_EDF_Thread_get_node( the_thread ); (void) scheduler; - _Scheduler_Node_do_initialize( &node->Base, the_thread ); + _Scheduler_Node_do_initialize( &node->Base, the_thread, priority ); node->thread = the_thread; } diff --git a/cpukit/score/src/scheduleredfunblock.c b/cpukit/score/src/scheduleredfunblock.c index b3acbcd4c2..9f80fa9aea 100644 --- a/cpukit/score/src/scheduleredfunblock.c +++ b/cpukit/score/src/scheduleredfunblock.c @@ -29,11 +29,16 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock( { Scheduler_EDF_Context *context; Scheduler_EDF_Node *node; + Priority_Control priority; + bool prepend_it; context = _Scheduler_EDF_Get_context( scheduler ); node = _Scheduler_EDF_Thread_get_node( the_thread ); + priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it ); + (void) prepend_it; - _Scheduler_EDF_Enqueue( context, node, node->current_priority ); + node->current_priority = priority; + _Scheduler_EDF_Enqueue( context, node, priority ); /* * If the thread that was unblocked is more important than the heir, @@ -47,11 +52,8 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock( * Even if the thread isn't preemptible, if the new heir is * a pseudo-ISR system task, we need to do a context switch. */ - if ( the_thread->current_priority < _Thread_Heir->current_priority ) { - _Scheduler_Update_heir( - the_thread, - the_thread->current_priority == PRIORITY_PSEUDO_ISR - ); + if ( priority < _Thread_Heir->current_priority ) { + _Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR ); } SCHEDULER_RETURN_VOID_OR_NULL; diff --git a/cpukit/score/src/scheduleredfupdate.c b/cpukit/score/src/scheduleredfupdate.c deleted file mode 100644 index 5d475fe5f1..0000000000 --- a/cpukit/score/src/scheduleredfupdate.c +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file - * - * @brief Scheduler EDF Update - * @ingroup ScoreScheduler - */ - -/* - * Copyright (C) 2011 Petr Benes. - * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -void _Scheduler_EDF_Update_priority( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Priority_Control new_priority -) -{ - Scheduler_EDF_Node *node; - - node = _Scheduler_EDF_Thread_get_node( the_thread ); - - if ( ( new_priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) { - node->background_priority = new_priority; - } - - node->current_priority = new_priority; -} diff --git a/cpukit/score/src/schedulerpriority.c b/cpukit/score/src/schedulerpriority.c index 61505a4fce..2719697ba3 100644 --- a/cpukit/score/src/schedulerpriority.c +++ b/cpukit/score/src/schedulerpriority.c @@ -32,3 +32,24 @@ void _Scheduler_priority_Initialize( const Scheduler_Control *scheduler ) scheduler->maximum_priority ); } + +void _Scheduler_priority_Node_initialize( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Priority_Control priority +) +{ + Scheduler_priority_Context *context; + Scheduler_priority_Node *node; + + context = _Scheduler_priority_Get_context( scheduler ); + node = _Scheduler_priority_Thread_get_node( the_thread ); + + _Scheduler_Node_do_initialize( &node->Base, the_thread, priority ); + _Scheduler_priority_Ready_queue_update( + &node->Ready_queue, + priority, + &context->Bit_map, + &context->Ready[ 0 ] + ); +} diff --git a/cpukit/score/src/schedulerpriorityaffinitysmp.c b/cpukit/score/src/schedulerpriorityaffinitysmp.c index fa56e2b1b5..3618f4c901 100644 --- a/cpukit/score/src/schedulerpriorityaffinitysmp.c +++ b/cpukit/score/src/schedulerpriorityaffinitysmp.c @@ -96,15 +96,14 @@ _Scheduler_priority_affinity_SMP_Node_downcast( */ void _Scheduler_priority_affinity_SMP_Node_initialize( const Scheduler_Control *scheduler, - Thread_Control *thread + Thread_Control *the_thread, + Priority_Control priority ) { Scheduler_priority_affinity_SMP_Node *node = - _Scheduler_priority_affinity_SMP_Thread_get_own_node( thread ); - - (void) scheduler; + _Scheduler_priority_affinity_SMP_Thread_get_own_node( the_thread ); - _Scheduler_SMP_Node_initialize( &node->Base.Base, thread ); + _Scheduler_priority_SMP_Node_initialize( scheduler, the_thread, priority ); /* * All we add is affinity information to the basic SMP node. @@ -409,6 +408,7 @@ Thread_Control *_Scheduler_priority_affinity_SMP_Unblock( needs_help = _Scheduler_SMP_Unblock( context, thread, + _Scheduler_priority_SMP_Do_update, _Scheduler_priority_affinity_SMP_Enqueue_fifo ); @@ -535,21 +535,17 @@ static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo( /* * This is the public scheduler specific Change Priority operation. */ -Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority( +Thread_Control *_Scheduler_priority_affinity_SMP_Update_priority( const Scheduler_Control *scheduler, - Thread_Control *thread, - Priority_Control new_priority, - bool prepend_it + Thread_Control *thread ) { Scheduler_Context *context = _Scheduler_Get_context( scheduler ); Thread_Control *displaced; - displaced = _Scheduler_SMP_Change_priority( + displaced = _Scheduler_SMP_Update_priority( context, thread, - new_priority, - prepend_it, _Scheduler_priority_SMP_Extract_from_ready, _Scheduler_priority_SMP_Do_update, _Scheduler_priority_affinity_SMP_Enqueue_fifo, diff --git a/cpukit/score/src/schedulerprioritychangepriority.c b/cpukit/score/src/schedulerprioritychangepriority.c index f883e02d43..04599f5c74 100644 --- a/cpukit/score/src/schedulerprioritychangepriority.c +++ b/cpukit/score/src/schedulerprioritychangepriority.c @@ -21,16 +21,30 @@ #include -Scheduler_Void_or_thread _Scheduler_priority_Change_priority( +Scheduler_Void_or_thread _Scheduler_priority_Update_priority( const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Priority_Control new_priority, - bool prepend_it + Thread_Control *the_thread ) { - Scheduler_priority_Context *context = - _Scheduler_priority_Get_context( scheduler ); - Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread ); + Scheduler_priority_Context *context; + Scheduler_priority_Node *node; + unsigned int priority; + bool prepend_it; + + if ( !_Thread_Is_ready( the_thread ) ) { + /* Nothing to do */ + SCHEDULER_RETURN_VOID_OR_NULL; + } + + node = _Scheduler_priority_Thread_get_node( the_thread ); + priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it ); + + if ( priority == node->Ready_queue.current_priority ) { + /* Nothing to do */ + SCHEDULER_RETURN_VOID_OR_NULL; + } + + context = _Scheduler_priority_Get_context( scheduler ); _Scheduler_priority_Ready_queue_extract( &the_thread->Object.Node, @@ -40,7 +54,7 @@ Scheduler_Void_or_thread _Scheduler_priority_Change_priority( _Scheduler_priority_Ready_queue_update( &node->Ready_queue, - new_priority, + priority, &context->Bit_map, &context->Ready[ 0 ] ); diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c index bd042d2534..aba863e66a 100644 --- a/cpukit/score/src/schedulerprioritysmp.c +++ b/cpukit/score/src/schedulerprioritysmp.c @@ -47,24 +47,27 @@ 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 ) { - Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( thread ); - - _Scheduler_SMP_Node_initialize( node, thread ); -} + Scheduler_Context *context; + Scheduler_priority_SMP_Context *self; + Scheduler_priority_SMP_Node *node; -void _Scheduler_priority_SMP_Update_priority( - const Scheduler_Control *scheduler, - Thread_Control *thread, - Priority_Control new_priority -) -{ - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - Scheduler_Node *node = _Scheduler_Thread_get_node( thread ); + context = _Scheduler_Get_context( scheduler ); + self = _Scheduler_priority_SMP_Get_self( context ); + node = _Scheduler_priority_SMP_Node_downcast( + _Scheduler_Thread_get_own_node( the_thread ) + ); - _Scheduler_priority_SMP_Do_update( context, node, new_priority ); + _Scheduler_SMP_Node_initialize( &node->Base, the_thread, priority ); + _Scheduler_priority_Ready_queue_update( + &node->Ready_queue, + priority, + &self->Bit_map, + &self->Ready[ 0 ] + ); } static Scheduler_Node *_Scheduler_priority_SMP_Get_highest_ready( @@ -213,24 +216,21 @@ Thread_Control *_Scheduler_priority_SMP_Unblock( return _Scheduler_SMP_Unblock( context, thread, + _Scheduler_priority_SMP_Do_update, _Scheduler_priority_SMP_Enqueue_fifo ); } -Thread_Control *_Scheduler_priority_SMP_Change_priority( +Thread_Control *_Scheduler_priority_SMP_Update_priority( const Scheduler_Control *scheduler, - Thread_Control *thread, - Priority_Control new_priority, - bool prepend_it + Thread_Control *thread ) { Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - return _Scheduler_SMP_Change_priority( + return _Scheduler_SMP_Update_priority( context, thread, - new_priority, - prepend_it, _Scheduler_priority_SMP_Extract_from_ready, _Scheduler_priority_SMP_Do_update, _Scheduler_priority_SMP_Enqueue_fifo, diff --git a/cpukit/score/src/schedulerpriorityunblock.c b/cpukit/score/src/schedulerpriorityunblock.c index a912ebfbe2..ba8501bc50 100644 --- a/cpukit/score/src/schedulerpriorityunblock.c +++ b/cpukit/score/src/schedulerpriorityunblock.c @@ -27,9 +27,24 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock ( Thread_Control *the_thread ) { - Scheduler_priority_Context *context = - _Scheduler_priority_Get_context( scheduler ); - Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread ); + Scheduler_priority_Context *context; + Scheduler_priority_Node *node; + unsigned int priority; + bool prepend_it; + + context = _Scheduler_priority_Get_context( scheduler ); + node = _Scheduler_priority_Thread_get_node( the_thread ); + priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it ); + (void) prepend_it; + + if ( priority != node->Ready_queue.current_priority ) { + _Scheduler_priority_Ready_queue_update( + &node->Ready_queue, + priority, + &context->Bit_map, + &context->Ready[ 0 ] + ); + } _Scheduler_priority_Ready_queue_enqueue( &the_thread->Object.Node, @@ -51,11 +66,8 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock ( * Even if the thread isn't preemptible, if the new heir is * a pseudo-ISR system task, we need to do a context switch. */ - if ( the_thread->current_priority < _Thread_Heir->current_priority ) { - _Scheduler_Update_heir( - the_thread, - the_thread->current_priority == PRIORITY_PSEUDO_ISR - ); + if ( priority < _Thread_Heir->current_priority ) { + _Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR ); } SCHEDULER_RETURN_VOID_OR_NULL; diff --git a/cpukit/score/src/schedulerpriorityupdate.c b/cpukit/score/src/schedulerpriorityupdate.c deleted file mode 100644 index d2a7e6ccba..0000000000 --- a/cpukit/score/src/schedulerpriorityupdate.c +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @file - * - * @brief Update Scheduler Priority - * @ingroup ScoreScheduler - */ - -/* - * Copyright (C) 2010 Gedare Bloom. - * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -void _Scheduler_priority_Update_priority( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Priority_Control new_priority -) -{ - Scheduler_priority_Context *context = - _Scheduler_priority_Get_context( scheduler ); - Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread ); - - _Scheduler_priority_Ready_queue_update( - &node->Ready_queue, - new_priority, - &context->Bit_map, - &context->Ready[ 0 ] - ); -} diff --git a/cpukit/score/src/schedulersimplechangepriority.c b/cpukit/score/src/schedulersimplechangepriority.c index 9b94b3ab26..9d4a565dbd 100644 --- a/cpukit/score/src/schedulersimplechangepriority.c +++ b/cpukit/score/src/schedulersimplechangepriority.c @@ -21,15 +21,23 @@ #include -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 ) { - Scheduler_simple_Context *context = - _Scheduler_simple_Get_context( scheduler ); + Scheduler_simple_Context *context; + Scheduler_Node *node; + bool prepend_it; + + if ( !_Thread_Is_ready( the_thread ) ) { + /* Nothing to do */ + SCHEDULER_RETURN_VOID_OR_NULL; + } + + context = _Scheduler_simple_Get_context( scheduler ); + node = _Scheduler_Thread_get_node( the_thread ); + _Scheduler_Node_get_priority( node, &prepend_it ); _Scheduler_simple_Extract( scheduler, the_thread ); diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c index 0f05a7da81..f368ead556 100644 --- a/cpukit/score/src/schedulersimplesmp.c +++ b/cpukit/score/src/schedulersimplesmp.c @@ -44,12 +44,13 @@ 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 ) { Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( the_thread ); - _Scheduler_SMP_Node_initialize( node, the_thread ); + _Scheduler_SMP_Node_initialize( node, the_thread, priority ); } static void _Scheduler_simple_SMP_Do_update( @@ -65,18 +66,6 @@ static void _Scheduler_simple_SMP_Do_update( _Scheduler_SMP_Node_update_priority( node, new_priority ); } -void _Scheduler_simple_SMP_Update_priority( - const Scheduler_Control *scheduler, - Thread_Control *thread, - Priority_Control new_priority -) -{ - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - Scheduler_Node *node = _Scheduler_Thread_get_node( thread ); - - _Scheduler_simple_SMP_Do_update( context, node, new_priority ); -} - static Scheduler_Node *_Scheduler_simple_SMP_Get_highest_ready( Scheduler_Context *context, Scheduler_Node *node @@ -295,24 +284,21 @@ Thread_Control *_Scheduler_simple_SMP_Unblock( return _Scheduler_SMP_Unblock( context, thread, + _Scheduler_simple_SMP_Do_update, _Scheduler_simple_SMP_Enqueue_fifo ); } -Thread_Control *_Scheduler_simple_SMP_Change_priority( +Thread_Control *_Scheduler_simple_SMP_Update_priority( const Scheduler_Control *scheduler, - Thread_Control *thread, - Priority_Control new_priority, - bool prepend_it + Thread_Control *thread ) { Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - return _Scheduler_SMP_Change_priority( + return _Scheduler_SMP_Update_priority( context, thread, - new_priority, - prepend_it, _Scheduler_simple_SMP_Extract_from_ready, _Scheduler_simple_SMP_Do_update, _Scheduler_simple_SMP_Enqueue_fifo, diff --git a/cpukit/score/src/schedulerstrongapa.c b/cpukit/score/src/schedulerstrongapa.c index dd4409766e..51dac679ed 100644 --- a/cpukit/score/src/schedulerstrongapa.c +++ b/cpukit/score/src/schedulerstrongapa.c @@ -172,25 +172,28 @@ void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler ) } void _Scheduler_strong_APA_Node_initialize( - const Scheduler_Control *scheduler, - Thread_Control *the_thread -) -{ - Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( the_thread ); - - _Scheduler_SMP_Node_initialize( node, the_thread ); -} - -void _Scheduler_strong_APA_Update_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, - Priority_Control new_priority + Priority_Control priority ) { - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - Scheduler_Node *node = _Scheduler_Thread_get_node( the_thread ); + Scheduler_Context *context; + Scheduler_strong_APA_Context *self; + Scheduler_strong_APA_Node *node; + + context = _Scheduler_Get_context( scheduler ); + self = _Scheduler_strong_APA_Get_self( context ); + node = _Scheduler_strong_APA_Node_downcast( + _Scheduler_Thread_get_own_node( the_thread ) + ); - _Scheduler_strong_APA_Do_update( context, node, new_priority ); + _Scheduler_SMP_Node_initialize( &node->Base, the_thread, priority ); + _Scheduler_priority_Ready_queue_update( + &node->Ready_queue, + priority, + &self->Bit_map, + &self->Ready[ 0 ] + ); } static Scheduler_Node *_Scheduler_strong_APA_Get_highest_ready( @@ -339,24 +342,21 @@ Thread_Control *_Scheduler_strong_APA_Unblock( return _Scheduler_SMP_Unblock( context, the_thread, + _Scheduler_strong_APA_Do_update, _Scheduler_strong_APA_Enqueue_fifo ); } -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 ) { Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - return _Scheduler_SMP_Change_priority( + return _Scheduler_SMP_Update_priority( context, the_thread, - new_priority, - prepend_it, _Scheduler_strong_APA_Extract_from_ready, _Scheduler_strong_APA_Do_update, _Scheduler_strong_APA_Enqueue_fifo, diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c index 2e0bbd91bb..8028540e10 100644 --- a/cpukit/score/src/thread.c +++ b/cpukit/score/src/thread.c @@ -34,7 +34,6 @@ THREAD_OFFSET_ASSERT( Join_queue ); THREAD_OFFSET_ASSERT( current_state ); THREAD_OFFSET_ASSERT( current_priority ); THREAD_OFFSET_ASSERT( real_priority ); -THREAD_OFFSET_ASSERT( priority_generation ); THREAD_OFFSET_ASSERT( priority_restore_hint ); THREAD_OFFSET_ASSERT( resource_count ); THREAD_OFFSET_ASSERT( Wait ); diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c index 152646f52f..7b22371326 100644 --- a/cpukit/score/src/threadchangepriority.c +++ b/cpukit/score/src/threadchangepriority.c @@ -50,11 +50,12 @@ void _Thread_Change_priority( * we are not REALLY changing priority. */ if ( ( *filter )( the_thread, &new_priority, arg ) ) { - uint32_t my_generation; + Scheduler_Node *own_node; + + own_node = _Scheduler_Thread_get_own_node( the_thread ); + _Scheduler_Node_set_priority( own_node, new_priority, prepend_it ); - my_generation = the_thread->priority_generation + 1; the_thread->current_priority = new_priority; - the_thread->priority_generation = my_generation; ( *the_thread->Wait.operations->priority_change )( the_thread, @@ -65,19 +66,7 @@ void _Thread_Change_priority( _Thread_Lock_release( lock, &lock_context ); _Thread_State_acquire( the_thread, &lock_context ); - - if ( the_thread->priority_generation == my_generation ) { - if ( _States_Is_ready( the_thread->current_state ) ) { - _Scheduler_Change_priority( - the_thread, - new_priority, - prepend_it - ); - } else { - _Scheduler_Update_priority( the_thread, new_priority ); - } - } - + _Scheduler_Update_priority( the_thread ); _Thread_State_release( the_thread, &lock_context ); } else { _Thread_Lock_release( lock, &lock_context ); diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index 229d68bf74..10dbf02dfc 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -200,11 +200,9 @@ bool _Thread_Initialize( RTEMS_STATIC_ASSERT( THREAD_WAIT_FLAGS_INITIAL == 0, Wait_flags ); - _Scheduler_Node_initialize( scheduler, the_thread ); + _Scheduler_Node_initialize( scheduler, the_thread, priority ); scheduler_node_initialized = true; - _Scheduler_Update_priority( the_thread, priority ); - /* POSIX Keys */ _RBTree_Initialize_empty( &the_thread->Keys.Key_value_pairs ); _ISR_lock_Initialize( &the_thread->Keys.Lock, "POSIX Key Value Pairs" ); -- cgit v1.2.3