[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