Since the thread priority change is now performed atomically in one critical section it is possible to simplify the thread queue update procedure. Add a thread queue agnostic thread priority change notification handler so that we are able to use alternative thread queue implementations.
Update #2273. --- cpukit/score/Makefile.am | 2 +- cpukit/score/include/rtems/score/thread.h | 16 ++++++++++++++++ cpukit/score/include/rtems/score/threadimpl.h | 5 +++++ cpukit/score/include/rtems/score/threadqimpl.h | 17 ----------------- cpukit/score/src/threadchangepriority.c | 2 +- cpukit/score/src/threadinitialize.c | 19 ++++++++++++++----- cpukit/score/src/threadqdequeue.c | 2 ++ cpukit/score/src/threadqenqueue.c | 19 +++++++++++++++++++ cpukit/score/src/threadqextract.c | 2 ++ 9 files changed, 60 insertions(+), 24 deletions(-) diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 509a243..ae407fe 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -299,7 +299,7 @@ endif ## THREADQ_C_FILES libscore_a_SOURCES += src/threadq.c src/threadqdequeue.c \ - src/threadqenqueue.c src/threadqextract.c src/threadqrequeue.c \ + src/threadqenqueue.c src/threadqextract.c \ src/threadqextractwithproxy.c src/threadqfirst.c \ src/threadqflush.c src/threadqprocesstimeout.c src/threadqtimeout.c diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index cea88f4..9b1d8d9 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -263,6 +263,17 @@ typedef union { } Thread_Wait_information_Object_argument_type; /** + * @brief Priority change notification handler. + * + * @param[in] the_thread The thread. + * @param[in] new_priority The new priority value. + */ +typedef void (*Thread_Wait_priority_change)( + Thread_Control *the_thread, + Priority_Control new_priority +); + +/** * @brief This type is able to contain several flags used to control the wait * class and state of a thread. * @@ -310,6 +321,11 @@ typedef struct { Thread_queue_Control *queue; /** + * @brief Priority change notification handler. + */ + Thread_Wait_priority_change priority_change; + + /** * @brief This field contains several flags used to control the wait class * and state of a thread in case fine-grained locking is used. */ diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 9d98fe8..a31ff9f 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -925,6 +925,11 @@ RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources( return owns_resources; } +void _Thread_Wait_priority_change_do_nothing( + Thread_Control *the_thread, + Priority_Control new_priority +); + /** * @brief The initial thread wait flags value set by _Thread_Initialize(). */ diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index 4a1084d..4c8d22e 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -266,23 +266,6 @@ RBTree_Compare_result _Thread_queue_Compare_priority( ); /** - * @brief Invoked when a thread changes priority and is blocked. - * - * This routine is invoked when a thread changes priority and is - * blocked on a thread queue. If the queue is priority ordered, - * the_thread is removed from the_thread_queue and reinserted using - * its new priority. This method has no impact on the state of the_thread - * or of any timeouts associated with this blocking. - * - * @param[in] the_thread_queue pointer to a threadq header - * @param[in] the_thread pointer to a thread control block - */ -void _Thread_queue_Requeue( - Thread_queue_Control *the_thread_queue, - Thread_Control *the_thread -); - -/** * This routine is invoked to indicate that the specified thread queue is * entering a critical section. */ diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c index 34a5a14..c209dbd 100644 --- a/cpukit/score/src/threadchangepriority.c +++ b/cpukit/score/src/threadchangepriority.c @@ -50,7 +50,7 @@ void _Thread_Change_priority( _Scheduler_Update_priority( the_thread, new_priority ); } - _Thread_queue_Requeue( the_thread->Wait.queue, the_thread ); + (*the_thread->Wait.priority_change)( the_thread, new_priority ); } _ISR_Enable( level ); diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index 934fea9..b0ce0e3 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -29,6 +29,14 @@ #include <rtems/score/cpusetimpl.h> #include <rtems/config.h> +void _Thread_Wait_priority_change_do_nothing( + Thread_Control *the_thread, + Priority_Control new_priority +) +{ + /* Do nothing */ +} + bool _Thread_Initialize( Objects_Information *information, Thread_Control *the_thread, @@ -194,11 +202,12 @@ bool _Thread_Initialize( /* Initialize the CPU for the non-SMP schedulers */ _Thread_Set_CPU( the_thread, cpu ); - the_thread->current_state = STATES_DORMANT; - the_thread->Wait.queue = NULL; - the_thread->resource_count = 0; - the_thread->real_priority = priority; - the_thread->Start.initial_priority = priority; + the_thread->current_state = STATES_DORMANT; + the_thread->Wait.queue = NULL; + the_thread->Wait.priority_change = _Thread_Wait_priority_change_do_nothing; + the_thread->resource_count = 0; + the_thread->real_priority = priority; + the_thread->Start.initial_priority = priority; _Thread_Wait_flags_set( the_thread, THREAD_WAIT_FLAGS_INITIAL ); diff --git a/cpukit/score/src/threadqdequeue.c b/cpukit/score/src/threadqdequeue.c index 52ba009..c8d355e 100644 --- a/cpukit/score/src/threadqdequeue.c +++ b/cpukit/score/src/threadqdequeue.c @@ -70,6 +70,8 @@ Thread_Control *_Thread_queue_Dequeue( } } + the_thread->Wait.priority_change = _Thread_Wait_priority_change_do_nothing; + /* * We found a thread to unblock. * diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c index 0fa5fa6..bc0dc02 100644 --- a/cpukit/score/src/threadqenqueue.c +++ b/cpukit/score/src/threadqenqueue.c @@ -23,6 +23,23 @@ #include <rtems/score/threadimpl.h> #include <rtems/score/watchdogimpl.h> +static void _Thread_queue_Requeue_priority( + Thread_Control *the_thread, + Priority_Control new_priority +) +{ + Thread_queue_Control *tq = the_thread->Wait.queue; + + _Thread_queue_Enter_critical_section( tq ); + _RBTree_Extract( &tq->Queues.Priority, &the_thread->RBNode ); + _RBTree_Insert( + &tq->Queues.Priority, + &the_thread->RBNode, + _Thread_queue_Compare_priority, + false + ); +} + void _Thread_queue_Enqueue_with_handler( Thread_queue_Control *the_thread_queue, Thread_Control *the_thread, @@ -83,6 +100,8 @@ void _Thread_queue_Enqueue_with_handler( _Thread_queue_Compare_priority, false ); + + the_thread->Wait.priority_change = _Thread_queue_Requeue_priority; } the_thread->Wait.queue = the_thread_queue; diff --git a/cpukit/score/src/threadqextract.c b/cpukit/score/src/threadqextract.c index d12d3c8..b7772b9 100644 --- a/cpukit/score/src/threadqextract.c +++ b/cpukit/score/src/threadqextract.c @@ -46,6 +46,8 @@ void _Thread_queue_Extract_with_return_code( &the_thread->Wait.queue->Queues.Priority, &the_thread->RBNode ); + + the_thread->Wait.priority_change = _Thread_Wait_priority_change_do_nothing; } the_thread->Wait.return_code = return_code; -- 2.1.4 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel