mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-25 07:18:00 +08:00
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.
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user