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

Gedare Bloom gedare at rtems.org
Thu Jun 13 15:45:57 UTC 2013


On Wed, Jun 12, 2013 at 11:12 AM, Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
> 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 );
>  }
I would prefer _Scheduler_Yield( Thread_Control *thread ) {
  _Scheduler.Operations.yield(thread);
}
without including this _Scheduler_Yield_with_thread() function. Just
change all of the yield functions to take a thread argument.

>
>  /**
> 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 );
This change seems unnecessary, although if you make the above change
to Scheduler_Yield, then it should be called here with the 'executing'
argument.

>          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
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel



More information about the devel mailing list