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
+   *   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@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to