[PATCH 12/27] score: Rework affine ready queue handling
Gedare Bloom
gedare at rtems.org
Sat Nov 20 19:42:22 UTC 2021
On Mon, Nov 15, 2021 at 10:13 AM Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
>
> Rework the handling of the affine ready queue for the EDF SMP scheduler.
> Do the queue handling in the node insert, move, and extract operations.
> Remove the queue handling from _Scheduler_EDF_SMP_Allocate_processor().
>
> Update #4531.
> ---
> cpukit/include/rtems/score/scheduleredfsmp.h | 13 ++-
> cpukit/score/src/scheduleredfsmp.c | 106 ++++++++++++-------
> 2 files changed, 77 insertions(+), 42 deletions(-)
>
> diff --git a/cpukit/include/rtems/score/scheduleredfsmp.h b/cpukit/include/rtems/score/scheduleredfsmp.h
> index 85e438e81d..e749b3d419 100644
> --- a/cpukit/include/rtems/score/scheduleredfsmp.h
> +++ b/cpukit/include/rtems/score/scheduleredfsmp.h
> @@ -79,9 +79,18 @@ typedef struct {
> RBTree_Control Queue;
>
> /**
> - * @brief The scheduled thread of the corresponding processor.
> + * @brief If this member is not NULL, then it references the scheduled thread
> + * affine only to the corresponding processor, otherwise the processor is
> + * allocated to a thread which may execute on any of the processors owned
> + * by the scheduler.
> */
> - Scheduler_EDF_SMP_Node *scheduled;
> + Scheduler_EDF_SMP_Node *affine_scheduled;
> +
> + /**
> + * @brief This member referneces the thread allocated to the corresponding
typo: references
> + * processor.
> + */
> + Scheduler_EDF_SMP_Node *allocated;
> } Scheduler_EDF_SMP_Ready_queue;
>
> typedef struct {
> diff --git a/cpukit/score/src/scheduleredfsmp.c b/cpukit/score/src/scheduleredfsmp.c
> index a915dbe511..7da777e87a 100644
> --- a/cpukit/score/src/scheduleredfsmp.c
> +++ b/cpukit/score/src/scheduleredfsmp.c
> @@ -196,21 +196,21 @@ static inline Scheduler_Node *_Scheduler_EDF_SMP_Get_highest_ready(
> return &highest_ready->Base.Base;
> }
>
> -static inline void _Scheduler_EDF_SMP_Set_scheduled(
> +static inline void _Scheduler_EDF_SMP_Set_allocated(
> Scheduler_EDF_SMP_Context *self,
> - Scheduler_EDF_SMP_Node *scheduled,
> + Scheduler_EDF_SMP_Node *allocated,
> const Per_CPU_Control *cpu
> )
> {
> - self->Ready[ _Per_CPU_Get_index( cpu ) + 1 ].scheduled = scheduled;
> + self->Ready[ _Per_CPU_Get_index( cpu ) + 1 ].allocated = allocated;
> }
>
> -static inline Scheduler_EDF_SMP_Node *_Scheduler_EDF_SMP_Get_scheduled(
> +static inline Scheduler_EDF_SMP_Node *_Scheduler_EDF_SMP_Get_allocated(
> const Scheduler_EDF_SMP_Context *self,
> uint8_t rqi
> )
> {
> - return self->Ready[ rqi ].scheduled;
> + return self->Ready[ rqi ].allocated;
> }
>
> static inline Scheduler_Node *_Scheduler_EDF_SMP_Get_lowest_scheduled(
> @@ -226,20 +226,62 @@ static inline Scheduler_Node *_Scheduler_EDF_SMP_Get_lowest_scheduled(
>
> if ( rqi != 0 ) {
> Scheduler_EDF_SMP_Context *self;
> - Scheduler_EDF_SMP_Node *node;
> + Scheduler_EDF_SMP_Node *affine_scheduled;
>
> self = _Scheduler_EDF_SMP_Get_self( context );
> - node = _Scheduler_EDF_SMP_Get_scheduled( self, rqi );
> + affine_scheduled = self->Ready[ rqi ].affine_scheduled;
>
> - if ( node->ready_queue_index > 0 ) {
> - _Assert( node->ready_queue_index == rqi );
> - return &node->Base.Base;
> + if ( affine_scheduled != NULL ) {
> + _Assert( affine_scheduled->ready_queue_index == rqi );
> + return &affine_scheduled->Base.Base;
> }
> }
>
> return _Scheduler_SMP_Get_lowest_scheduled( context, filter_base );
> }
>
> +static inline void _Scheduler_EDF_SMP_Insert_scheduled(
> + Scheduler_Context *context,
> + Scheduler_Node *node_base,
> + Priority_Control priority_to_insert
> +)
> +{
> + Scheduler_EDF_SMP_Context *self;
> + Scheduler_EDF_SMP_Node *node;
> + uint8_t rqi;
> + Scheduler_EDF_SMP_Ready_queue *ready_queue;
> +
> + self = _Scheduler_EDF_SMP_Get_self( context );
> + node = _Scheduler_EDF_SMP_Node_downcast( node_base );
> + rqi = node->ready_queue_index;
> + ready_queue = &self->Ready[ rqi ];
> +
> + _Scheduler_SMP_Insert_scheduled( context, node_base, priority_to_insert );
> +
> + if ( rqi != 0 ) {
> + ready_queue->affine_scheduled = node;
> +
> + if ( !_RBTree_Is_empty( &ready_queue->Queue ) ) {
> + _Chain_Extract_unprotected( &ready_queue->Node );
> + }
> + }
> +}
> +
> +static inline void _Scheduler_EDF_SMP_Activate_ready_queue_if_necessary(
> + Scheduler_EDF_SMP_Context *self,
> + uint8_t rqi,
> + Scheduler_EDF_SMP_Ready_queue *ready_queue
> +)
> +{
> + if (
> + rqi != 0 &&
> + _RBTree_Is_empty( &ready_queue->Queue ) &&
> + ready_queue->affine_scheduled == NULL
> + ) {
> + _Chain_Append_unprotected( &self->Affine_queues, &ready_queue->Node );
> + }
> +}
> +
> static inline void _Scheduler_EDF_SMP_Insert_ready(
> Scheduler_Context *context,
> Scheduler_Node *node_base,
> @@ -265,6 +307,7 @@ static inline void _Scheduler_EDF_SMP_Insert_ready(
> node->generation = generation;
> self->generations[ generation_index ] = generation + increment;
>
> + _Scheduler_EDF_SMP_Activate_ready_queue_if_necessary( self, rqi, ready_queue );
> _RBTree_Initialize_node( &node->Base.Base.Node.RBTree );
> _RBTree_Insert_inline(
> &ready_queue->Queue,
> @@ -272,16 +315,6 @@ static inline void _Scheduler_EDF_SMP_Insert_ready(
> &insert_priority,
> _Scheduler_EDF_SMP_Priority_less_equal
> );
> -
> - if ( rqi != 0 && _Chain_Is_node_off_chain( &ready_queue->Node ) ) {
> - Scheduler_EDF_SMP_Node *scheduled;
> -
> - scheduled = _Scheduler_EDF_SMP_Get_scheduled( self, rqi );
> -
> - if ( scheduled->ready_queue_index == 0 ) {
> - _Chain_Append_unprotected( &self->Affine_queues, &ready_queue->Node );
> - }
> - }
> }
>
> static inline void _Scheduler_EDF_SMP_Extract_from_scheduled(
> @@ -305,6 +338,8 @@ static inline void _Scheduler_EDF_SMP_Extract_from_scheduled(
> if ( rqi != 0 && !_RBTree_Is_empty( &ready_queue->Queue ) ) {
> _Chain_Append_unprotected( &self->Affine_queues, &ready_queue->Node );
> }
> +
> + ready_queue->affine_scheduled = NULL;
> }
>
> static inline void _Scheduler_EDF_SMP_Extract_from_ready(
> @@ -328,10 +363,9 @@ static inline void _Scheduler_EDF_SMP_Extract_from_ready(
> if (
> rqi != 0
> && _RBTree_Is_empty( &ready_queue->Queue )
> - && !_Chain_Is_node_off_chain( &ready_queue->Node )
> + && ready_queue->affine_scheduled == NULL
> ) {
> _Chain_Extract_unprotected( &ready_queue->Node );
> - _Chain_Set_off_chain( &ready_queue->Node );
> }
> }
>
> @@ -342,7 +376,7 @@ static inline void _Scheduler_EDF_SMP_Move_from_scheduled_to_ready(
> {
> Priority_Control insert_priority;
>
> - _Scheduler_SMP_Extract_from_scheduled( context, scheduled_to_ready );
> + _Scheduler_EDF_SMP_Extract_from_scheduled( context, scheduled_to_ready );
> insert_priority = _Scheduler_SMP_Node_priority( scheduled_to_ready );
> _Scheduler_EDF_SMP_Insert_ready(
> context,
> @@ -361,7 +395,7 @@ static inline void _Scheduler_EDF_SMP_Move_from_ready_to_scheduled(
> _Scheduler_EDF_SMP_Extract_from_ready( context, ready_to_scheduled );
> insert_priority = _Scheduler_SMP_Node_priority( ready_to_scheduled );
> insert_priority = SCHEDULER_PRIORITY_APPEND( insert_priority );
> - _Scheduler_SMP_Insert_scheduled(
> + _Scheduler_EDF_SMP_Insert_scheduled(
> context,
> ready_to_scheduled,
> insert_priority
> @@ -385,24 +419,16 @@ static inline void _Scheduler_EDF_SMP_Allocate_processor(
> rqi = scheduled->ready_queue_index;
>
> if ( rqi != 0 ) {
> - Scheduler_EDF_SMP_Ready_queue *ready_queue;
> - Per_CPU_Control *desired_cpu;
> -
> - ready_queue = &self->Ready[ rqi ];
> -
> - if ( !_Chain_Is_node_off_chain( &ready_queue->Node ) ) {
> - _Chain_Extract_unprotected( &ready_queue->Node );
> - _Chain_Set_off_chain( &ready_queue->Node );
> - }
> + Per_CPU_Control *desired_cpu;
>
> desired_cpu = _Per_CPU_Get_by_index( rqi - 1 );
>
> if ( victim_cpu != desired_cpu ) {
> Scheduler_EDF_SMP_Node *node;
>
> - node = _Scheduler_EDF_SMP_Get_scheduled( self, rqi );
> + node = _Scheduler_EDF_SMP_Get_allocated( self, rqi );
> _Assert( node->ready_queue_index == 0 );
> - _Scheduler_EDF_SMP_Set_scheduled( self, node, victim_cpu );
> + _Scheduler_EDF_SMP_Set_allocated( self, node, victim_cpu );
> _Scheduler_SMP_Allocate_processor_exact(
> context,
> &node->Base.Base,
> @@ -413,7 +439,7 @@ static inline void _Scheduler_EDF_SMP_Allocate_processor(
> }
> }
>
> - _Scheduler_EDF_SMP_Set_scheduled( self, scheduled, victim_cpu );
> + _Scheduler_EDF_SMP_Set_allocated( self, scheduled, victim_cpu );
> _Scheduler_SMP_Allocate_processor_exact(
> context,
> &scheduled->Base.Base,
> @@ -454,7 +480,7 @@ static inline bool _Scheduler_EDF_SMP_Enqueue(
> insert_priority,
> _Scheduler_SMP_Priority_less_equal,
> _Scheduler_EDF_SMP_Insert_ready,
> - _Scheduler_SMP_Insert_scheduled,
> + _Scheduler_EDF_SMP_Insert_scheduled,
> _Scheduler_EDF_SMP_Move_from_scheduled_to_ready,
> _Scheduler_EDF_SMP_Get_lowest_scheduled,
> _Scheduler_EDF_SMP_Allocate_processor
> @@ -475,7 +501,7 @@ static inline void _Scheduler_EDF_SMP_Enqueue_scheduled(
> _Scheduler_EDF_SMP_Extract_from_ready,
> _Scheduler_EDF_SMP_Get_highest_ready,
> _Scheduler_EDF_SMP_Insert_ready,
> - _Scheduler_SMP_Insert_scheduled,
> + _Scheduler_EDF_SMP_Insert_scheduled,
> _Scheduler_EDF_SMP_Move_from_ready_to_scheduled,
> _Scheduler_EDF_SMP_Allocate_processor
> );
> @@ -510,7 +536,7 @@ static inline bool _Scheduler_EDF_SMP_Do_ask_for_help(
> node,
> _Scheduler_SMP_Priority_less_equal,
> _Scheduler_EDF_SMP_Insert_ready,
> - _Scheduler_SMP_Insert_scheduled,
> + _Scheduler_EDF_SMP_Insert_scheduled,
> _Scheduler_EDF_SMP_Move_from_scheduled_to_ready,
> _Scheduler_EDF_SMP_Get_lowest_scheduled,
> _Scheduler_EDF_SMP_Allocate_processor
> @@ -598,7 +624,7 @@ static inline void _Scheduler_EDF_SMP_Register_idle(
>
> self = _Scheduler_EDF_SMP_Get_self( context );
> idle = _Scheduler_EDF_SMP_Node_downcast( idle_base );
> - _Scheduler_EDF_SMP_Set_scheduled( self, idle, cpu );
> + _Scheduler_EDF_SMP_Set_allocated( self, idle, cpu );
> }
>
> void _Scheduler_EDF_SMP_Add_processor(
> --
> 2.26.2
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
More information about the devel
mailing list