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/include/rtems/score/scheduler.h | 74 ++++++++++++++++++---------- 1 file changed, 47 insertions(+), 27 deletions(-) (limited to 'cpukit/score/include/rtems/score/scheduler.h') 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. * -- cgit v1.2.3