From 424ffe4db039878eae13428d1ddeeb4a7c7f47fe Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 11 Aug 2016 10:26:57 +0200 Subject: score: Introduce thread queue surrender operation This is an optimization for _Thread_queue_Surrender(). It helps to encapsulate the priority boosting in the priority inheritance thread queue operations. --- cpukit/score/include/rtems/score/threadq.h | 22 +++++++ cpukit/score/include/rtems/score/threadqimpl.h | 25 -------- cpukit/score/src/threadqenqueue.c | 4 +- cpukit/score/src/threadqops.c | 79 +++++++++++++++++++++++--- 4 files changed, 94 insertions(+), 36 deletions(-) diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h index 3c689ac974..48e951eef1 100644 --- a/cpukit/score/include/rtems/score/threadq.h +++ b/cpukit/score/include/rtems/score/threadq.h @@ -370,6 +370,23 @@ typedef void ( *Thread_queue_Extract_operation )( Thread_Control *the_thread ); +/** + * @brief Thread queue surrender operation. + * + * This operation must dequeue and return the first thread on the queue. + * + * @param[in] queue The actual thread queue. + * @param[in] heads The thread queue heads. It must not be NULL. + * @param[in] previous_owner The previous owner of the thread queue. + * + * @return The previous first thread on the queue. + */ +typedef Thread_Control *( *Thread_queue_Surrender_operation )( + Thread_queue_Queue *queue, + Thread_queue_Heads *heads, + Thread_Control *previous_owner +); + /** * @brief Thread queue first operation. * @@ -415,6 +432,11 @@ struct Thread_queue_Operations { */ Thread_queue_Extract_operation extract; + /** + * @brief Thread queue surrender operation. + */ + Thread_queue_Surrender_operation surrender; + /** * @brief Thread queue first operation. */ diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index 8137800841..8a3b991516 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -946,31 +946,6 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy( #endif } -/** - * @brief Boosts the priority of the thread if threads of another scheduler - * instance are enqueued on the thread queue. - * - * The thread queue must use the priority waiting discipline. - * - * @param[in] queue The actual thread queue. - * @param[in] the_thread The thread to boost the priority if necessary. - */ -#if defined(RTEMS_SMP) -void _Thread_queue_Boost_priority( - Thread_queue_Queue *queue, - Thread_Control *the_thread -); -#else -RTEMS_INLINE_ROUTINE void _Thread_queue_Boost_priority( - Thread_queue_Queue *queue, - Thread_Control *the_thread -) -{ - (void) queue; - (void) the_thread; -} -#endif - #if defined(RTEMS_MULTIPROCESSING) void _Thread_queue_MP_callout_do_nothing( Thread_Control *the_proxy, diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c index 2f6b041789..5a7fd6def5 100644 --- a/cpukit/score/src/threadqenqueue.c +++ b/cpukit/score/src/threadqenqueue.c @@ -596,7 +596,7 @@ void _Thread_queue_Surrender( Thread_Control *new_owner; bool unblock; - new_owner = ( *operations->first )( heads ); + new_owner = ( *operations->surrender )( queue, heads, previous_owner ); queue->owner = new_owner; #if defined(RTEMS_MULTIPROCESSING) @@ -604,10 +604,8 @@ void _Thread_queue_Surrender( #endif { ++new_owner->resource_count; - _Thread_queue_Boost_priority( queue, new_owner ); } - ( *operations->extract )( queue, new_owner ); unblock = _Thread_queue_Make_ready_again( new_owner ); _Thread_queue_Unblock_critical( diff --git a/cpukit/score/src/threadqops.c b/cpukit/score/src/threadqops.c index df7054f0c8..41506bfceb 100644 --- a/cpukit/score/src/threadqops.c +++ b/cpukit/score/src/threadqops.c @@ -71,12 +71,11 @@ static Thread_queue_Heads *_Thread_queue_Queue_enqueue( static void _Thread_queue_Queue_extract( Thread_queue_Queue *queue, + Thread_queue_Heads *heads, Thread_Control *the_thread, void ( *extract )( Thread_queue_Heads *, Thread_Control * ) ) { - Thread_queue_Heads *heads = queue->heads; - _Assert( heads != NULL ); the_thread->Wait.spare_heads = RTEMS_CONTAINER_OF( @@ -142,6 +141,7 @@ static void _Thread_queue_FIFO_extract( { _Thread_queue_Queue_extract( queue, + queue->heads, the_thread, _Thread_queue_FIFO_do_extract ); @@ -160,6 +160,25 @@ static Thread_Control *_Thread_queue_FIFO_first( return THREAD_CHAIN_NODE_TO_THREAD( first ); } +static Thread_Control *_Thread_queue_FIFO_surrender( + Thread_queue_Queue *queue, + Thread_queue_Heads *heads, + Thread_Control *previous_owner +) +{ + Thread_Control *first; + + first = _Thread_queue_FIFO_first( heads ); + _Thread_queue_Queue_extract( + queue, + heads, + first, + _Thread_queue_FIFO_do_extract + ); + + return first; +} + static Thread_queue_Priority_queue *_Thread_queue_Priority_queue( Thread_queue_Heads *heads, const Thread_Control *the_thread @@ -296,6 +315,7 @@ static void _Thread_queue_Priority_extract( { _Thread_queue_Queue_extract( queue, + queue->heads, the_thread, _Thread_queue_Priority_do_extract ); @@ -322,6 +342,25 @@ static Thread_Control *_Thread_queue_Priority_first( return THREAD_RBTREE_NODE_TO_THREAD( first ); } +static Thread_Control *_Thread_queue_Priority_surrender( + Thread_queue_Queue *queue, + Thread_queue_Heads *heads, + Thread_Control *previous_owner +) +{ + Thread_Control *first; + + first = _Thread_queue_Priority_first( heads ); + _Thread_queue_Queue_extract( + queue, + heads, + first, + _Thread_queue_Priority_do_extract + ); + + return first; +} + static void _Thread_queue_Priority_inherit_enqueue( Thread_queue_Queue *queue, Thread_Control *the_thread, @@ -374,14 +413,12 @@ static void _Thread_queue_Priority_inherit_enqueue( } } -#if defined(RTEMS_SMP) -void _Thread_queue_Boost_priority( - Thread_queue_Queue *queue, +static void _Thread_queue_Boost_priority( + Thread_queue_Heads *heads, Thread_Control *the_thread ) { - Thread_queue_Heads *heads = queue->heads; - +#if defined(RTEMS_SMP) if ( !_Chain_Has_only_one_node( &heads->Heads.Fifo ) ) { const Scheduler_Control *scheduler; Priority_Control boost_priority; @@ -394,8 +431,31 @@ void _Thread_queue_Boost_priority( _Scheduler_Thread_set_priority( the_thread, boost_priority, false ); } -} +#else + (void) heads; + (void) the_thread; #endif +} + +static Thread_Control *_Thread_queue_Priority_inherit_surrender( + Thread_queue_Queue *queue, + Thread_queue_Heads *heads, + Thread_Control *previous_owner +) +{ + Thread_Control *first; + + first = _Thread_queue_Priority_first( heads ); + _Thread_queue_Boost_priority( heads, first ); + _Thread_queue_Queue_extract( + queue, + heads, + first, + _Thread_queue_Priority_do_extract + ); + + return first; +} const Thread_queue_Operations _Thread_queue_Operations_default = { .priority_change = _Thread_queue_Do_nothing_priority_change, @@ -411,6 +471,7 @@ const Thread_queue_Operations _Thread_queue_Operations_FIFO = { .priority_change = _Thread_queue_Do_nothing_priority_change, .enqueue = _Thread_queue_FIFO_enqueue, .extract = _Thread_queue_FIFO_extract, + .surrender = _Thread_queue_FIFO_surrender, .first = _Thread_queue_FIFO_first }; @@ -418,6 +479,7 @@ const Thread_queue_Operations _Thread_queue_Operations_priority = { .priority_change = _Thread_queue_Priority_priority_change, .enqueue = _Thread_queue_Priority_enqueue, .extract = _Thread_queue_Priority_extract, + .surrender = _Thread_queue_Priority_surrender, .first = _Thread_queue_Priority_first }; @@ -425,5 +487,6 @@ const Thread_queue_Operations _Thread_queue_Operations_priority_inherit = { .priority_change = _Thread_queue_Priority_priority_change, .enqueue = _Thread_queue_Priority_inherit_enqueue, .extract = _Thread_queue_Priority_extract, + .surrender = _Thread_queue_Priority_inherit_surrender, .first = _Thread_queue_Priority_first }; -- cgit v1.2.3