[PATCH 08/12] scheduler: Specify thread of yield operation

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Jun 12 15:12:34 UTC 2013


The yielding thread of the yield operation is now specified by a
parameter.  The yield operation is used in the tick operation.  The tick
operation may be performed for each executing thread in a SMP
configuration.
---
 cpukit/score/include/rtems/score/scheduler.h       |    8 ++++-
 cpukit/score/include/rtems/score/scheduleredf.h    |    8 ++++--
 .../score/include/rtems/score/schedulerpriority.h  |    8 ++++--
 cpukit/score/include/rtems/score/schedulersimple.h |    8 ++++--
 cpukit/score/inline/rtems/score/scheduler.inl      |   25 ++++++++++++++++---
 cpukit/score/src/scheduleredfyield.c               |   13 ++++-----
 cpukit/score/src/schedulerprioritytick.c           |    2 +-
 cpukit/score/src/schedulerpriorityyield.c          |   14 ++++------
 cpukit/score/src/schedulersimpleyield.c            |    8 ++----
 9 files changed, 58 insertions(+), 36 deletions(-)

diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index 9e08b23..930412f 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -49,8 +49,12 @@ typedef struct {
   /** Implements the scheduling decision logic (policy). */
   void ( *schedule )(void);
 
-  /** Voluntarily yields the processor per the scheduling policy. */
-  void ( *yield )(void);
+  /**
+   * @brief Voluntarily yields the processor per the scheduling policy.
+   *
+   * @see _Scheduler_Yield() and _Scheduler_Yield_with_thread().
+   */
+  void ( *yield )( Thread_Control *thread );
 
   /** Removes the given thread from scheduling decisions. */
   void ( *block )(Thread_Control *);
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index e84b3f5..7846067 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -189,11 +189,13 @@ void _Scheduler_EDF_Unblock(
  *  transfer control of the processor to another thread in the queue with
  *  equal deadline. This does not have to happen very often.
  *
- *  This routine will remove the running THREAD from the ready queue
- *  and place back. The rbtree ready queue is responsible for FIFO ordering
+ *  This routine will remove the specified THREAD from the ready queue
+ *  and place it back. The rbtree ready queue is responsible for FIFO ordering
  *  in such a case.
+ *
+ *  @param[in/out] thread The yielding thread.
  */
-void _Scheduler_EDF_Yield( void );
+void _Scheduler_EDF_Yield( Thread_Control *thread );
 
 /**
  *  @brief Put @a the_thread to the rbtree ready queue.
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index 81c3582..f0582c1 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -145,12 +145,12 @@ void _Scheduler_priority_Unblock(
 );
 
 /**
- *  @brief Remove the running THREAD to the rear of this chain.
+ *  @brief The specified THREAD yields.
  *
  *  This routine is invoked when a thread wishes to voluntarily
  *  transfer control of the processor to another thread in the queue.
  *
- *  This routine will remove the running THREAD from the ready queue
+ *  This routine will remove the specified THREAD from the ready queue
  *  and place it immediately at the rear of this chain.  Reset timeslice
  *  and yield the processor functions both use this routine, therefore if
  *  reset is true and this is the only thread on the queue then the
@@ -160,8 +160,10 @@ void _Scheduler_priority_Unblock(
  *  - INTERRUPT LATENCY:
  *    + ready chain
  *    + select heir
+ *
+ *  @param[in/out] thread The yielding thread.
  */
-void _Scheduler_priority_Yield( void );
+void _Scheduler_priority_Yield( Thread_Control *thread );
 
 /**
  *  @brief Puts @a the_thread on to the priority-based ready queue.
diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h
index 6682074..47b74be 100644
--- a/cpukit/score/include/rtems/score/schedulersimple.h
+++ b/cpukit/score/include/rtems/score/schedulersimple.h
@@ -74,15 +74,17 @@ void _Scheduler_simple_Schedule( void );
  *
  *  This routine is invoked when a thread wishes to voluntarily
  *  transfer control of the processor to another thread in the queue.
- *  It will remove the running THREAD from the scheduler.informaiton
+ *  It will remove the specified THREAD from the scheduler.informaiton
  *  (where the ready queue is stored) and place it immediately at the
  *  between the last entry of its priority and the next priority thread.
  *  Reset timeslice and yield the processor functions both use this routine,
  *  therefore if reset is true and this is the only thread on the queue then
  *  the timeslice counter is reset.  The heir THREAD will be updated if the
  *  running is also the currently the heir.
-*/
-void _Scheduler_simple_Yield( void );
+ *
+ *  @param[in/out] thread The yielding thread.
+ */
+void _Scheduler_simple_Yield( Thread_Control *thread );
 
 /**
  *  @brief Remove a simple-priority-based thread from the queue.
diff --git a/cpukit/score/inline/rtems/score/scheduler.inl b/cpukit/score/inline/rtems/score/scheduler.inl
index 3201c23..bacc12c 100644
--- a/cpukit/score/inline/rtems/score/scheduler.inl
+++ b/cpukit/score/inline/rtems/score/scheduler.inl
@@ -55,16 +55,33 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( void )
 }
 
 /**
+ * @brief Scheduler yield with a particular thread.
+ *
+ * This routine is invoked when a thread wishes to voluntarily transfer control
+ * of the processor to another thread.
+ *
+ * @see _Scheduler_Yield().
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Yield_with_thread(
+  Thread_Control *thread
+)
+{
+  ( *_Scheduler.Operations.yield )( thread );
+}
+
+/**
  * @brief Scheduler yield.
  *
  * This routine is invoked when a thread wishes to voluntarily
- * transfer control of the processor to another thread. This routine
- * always operates on the scheduler that 'owns' the currently executing
- * thread.
+ * transfer control of the processor to another thread.
+ *
+ * The currently executing thread of this processor is used.
+ *
+ * @see _Scheduler_Yield_with_thread().
  */
 RTEMS_INLINE_ROUTINE void _Scheduler_Yield( void )
 {
-  _Scheduler.Operations.yield();
+  _Scheduler_Yield_with_thread( _Thread_Executing );
 }
 
 /**
diff --git a/cpukit/score/src/scheduleredfyield.c b/cpukit/score/src/scheduleredfyield.c
index d686254..4ba9f79 100644
--- a/cpukit/score/src/scheduleredfyield.c
+++ b/cpukit/score/src/scheduleredfyield.c
@@ -25,14 +25,13 @@
 #include <rtems/score/scheduleredf.h>
 #include <rtems/score/thread.h>
 
-void _Scheduler_EDF_Yield(void)
+void _Scheduler_EDF_Yield( Thread_Control *thread )
 {
   ISR_Level                 level;
 
-  Thread_Control *executing  = _Thread_Executing;
-  Scheduler_EDF_Per_thread *executing_info =
-    (Scheduler_EDF_Per_thread *) executing->scheduler_info;
-  RBTree_Node *executing_node = &(executing_info->Node);
+  Scheduler_EDF_Per_thread *thread_info =
+    (Scheduler_EDF_Per_thread *) thread->scheduler_info;
+  RBTree_Node *thread_node = &(thread_info->Node);
 
   _ISR_Disable( level );
 
@@ -40,8 +39,8 @@ void _Scheduler_EDF_Yield(void)
    * The RBTree has more than one node, enqueue behind the tasks
    * with the same priority in case there are such ones.
    */
-  _RBTree_Extract( &_Scheduler_EDF_Ready_queue, executing_node );
-  _RBTree_Insert( &_Scheduler_EDF_Ready_queue, executing_node );
+  _RBTree_Extract( &_Scheduler_EDF_Ready_queue, thread_node );
+  _RBTree_Insert( &_Scheduler_EDF_Ready_queue, thread_node );
 
   _ISR_Flash( level );
 
diff --git a/cpukit/score/src/schedulerprioritytick.c b/cpukit/score/src/schedulerprioritytick.c
index afe6c76..8fa739c 100644
--- a/cpukit/score/src/schedulerprioritytick.c
+++ b/cpukit/score/src/schedulerprioritytick.c
@@ -68,7 +68,7 @@ void _Scheduler_priority_Tick( void )
          *  currently executing thread is placed at the rear of the
          *  FIFO for this priority and a new heir is selected.
          */
-        _Scheduler_Yield();
+        _Scheduler_Yield_with_thread( executing );
         executing->cpu_time_budget = _Thread_Ticks_per_timeslice;
       }
       break;
diff --git a/cpukit/score/src/schedulerpriorityyield.c b/cpukit/score/src/schedulerpriorityyield.c
index c000125..4c2b599 100644
--- a/cpukit/score/src/schedulerpriorityyield.c
+++ b/cpukit/score/src/schedulerpriorityyield.c
@@ -24,28 +24,26 @@
 #include <rtems/score/schedulerpriority.h>
 #include <rtems/score/thread.h>
 
-void _Scheduler_priority_Yield(void)
+void _Scheduler_priority_Yield( Thread_Control *thread )
 {
   Scheduler_priority_Per_thread *sched_info;
   ISR_Level                      level;
-  Thread_Control                *executing;
   Chain_Control                 *ready;
 
-  executing  = _Thread_Executing;
-  sched_info = (Scheduler_priority_Per_thread *) executing->scheduler_info;
+  sched_info = (Scheduler_priority_Per_thread *) thread->scheduler_info;
   ready      = sched_info->ready_chain;
   _ISR_Disable( level );
     if ( !_Chain_Has_only_one_node( ready ) ) {
-      _Chain_Extract_unprotected( &executing->Object.Node );
-      _Chain_Append_unprotected( ready, &executing->Object.Node );
+      _Chain_Extract_unprotected( &thread->Object.Node );
+      _Chain_Append_unprotected( ready, &thread->Object.Node );
 
       _ISR_Flash( level );
 
-      if ( _Thread_Is_heir( executing ) )
+      if ( _Thread_Is_heir( thread ) )
         _Thread_Heir = (Thread_Control *) _Chain_First( ready );
       _Thread_Dispatch_necessary = true;
     }
-    else if ( !_Thread_Is_heir( executing ) )
+    else if ( !_Thread_Is_heir( thread ) )
       _Thread_Dispatch_necessary = true;
 
   _ISR_Enable( level );
diff --git a/cpukit/score/src/schedulersimpleyield.c b/cpukit/score/src/schedulersimpleyield.c
index 1d5d48c..cfbe7a4 100644
--- a/cpukit/score/src/schedulersimpleyield.c
+++ b/cpukit/score/src/schedulersimpleyield.c
@@ -24,21 +24,19 @@
 #include <rtems/score/thread.h>
 #include <rtems/score/schedulersimple.h>
 
-void _Scheduler_simple_Yield( void )
+void _Scheduler_simple_Yield( Thread_Control *thread )
 {
   ISR_Level       level;
-  Thread_Control *executing;
 
-  executing = _Thread_Executing;
   _ISR_Disable( level );
 
-    _Scheduler_simple_Ready_queue_requeue(&_Scheduler, executing);
+    _Scheduler_simple_Ready_queue_requeue( &_Scheduler, thread );
 
     _ISR_Flash( level );
 
     _Scheduler_simple_Schedule();
 
-    if ( !_Thread_Is_heir( executing ) )
+    if ( !_Thread_Is_heir( thread ) )
       _Thread_Dispatch_necessary = true;
 
   _ISR_Enable( level );
-- 
1.7.7




More information about the devel mailing list