[PATCH 12/12] smp: Add Priority SMP Scheduler

Joel Sherrill joel.sherrill at OARcorp.com
Sat Aug 17 21:18:22 UTC 2013


At first glance, this doesn't include any documentation
changes.

I also don't see exactly how this is different from the
Simple SMP Scheduler. Is it using the fifo per priority
and bitmap scheme like the Deterministic Priority
Scheduler?

There needs to be more on the algorithm and how
it is unique.

On 8/13/2013 8:42 AM, Sebastian Huber wrote:
> ---
>   cpukit/sapi/include/confdefs.h                     |   23 ++-
>   cpukit/score/Makefile.am                           |    2 +
>   .../include/rtems/score/schedulerpriorityimpl.h    |   17 ++
>   .../include/rtems/score/schedulerprioritysmp.h     |   88 ++++++++
>   cpukit/score/preinstall.am                         |    4 +
>   cpukit/score/src/schedulerprioritysmp.c            |  217 ++++++++++++++++++++
>   cpukit/score/src/schedulerpriorityupdate.c         |   10 +-
>   .../smptests/smpmigration01/smpmigration01.scn     |   24 +-
>   8 files changed, 363 insertions(+), 22 deletions(-)
>   create mode 100644 cpukit/score/include/rtems/score/schedulerprioritysmp.h
>   create mode 100644 cpukit/score/src/schedulerprioritysmp.c
>
> diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
> index 0a98645..45275a8 100644
> --- a/cpukit/sapi/include/confdefs.h
> +++ b/cpukit/sapi/include/confdefs.h
> @@ -606,6 +606,7 @@ const rtems_libio_helper rtems_fs_init_helper =
>    * scheduling policy to use.  The supported configurations are:
>    *  CONFIGURE_SCHEDULER_USER       - user provided scheduler
>    *  CONFIGURE_SCHEDULER_PRIORITY   - Deterministic Priority Scheduler
> + *  CONFIGURE_SCHEDULER_PRIORITY_SMP - Priority SMP Scheduler
>    *  CONFIGURE_SCHEDULER_SIMPLE     - Light-weight Priority Scheduler
>    *  CONFIGURE_SCHEDULER_SIMPLE_SMP - Simple SMP Priority Scheduler
>    *  CONFIGURE_SCHEDULER_EDF        - EDF Scheduler
> @@ -629,12 +630,13 @@ const rtems_libio_helper rtems_fs_init_helper =
>   /* If no scheduler is specified, the priority scheduler is default. */
>   #if !defined(CONFIGURE_SCHEDULER_USER) && \
>       !defined(CONFIGURE_SCHEDULER_PRIORITY) && \
> +    !defined(CONFIGURE_SCHEDULER_PRIORITY_SMP) && \
>       !defined(CONFIGURE_SCHEDULER_SIMPLE) && \
>       !defined(CONFIGURE_SCHEDULER_SIMPLE_SMP) && \
>       !defined(CONFIGURE_SCHEDULER_EDF) && \
>       !defined(CONFIGURE_SCHEDULER_CBS)
>     #if defined(RTEMS_SMP) && defined(CONFIGURE_SMP_APPLICATION)
> -    #define CONFIGURE_SCHEDULER_SIMPLE_SMP
> +    #define CONFIGURE_SCHEDULER_PRIORITY_SMP
>     #else
>       #define CONFIGURE_SCHEDULER_PRIORITY
>     #endif
> @@ -659,6 +661,25 @@ const rtems_libio_helper rtems_fs_init_helper =
>   #endif
>
>   /*
> + * If the Priority SMP Scheduler is selected, then configure for it.
> + */
> +#if defined(CONFIGURE_SCHEDULER_PRIORITY_SMP)
> +  #include <rtems/score/schedulerprioritysmp.h>
> +  #define CONFIGURE_SCHEDULER_ENTRY_POINTS SCHEDULER_PRIORITY_SMP_ENTRY_POINTS
> +
> +  /**
> +   * This defines the memory used by the priority scheduler.
> +   */
> +  #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
> +    _Configure_From_workspace( \
> +      sizeof(Scheduler_SMP_Control) +  \
> +      ((CONFIGURE_MAXIMUM_PRIORITY) * sizeof(Chain_Control)) ) \
> +  )
> +  #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
> +    _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) )
> +#endif
> +
> +/*
>    * If the Simple Priority Scheduler is selected, then configure for it.
>    */
>   #if defined(CONFIGURE_SCHEDULER_SIMPLE)
> diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
> index c5af9c7..c9d2d47 100644
> --- a/cpukit/score/Makefile.am
> +++ b/cpukit/score/Makefile.am
> @@ -53,6 +53,7 @@ include_rtems_score_HEADERS += include/rtems/score/scheduleredf.h
>   include_rtems_score_HEADERS += include/rtems/score/scheduleredfimpl.h
>   include_rtems_score_HEADERS += include/rtems/score/schedulerpriority.h
>   include_rtems_score_HEADERS += include/rtems/score/schedulerpriorityimpl.h
> +include_rtems_score_HEADERS += include/rtems/score/schedulerprioritysmp.h
>   include_rtems_score_HEADERS += include/rtems/score/schedulersimple.h
>   include_rtems_score_HEADERS += include/rtems/score/schedulersimpleimpl.h
>   include_rtems_score_HEADERS += include/rtems/score/schedulersmp.h
> @@ -119,6 +120,7 @@ libscore_a_SOURCES += src/mpci.c src/objectmp.c src/threadmp.c
>   endif
>
>   if HAS_SMP
> +libscore_a_SOURCES += src/schedulerprioritysmp.c
>   libscore_a_SOURCES += src/schedulersimplesmp.c
>   libscore_a_SOURCES += src/schedulersmpstartidle.c
>   libscore_a_SOURCES += src/smp.c
> diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
> index 9f45f21..1c85150 100644
> --- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
> +++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
> @@ -186,6 +186,23 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
>     _Scheduler_Update_heir( heir, force_dispatch );
>   }
>
> +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Update_body(
> +  Thread_Control *thread,
> +  Chain_Control *ready_queues
> +)
> +{
> +  Scheduler_priority_Per_thread *sched_info_of_thread =
> +    _Scheduler_priority_Get_scheduler_info( thread );
> +
> +  sched_info_of_thread->ready_chain =
> +    &ready_queues[ thread->current_priority ];
> +
> +  _Priority_bit_map_Initialize_information(
> +    &sched_info_of_thread->Priority_map,
> +    thread->current_priority
> +  );
> +}
> +
>   /**
>    * @brief Priority comparison.
>    *
> diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
> new file mode 100644
> index 0000000..012ad1f
> --- /dev/null
> +++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
> @@ -0,0 +1,88 @@
> +/**
> + * @file
> + *
> + * @ingroup ScoreSchedulerPrioritySMP
> + *
> + * @brief Priority SMP Scheduler API
> + */
> +
> +/*
> + * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
> + *
> + *  embedded brains GmbH
> + *  Dornierstr. 4
> + *  82178 Puchheim
> + *  Germany
> + *  <rtems at embedded-brains.de>
> + *
> + * The license and distribution terms for this file may be
> + * found in the file LICENSE in this distribution or at
> + * http://www.rtems.com/license/LICENSE.
> + */
> +
> +#ifndef _RTEMS_SCORE_SCHEDULERPRIORITYSMP_H
> +#define _RTEMS_SCORE_SCHEDULERPRIORITYSMP_H
> +
> +#include <rtems/score/scheduler.h>
> +#include <rtems/score/schedulerpriority.h>
> +#include <rtems/score/schedulersmp.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif /* __cplusplus */
> +
> +/**
> + * @defgroup ScoreSchedulerPrioritySMP Priority SMP Scheduler
> + *
> + * @ingroup ScoreScheduler
> + *
> + * The thread preempt mode will be ignored.
> + *
> + * @{
> + */
> +
> +/**
> + * @brief Entry points for the Simple SMP Scheduler.
> + */
> +#define SCHEDULER_PRIORITY_SMP_ENTRY_POINTS \
> +  { \
> +    _Scheduler_priority_SMP_Initialize, \
> +    _Scheduler_priority_SMP_Schedule, \
> +    _Scheduler_priority_SMP_Yield, \
> +    _Scheduler_priority_SMP_Block, \
> +    _Scheduler_priority_SMP_Enqueue_fifo, \
> +    _Scheduler_priority_Allocate, \
> +    _Scheduler_priority_Free, \
> +    _Scheduler_priority_SMP_Update, \
> +    _Scheduler_priority_SMP_Enqueue_fifo, \
> +    _Scheduler_priority_SMP_Enqueue_lifo, \
> +    _Scheduler_priority_SMP_Extract, \
> +    _Scheduler_priority_Priority_compare, \
> +    _Scheduler_default_Release_job, \
> +    _Scheduler_default_Tick, \
> +    _Scheduler_SMP_Start_idle \
> +  }
> +
> +void _Scheduler_priority_SMP_Initialize( void );
> +
> +void _Scheduler_priority_SMP_Schedule( Thread_Control *thread );
> +
> +void _Scheduler_priority_SMP_Block( Thread_Control *thread );
> +
> +void _Scheduler_priority_SMP_Update( Thread_Control *thread );
> +
> +void _Scheduler_priority_SMP_Enqueue_fifo( Thread_Control *thread );
> +
> +void _Scheduler_priority_SMP_Enqueue_lifo( Thread_Control *thread );
> +
> +void _Scheduler_priority_SMP_Extract( Thread_Control *thread );
> +
> +void _Scheduler_priority_SMP_Yield( Thread_Control *thread );
> +
> +/** @} */
> +
> +#ifdef __cplusplus
> +}
> +#endif /* __cplusplus */
> +
> +#endif /* _RTEMS_SCORE_SCHEDULERPRIORITYSMP_H */
> diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
> index 4e645f4..79a18b5 100644
> --- a/cpukit/score/preinstall.am
> +++ b/cpukit/score/preinstall.am
> @@ -195,6 +195,10 @@ $(PROJECT_INCLUDE)/rtems/score/schedulerpriorityimpl.h: include/rtems/score/sche
>          $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerpriorityimpl.h
>   PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerpriorityimpl.h
>
> +$(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmp.h: include/rtems/score/schedulerprioritysmp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
> +       $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmp.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmp.h
> +
>   $(PROJECT_INCLUDE)/rtems/score/schedulersimple.h: include/rtems/score/schedulersimple.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
>          $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulersimple.h
>   PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulersimple.h
> diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c
> new file mode 100644
> index 0000000..ae0a1ca
> --- /dev/null
> +++ b/cpukit/score/src/schedulerprioritysmp.c
> @@ -0,0 +1,217 @@
> +/**
> + * @file
> + *
> + * @brief Priority SMP Scheduler Implementation
> + *
> + * @ingroup ScoreSchedulerSMP
> + */
> +
> +/*
> + * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
> + *
> + *  embedded brains GmbH
> + *  Dornierstr. 4
> + *  82178 Puchheim
> + *  Germany
> + *  <rtems at embedded-brains.de>
> + *
> + * The license and distribution terms for this file may be
> + * found in the file LICENSE in this distribution or at
> + * http://www.rtems.com/license/LICENSE.
> + */
> +
> +#if HAVE_CONFIG_H
> +  #include "config.h"
> +#endif
> +
> +#include <rtems/score/schedulerprioritysmp.h>
> +#include <rtems/score/schedulerpriorityimpl.h>
> +#include <rtems/score/schedulersmpimpl.h>
> +#include <rtems/score/wkspace.h>
> +
> +static Scheduler_SMP_Control *_Scheduler_priority_SMP_Instance( void )
> +{
> +  return _Scheduler.information;
> +}
> +
> +void _Scheduler_priority_SMP_Initialize( void )
> +{
> +  Scheduler_SMP_Control *self = _Workspace_Allocate_or_fatal_error(
> +    sizeof( *self ) + PRIORITY_MAXIMUM * sizeof( Chain_Control )
> +  );
> +
> +  _Chain_Initialize_empty( &self->scheduled );
> +  _Scheduler_priority_Ready_queue_initialize( &self->ready[ 0 ] );
> +
> +  _Scheduler.information = self;
> +}
> +
> +void _Scheduler_priority_SMP_Update( Thread_Control *thread )
> +{
> +  Scheduler_SMP_Control *self = _Scheduler_priority_SMP_Instance();
> +
> +  _Scheduler_priority_Update_body( thread, &self->ready[ 0 ] );
> +}
> +
> +static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready(
> +  Scheduler_SMP_Control *self
> +)
> +{
> +  Thread_Control *highest_ready = NULL;
> +
> +  if ( !_Priority_bit_map_Is_empty() ) {
> +    highest_ready = _Scheduler_priority_Ready_queue_first( &self->ready[ 0 ] );
> +  }
> +
> +  return highest_ready;
> +}
> +
> +static void _Scheduler_priority_SMP_Move_from_scheduled_to_ready(
> +  Scheduler_SMP_Control *self,
> +  Thread_Control *scheduled_to_ready
> +)
> +{
> +  _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
> +  _Scheduler_priority_Ready_queue_enqueue_first( scheduled_to_ready );
> +}
> +
> +static void _Scheduler_priority_SMP_Move_from_ready_to_scheduled(
> +  Scheduler_SMP_Control *self,
> +  Thread_Control *ready_to_scheduled
> +)
> +{
> +  _Scheduler_priority_Ready_queue_extract( ready_to_scheduled );
> +  _Scheduler_simple_Insert_priority_fifo(
> +    &self->scheduled,
> +    ready_to_scheduled
> +  );
> +}
> +
> +static void _Scheduler_priority_SMP_Insert_ready_lifo(
> +  Scheduler_SMP_Control *self,
> +  Thread_Control *thread
> +)
> +{
> +  _Scheduler_priority_Ready_queue_enqueue( thread );
> +}
> +
> +static void _Scheduler_priority_SMP_Insert_ready_fifo(
> +  Scheduler_SMP_Control *self,
> +  Thread_Control *thread
> +)
> +{
> +  _Scheduler_priority_Ready_queue_enqueue_first( thread );
> +}
> +
> +static void _Scheduler_priority_SMP_Do_extract(
> +  Scheduler_SMP_Control *self,
> +  Thread_Control *thread
> +)
> +{
> +  bool is_scheduled = thread->is_scheduled;
> +
> +  ( void ) self;
> +
> +  thread->is_in_the_air = is_scheduled;
> +  thread->is_scheduled = false;
> +
> +  if ( is_scheduled ) {
> +    _Chain_Extract_unprotected( &thread->Object.Node );
> +  } else {
> +    _Scheduler_priority_Ready_queue_extract( thread );
> +  }
> +}
> +
> +void _Scheduler_priority_SMP_Block( Thread_Control *thread )
> +{
> +  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
> +
> +  _Scheduler_SMP_Block(
> +    self,
> +    thread,
> +    _Scheduler_priority_SMP_Do_extract,
> +    _Scheduler_priority_SMP_Get_highest_ready,
> +    _Scheduler_priority_SMP_Move_from_ready_to_scheduled
> +  );
> +}
> +
> +static void _Scheduler_priority_SMP_Enqueue_ordered(
> +  Scheduler_SMP_Control *self,
> +  Thread_Control *thread,
> +  Chain_Node_order order,
> +  Scheduler_SMP_Insert insert_ready,
> +  Scheduler_SMP_Insert insert_scheduled
> +)
> +{
> +  _Scheduler_SMP_Enqueue_ordered(
> +    self,
> +    thread,
> +    order,
> +    _Scheduler_priority_SMP_Get_highest_ready,
> +    insert_ready,
> +    insert_scheduled,
> +    _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
> +    _Scheduler_priority_SMP_Move_from_scheduled_to_ready
> +  );
> +}
> +
> +void _Scheduler_priority_SMP_Enqueue_lifo( Thread_Control *thread )
> +{
> +  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
> +
> +  _Scheduler_priority_SMP_Enqueue_ordered(
> +    self,
> +    thread,
> +    _Scheduler_simple_Insert_priority_lifo_order,
> +    _Scheduler_priority_SMP_Insert_ready_lifo,
> +    _Scheduler_SMP_Insert_scheduled_lifo
> +  );
> +}
> +
> +void _Scheduler_priority_SMP_Enqueue_fifo( Thread_Control *thread )
> +{
> +  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
> +
> +  _Scheduler_priority_SMP_Enqueue_ordered(
> +    self,
> +    thread,
> +    _Scheduler_simple_Insert_priority_fifo_order,
> +    _Scheduler_priority_SMP_Insert_ready_fifo,
> +    _Scheduler_SMP_Insert_scheduled_fifo
> +  );
> +}
> +
> +void _Scheduler_priority_SMP_Extract( Thread_Control *thread )
> +{
> +  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
> +
> +  _Scheduler_SMP_Extract(
> +    self,
> +    thread,
> +    _Scheduler_priority_SMP_Do_extract
> +  );
> +}
> +
> +void _Scheduler_priority_SMP_Yield( Thread_Control *thread )
> +{
> +  ISR_Level level;
> +
> +  _ISR_Disable( level );
> +
> +  _Scheduler_priority_SMP_Extract( thread );
> +  _Scheduler_priority_SMP_Enqueue_fifo( thread );
> +
> +  _ISR_Enable( level );
> +}
> +
> +void _Scheduler_priority_SMP_Schedule( Thread_Control *thread )
> +{
> +  Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
> +
> +  _Scheduler_SMP_Schedule(
> +    self,
> +    thread,
> +    _Scheduler_priority_SMP_Get_highest_ready,
> +    _Scheduler_priority_SMP_Move_from_ready_to_scheduled
> +  );
> +}
> diff --git a/cpukit/score/src/schedulerpriorityupdate.c b/cpukit/score/src/schedulerpriorityupdate.c
> index de3f026..062b369 100644
> --- a/cpukit/score/src/schedulerpriorityupdate.c
> +++ b/cpukit/score/src/schedulerpriorityupdate.c
> @@ -25,15 +25,7 @@ void _Scheduler_priority_Update(
>     Thread_Control    *the_thread
>   )
>   {
> -  Scheduler_priority_Per_thread *sched_info_of_thread =
> -    _Scheduler_priority_Get_scheduler_info( the_thread );
>     Chain_Control *ready_queues = _Scheduler_priority_Get_ready_queues();
>
> -  sched_info_of_thread->ready_chain =
> -    &ready_queues[ the_thread->current_priority ];
> -
> -  _Priority_bit_map_Initialize_information(
> -    &sched_info_of_thread->Priority_map,
> -    the_thread->current_priority
> -  );
> +  _Scheduler_priority_Update_body( the_thread, ready_queues );
>   }
> diff --git a/testsuites/smptests/smpmigration01/smpmigration01.scn b/testsuites/smptests/smpmigration01/smpmigration01.scn
> index c5a2106..b2b56ff 100644
> --- a/testsuites/smptests/smpmigration01/smpmigration01.scn
> +++ b/testsuites/smptests/smpmigration01/smpmigration01.scn
> @@ -1,17 +1,17 @@
>   *** TEST SMPMIGRATION 1 ***
>   runner 0
> -        cpu 0 tokens 530399
> -        cpu 0 cycles 10077490
> -        cpu 1 tokens 530399
> -        cpu 1 cycles 10071429
> +        cpu 0 tokens 453284
> +        cpu 0 cycles 14955317
> +        cpu 1 tokens 453283
> +        cpu 1 cycles 14978390
>   runner 1
> -        cpu 0 tokens 530399
> -        cpu 0 cycles 5978212
> -        cpu 1 tokens 530399
> -        cpu 1 cycles 7951897
> +        cpu 0 tokens 453283
> +        cpu 0 cycles 21302793
> +        cpu 1 tokens 453283
> +        cpu 1 cycles 21318817
>   runner 2
> -        cpu 0 tokens 530399
> -        cpu 0 cycles 10070929
> -        cpu 1 tokens 530398
> -        cpu 1 cycles 10106437
> +        cpu 0 tokens 453283
> +        cpu 0 cycles 19973312
> +        cpu 1 tokens 453283
> +        cpu 1 cycles 21315227
>   *** END OF TEST SMPMIGRATION 1 ***
> --
> 1.7.7
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel


-- 
Joel Sherrill, Ph.D.             Director of Research & Development
joel.sherrill at OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
Support Available                (256) 722-9985




More information about the devel mailing list