[PATCH 3/6] score: Add SMP EDF scheduler

Joel Sherrill joel at rtems.org
Thu Jun 29 14:43:00 UTC 2017


There has to be a corresponding documentation patch.

--joel

On Thu, Jun 29, 2017 at 8:23 AM, Sebastian Huber <
sebastian.huber at embedded-brains.de> wrote:

> Update #3056.
> ---
>  cpukit/sapi/include/confdefs.h                     |  24 +
>  cpukit/sapi/include/rtems/scheduler.h              |  20 +-
>  cpukit/score/Makefile.am                           |   2 +
>  cpukit/score/include/rtems/score/scheduleredfsmp.h | 137 ++++++
>  cpukit/score/preinstall.am                         |   4 +
>  cpukit/score/src/scheduleredfchangepriority.c      |  16 -
>  cpukit/score/src/scheduleredfreleasejob.c          |  16 +
>  cpukit/score/src/scheduleredfsmp.c                 | 499
> +++++++++++++++++++++
>  testsuites/smptests/Makefile.am                    |   1 +
>  testsuites/smptests/configure.ac                   |   1 +
>  testsuites/smptests/smpscheduler03/test.c          |   5 +
>  testsuites/smptests/smpscheduler07/Makefile.am     |  19 +
>  testsuites/smptests/smpscheduler07/init.c          |  51 +++
>  .../smptests/smpscheduler07/smpscheduler07.doc     |  11 +
>  .../smptests/smpscheduler07/smpscheduler07.scn     |   2 +
>  15 files changed, 791 insertions(+), 17 deletions(-)
>  create mode 100644 cpukit/score/include/rtems/score/scheduleredfsmp.h
>  create mode 100644 cpukit/score/src/scheduleredfsmp.c
>  create mode 100644 testsuites/smptests/smpscheduler07/Makefile.am
>  create mode 100644 testsuites/smptests/smpscheduler07/init.c
>  create mode 100644 testsuites/smptests/smpscheduler07/smpscheduler07.doc
>  create mode 100644 testsuites/smptests/smpscheduler07/smpscheduler07.scn
>
> diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/
> confdefs.h
> index 604539b5e8..77b80d1cce 100755
> --- a/cpukit/sapi/include/confdefs.h
> +++ b/cpukit/sapi/include/confdefs.h
> @@ -780,6 +780,7 @@ extern rtems_initialization_tasks_table
> Initialization_tasks[];
>   *  - CONFIGURE_SCHEDULER_SIMPLE - Light-weight Priority Scheduler
>   *  - CONFIGURE_SCHEDULER_SIMPLE_SMP - Simple SMP Priority Scheduler
>   *  - CONFIGURE_SCHEDULER_EDF - EDF Scheduler
> + *  - CONFIGURE_SCHEDULER_EDF_SMP - EDF SMP Scheduler
>   *  - CONFIGURE_SCHEDULER_CBS - CBS Scheduler
>   *  - CONFIGURE_SCHEDULER_USER  - user provided scheduler
>   *
> @@ -805,6 +806,7 @@ extern rtems_initialization_tasks_table
> Initialization_tasks[];
>      !defined(CONFIGURE_SCHEDULER_SIMPLE) && \
>      !defined(CONFIGURE_SCHEDULER_SIMPLE_SMP) && \
>      !defined(CONFIGURE_SCHEDULER_EDF) && \
> +    !defined(CONFIGURE_SCHEDULER_EDF_SMP) && \
>      !defined(CONFIGURE_SCHEDULER_CBS)
>    #if defined(RTEMS_SMP) && CONFIGURE_MAXIMUM_PROCESSORS > 1
>      /**
> @@ -980,6 +982,25 @@ extern rtems_initialization_tasks_table
> Initialization_tasks[];
>  #endif
>
>  /*
> + * If the EDF SMP Scheduler is selected, then configure for it.
> + */
> +#if defined(CONFIGURE_SCHEDULER_EDF_SMP)
> +  #if !defined(CONFIGURE_SCHEDULER_NAME)
> +    /** Configure the name of the scheduler instance */
> +    #define CONFIGURE_SCHEDULER_NAME rtems_build_name('M', 'E', 'D', 'F')
> +  #endif
> +
> +  #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
> +    /** Configure the context needed by the scheduler instance */
> +    #define CONFIGURE_SCHEDULER_CONTEXT RTEMS_SCHEDULER_CONTEXT_EDF_
> SMP(dflt)
> +
> +    /** Configure the controls for this scheduler instance */
> +    #define CONFIGURE_SCHEDULER_CONTROLS \
> +      RTEMS_SCHEDULER_CONTROL_EDF_SMP(dflt, CONFIGURE_SCHEDULER_NAME)
> +  #endif
> +#endif
> +
> +/*
>   * If the CBS Scheduler is selected, then configure for it.
>   */
>  #if defined(CONFIGURE_SCHEDULER_CBS)
> @@ -3151,6 +3172,9 @@ extern rtems_initialization_tasks_table
> Initialization_tasks[];
>      #ifdef CONFIGURE_SCHEDULER_EDF
>        Scheduler_EDF_Node EDF;
>      #endif
> +    #ifdef CONFIGURE_SCHEDULER_EDF_SMP
> +      Scheduler_EDF_SMP_Node EDF_SMP;
> +    #endif
>      #ifdef CONFIGURE_SCHEDULER_PRIORITY
>        Scheduler_priority_Node Priority;
>      #endif
> diff --git a/cpukit/sapi/include/rtems/scheduler.h
> b/cpukit/sapi/include/rtems/scheduler.h
> index 0b20aab55e..fae0db4913 100644
> --- a/cpukit/sapi/include/rtems/scheduler.h
> +++ b/cpukit/sapi/include/rtems/scheduler.h
> @@ -5,7 +5,7 @@
>   */
>
>  /*
> - * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
> + * Copyright (c) 2014, 2017 embedded brains GmbH.  All rights reserved.
>   *
>   *  embedded brains GmbH
>   *  Dornierstr. 4
> @@ -93,6 +93,24 @@
>      }
>  #endif
>
> +#ifdef CONFIGURE_SCHEDULER_EDF_SMP
> +  #include <rtems/score/scheduleredfsmp.h>
> +
> +  #define RTEMS_SCHEDULER_CONTEXT_EDF_SMP_NAME( name ) \
> +    RTEMS_SCHEDULER_CONTEXT_NAME( EDF_SMP_ ## name )
> +
> +  #define RTEMS_SCHEDULER_CONTEXT_EDF_SMP( name ) \
> +    static Scheduler_EDF_SMP_Context RTEMS_SCHEDULER_CONTEXT_EDF_SMP_NAME(
> name )
> +
> +  #define RTEMS_SCHEDULER_CONTROL_EDF_SMP( name, obj_name ) \
> +    { \
> +      &RTEMS_SCHEDULER_CONTEXT_EDF_SMP_NAME( name ).Base.Base, \
> +      SCHEDULER_EDF_SMP_ENTRY_POINTS, \
> +      SCHEDULER_EDF_MAXIMUM_PRIORITY, \
> +      ( obj_name ) \
> +    }
> +#endif
> +
>  #ifdef CONFIGURE_SCHEDULER_PRIORITY
>    #include <rtems/score/schedulerpriority.h>
>
> diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
> index a3de792fdf..46b441737f 100644
> --- a/cpukit/score/Makefile.am
> +++ b/cpukit/score/Makefile.am
> @@ -126,6 +126,7 @@ include_rtems_score_HEADERS +=
> include/rtems/score/threadmp.h
>  endif
>
>  if HAS_SMP
> +include_rtems_score_HEADERS += include/rtems/score/scheduleredfsmp.h
>  include_rtems_score_HEADERS += include/rtems/score/
> schedulerprioritysmpimpl.h
>  include_rtems_score_HEADERS += include/rtems/score/
> schedulerpriorityaffinitysmp.h
>  include_rtems_score_HEADERS += include/rtems/score/schedulersimplesmp.h
> @@ -149,6 +150,7 @@ endif
>  if HAS_SMP
>  libscore_a_SOURCES += src/percpustatewait.c
>  libscore_a_SOURCES += src/profilingsmplock.c
> +libscore_a_SOURCES += src/scheduleredfsmp.c
>  libscore_a_SOURCES += src/schedulerpriorityaffinitysmp.c
>  libscore_a_SOURCES += src/schedulerprioritysmp.c
>  libscore_a_SOURCES += src/schedulersimplesmp.c
> diff --git a/cpukit/score/include/rtems/score/scheduleredfsmp.h
> b/cpukit/score/include/rtems/score/scheduleredfsmp.h
> new file mode 100644
> index 0000000000..8f6e85777a
> --- /dev/null
> +++ b/cpukit/score/include/rtems/score/scheduleredfsmp.h
> @@ -0,0 +1,137 @@
> +/**
> + * @file
> + *
> + * @brief EDF SMP Scheduler API
> + *
> + * @ingroup ScoreSchedulerSMPEDF
> + */
> +
> +/*
> + * Copyright (c) 2017 embedded brains GmbH.
> + *
> + * The license and distribution terms for this file may be
> + * found in the file LICENSE in this distribution or at
> + * http://www.rtems.org/license/LICENSE.
> + */
> +
> +#ifndef _RTEMS_SCORE_SCHEDULEREDFSMP_H
> +#define _RTEMS_SCORE_SCHEDULEREDFSMP_H
> +
> +#include <rtems/score/scheduler.h>
> +#include <rtems/score/scheduleredf.h>
> +#include <rtems/score/schedulersmp.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * @defgroup ScoreSchedulerSMPEDF EDF Priority SMP Scheduler
> + *
> + * @ingroup ScoreSchedulerSMP
> + *
> + * @{
> + */
> +
> +typedef struct {
> +  Scheduler_SMP_Context Base;
> +  RBTree_Control        Ready;
> +} Scheduler_EDF_SMP_Context;
> +
> +typedef struct {
> +  Scheduler_SMP_Node Base;
> +} Scheduler_EDF_SMP_Node;
> +
> +#define SCHEDULER_EDF_SMP_ENTRY_POINTS \
> +  { \
> +    _Scheduler_EDF_SMP_Initialize, \
> +    _Scheduler_default_Schedule, \
> +    _Scheduler_EDF_SMP_Yield, \
> +    _Scheduler_EDF_SMP_Block, \
> +    _Scheduler_EDF_SMP_Unblock, \
> +    _Scheduler_EDF_SMP_Update_priority, \
> +    _Scheduler_EDF_Map_priority, \
> +    _Scheduler_EDF_Unmap_priority, \
> +    _Scheduler_EDF_SMP_Ask_for_help, \
> +    _Scheduler_EDF_SMP_Reconsider_help_request, \
> +    _Scheduler_EDF_SMP_Withdraw_node, \
> +    _Scheduler_EDF_SMP_Add_processor, \
> +    _Scheduler_EDF_SMP_Remove_processor, \
> +    _Scheduler_EDF_SMP_Node_initialize, \
> +    _Scheduler_default_Node_destroy, \
> +    _Scheduler_EDF_Release_job, \
> +    _Scheduler_EDF_Cancel_job, \
> +    _Scheduler_default_Tick, \
> +    _Scheduler_SMP_Start_idle \
> +    SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
> +  }
> +
> +void _Scheduler_EDF_SMP_Initialize( const Scheduler_Control *scheduler );
> +
> +void _Scheduler_EDF_SMP_Node_initialize(
> +  const Scheduler_Control *scheduler,
> +  Scheduler_Node          *node,
> +  Thread_Control          *the_thread,
> +  Priority_Control         priority
> +);
> +
> +void _Scheduler_EDF_SMP_Block(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *thread,
> +  Scheduler_Node          *node
> +);
> +
> +void _Scheduler_EDF_SMP_Unblock(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *thread,
> +  Scheduler_Node          *node
> +);
> +
> +void _Scheduler_EDF_SMP_Update_priority(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Scheduler_Node          *node
> +);
> +
> +bool _Scheduler_EDF_SMP_Ask_for_help(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Scheduler_Node          *node
> +);
> +
> +void _Scheduler_EDF_SMP_Reconsider_help_request(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Scheduler_Node          *node
> +);
> +
> +void _Scheduler_EDF_SMP_Withdraw_node(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Scheduler_Node          *node,
> +  Thread_Scheduler_state   next_state
> +);
> +
> +void _Scheduler_EDF_SMP_Add_processor(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *idle
> +);
> +
> +Thread_Control *_Scheduler_EDF_SMP_Remove_processor(
> +  const Scheduler_Control *scheduler,
> +  struct Per_CPU_Control  *cpu
> +);
> +
> +void _Scheduler_EDF_SMP_Yield(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *thread,
> +  Scheduler_Node          *node
> +);
> +
> +/** @} */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTEMS_SCORE_SCHEDULEREDFSMP_H */
> diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
> index 4d468e5dde..da231541b0 100644
> --- a/cpukit/score/preinstall.am
> +++ b/cpukit/score/preinstall.am
> @@ -439,6 +439,10 @@ $(PROJECT_INCLUDE)/rtems/score/threadmp.h:
> include/rtems/score/threadmp.h $(PROJ
>  PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/threadmp.h
>  endif
>  if HAS_SMP
> +$(PROJECT_INCLUDE)/rtems/score/scheduleredfsmp.h: include/rtems/score/scheduleredfsmp.h
> $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
> +       $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/
> score/scheduleredfsmp.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduleredfsmp.h
> +
>  $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmpimpl.h:
> include/rtems/score/schedulerprioritysmpimpl.h $(PROJECT_INCLUDE)/rtems/
> score/$(dirstamp)
>         $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/
> schedulerprioritysmpimpl.h
>  PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/
> schedulerprioritysmpimpl.h
> diff --git a/cpukit/score/src/scheduleredfchangepriority.c
> b/cpukit/score/src/scheduleredfchangepriority.c
> index 0b70bce012..23382973cc 100644
> --- a/cpukit/score/src/scheduleredfchangepriority.c
> +++ b/cpukit/score/src/scheduleredfchangepriority.c
> @@ -20,22 +20,6 @@
>
>  #include <rtems/score/scheduleredfimpl.h>
>
> -Priority_Control _Scheduler_EDF_Map_priority(
> -  const Scheduler_Control *scheduler,
> -  Priority_Control         priority
> -)
> -{
> -  return SCHEDULER_EDF_PRIO_MSB | priority;
> -}
> -
> -Priority_Control _Scheduler_EDF_Unmap_priority(
> -  const Scheduler_Control *scheduler,
> -  Priority_Control         priority
> -)
> -{
> -  return priority & ~SCHEDULER_EDF_PRIO_MSB;
> -}
> -
>  void _Scheduler_EDF_Update_priority(
>    const Scheduler_Control *scheduler,
>    Thread_Control          *the_thread,
> diff --git a/cpukit/score/src/scheduleredfreleasejob.c b/cpukit/score/src/
> scheduleredfreleasejob.c
> index c19d9b9d24..068a0db7a3 100644
> --- a/cpukit/score/src/scheduleredfreleasejob.c
> +++ b/cpukit/score/src/scheduleredfreleasejob.c
> @@ -20,6 +20,22 @@
>
>  #include <rtems/score/scheduleredfimpl.h>
>
> +Priority_Control _Scheduler_EDF_Map_priority(
> +  const Scheduler_Control *scheduler,
> +  Priority_Control         priority
> +)
> +{
> +  return SCHEDULER_EDF_PRIO_MSB | priority;
> +}
> +
> +Priority_Control _Scheduler_EDF_Unmap_priority(
> +  const Scheduler_Control *scheduler,
> +  Priority_Control         priority
> +)
> +{
> +  return priority & ~SCHEDULER_EDF_PRIO_MSB;
> +}
> +
>  void _Scheduler_EDF_Release_job(
>    const Scheduler_Control *scheduler,
>    Thread_Control          *the_thread,
> diff --git a/cpukit/score/src/scheduleredfsmp.c b/cpukit/score/src/
> scheduleredfsmp.c
> new file mode 100644
> index 0000000000..270f9a44e9
> --- /dev/null
> +++ b/cpukit/score/src/scheduleredfsmp.c
> @@ -0,0 +1,499 @@
> +/**
> + * @file
> + *
> + * @brief EDF SMP Scheduler Implementation
> + *
> + * @ingroup ScoreSchedulerSMPEDF
> + */
> +
> +/*
> + * Copyright (c) 2017 embedded brains GmbH.
> + *
> + * The license and distribution terms for this file may be
> + * found in the file LICENSE in this distribution or at
> + * http://www.rtems.org/license/LICENSE.
> + */
> +
> +#if HAVE_CONFIG_H
> +  #include "config.h"
> +#endif
> +
> +#include <rtems/score/scheduleredfsmp.h>
> +#include <rtems/score/schedulersmpimpl.h>
> +
> +static Scheduler_EDF_SMP_Context *
> +_Scheduler_EDF_SMP_Get_context( const Scheduler_Control *scheduler )
> +{
> +  return (Scheduler_EDF_SMP_Context *) _Scheduler_Get_context( scheduler
> );
> +}
> +
> +static Scheduler_EDF_SMP_Context *
> +_Scheduler_EDF_SMP_Get_self( Scheduler_Context *context )
> +{
> +  return (Scheduler_EDF_SMP_Context *) context;
> +}
> +
> +static inline Scheduler_EDF_SMP_Node *
> +_Scheduler_EDF_SMP_Node_downcast( Scheduler_Node *node )
> +{
> +  return (Scheduler_EDF_SMP_Node *) node;
> +}
> +
> +static inline bool _Scheduler_EDF_SMP_Less(
> +  const void        *left,
> +  const RBTree_Node *right
> +)
> +{
> +  const Priority_Control   *the_left;
> +  const Scheduler_SMP_Node *the_right;
> +  Priority_Control          prio_left;
> +  Priority_Control          prio_right;
> +
> +  the_left = left;
> +  the_right = RTEMS_CONTAINER_OF( right, Scheduler_SMP_Node,
> Base.Node.RBTree );
> +
> +  prio_left = *the_left;
> +  prio_right = the_right->priority;
> +
> +  return prio_left < prio_right;
> +}
> +
> +static inline bool _Scheduler_EDF_SMP_Less_or_equal(
> +  const void        *left,
> +  const RBTree_Node *right
> +)
> +{
> +  const Priority_Control   *the_left;
> +  const Scheduler_SMP_Node *the_right;
> +  Priority_Control          prio_left;
> +  Priority_Control          prio_right;
> +
> +  the_left = left;
> +  the_right = RTEMS_CONTAINER_OF( right, Scheduler_SMP_Node,
> Base.Node.RBTree );
> +
> +  prio_left = *the_left;
> +  prio_right = the_right->priority;
> +
> +  return prio_left <= prio_right;
> +}
> +
> +void _Scheduler_EDF_SMP_Initialize( const Scheduler_Control *scheduler )
> +{
> +  Scheduler_EDF_SMP_Context *self =
> +    _Scheduler_EDF_SMP_Get_context( scheduler );
> +
> +  _Scheduler_SMP_Initialize( &self->Base );
> +  _RBTree_Initialize_empty( &self->Ready );
> +}
> +
> +void _Scheduler_EDF_SMP_Node_initialize(
> +  const Scheduler_Control *scheduler,
> +  Scheduler_Node          *node,
> +  Thread_Control          *the_thread,
> +  Priority_Control         priority
> +)
> +{
> +  Scheduler_SMP_Node *smp_node;
> +
> +  smp_node = _Scheduler_SMP_Node_downcast( node );
> +  _Scheduler_SMP_Node_initialize( scheduler, smp_node, the_thread,
> priority );
> +}
> +
> +static void _Scheduler_EDF_SMP_Do_update(
> +  Scheduler_Context *context,
> +  Scheduler_Node    *node,
> +  Priority_Control   new_priority
> +)
> +{
> +  Scheduler_SMP_Node *smp_node;
> +
> +  (void) context;
> +
> +  smp_node = _Scheduler_SMP_Node_downcast( node );
> +  _Scheduler_SMP_Node_update_priority( smp_node, new_priority );
> +}
> +
> +static bool _Scheduler_EDF_SMP_Has_ready( Scheduler_Context *context )
> +{
> +  Scheduler_EDF_SMP_Context *self =
> +    _Scheduler_EDF_SMP_Get_self( context );
> +
> +  return !_RBTree_Is_empty( &self->Ready );
> +}
> +
> +static Scheduler_Node *_Scheduler_EDF_SMP_Get_highest_ready(
> +  Scheduler_Context *context,
> +  Scheduler_Node    *node
> +)
> +{
> +  Scheduler_EDF_SMP_Context *self =
> +    _Scheduler_EDF_SMP_Get_self( context );
> +  Scheduler_Node *first = (Scheduler_Node *) _RBTree_Minimum(
> &self->Ready );
> +
> +  (void) node;
> +
> +  _Assert( &first->Node != NULL );
> +
> +  return first;
> +}
> +
> +static void _Scheduler_EDF_SMP_Move_from_scheduled_to_ready(
> +  Scheduler_Context *context,
> +  Scheduler_Node    *scheduled_to_ready
> +)
> +{
> +  Scheduler_EDF_SMP_Context *self =
> +    _Scheduler_EDF_SMP_Get_self( context );
> +  Scheduler_EDF_SMP_Node *node =
> +    _Scheduler_EDF_SMP_Node_downcast( scheduled_to_ready );
> +
> +  _Chain_Extract_unprotected( &node->Base.Base.Node.Chain );
> +  _RBTree_Initialize_node( &node->Base.Base.Node.RBTree );
> +  _RBTree_Insert_inline(
> +    &self->Ready,
> +    &node->Base.Base.Node.RBTree,
> +    &node->Base.priority,
> +    _Scheduler_EDF_SMP_Less
> +  );
> +}
> +
> +static void _Scheduler_EDF_SMP_Move_from_ready_to_scheduled(
> +  Scheduler_Context *context,
> +  Scheduler_Node    *ready_to_scheduled
> +)
> +{
> +  Scheduler_EDF_SMP_Context *self =
> +    _Scheduler_EDF_SMP_Get_self( context );
> +  Scheduler_EDF_SMP_Node *node =
> +    _Scheduler_EDF_SMP_Node_downcast( ready_to_scheduled );
> +
> +  _RBTree_Extract( &self->Ready, &node->Base.Base.Node.RBTree );
> +  _Chain_Initialize_node( &node->Base.Base.Node.Chain );
> +  _Chain_Insert_ordered_unprotected(
> +    &self->Base.Scheduled,
> +    &node->Base.Base.Node.Chain,
> +    _Scheduler_SMP_Insert_priority_fifo_order
> +  );
> +}
> +
> +static void _Scheduler_EDF_SMP_Insert_ready_lifo(
> +  Scheduler_Context *context,
> +  Scheduler_Node    *node_to_insert
> +)
> +{
> +  Scheduler_EDF_SMP_Context *self =
> +    _Scheduler_EDF_SMP_Get_self( context );
> +  Scheduler_EDF_SMP_Node *node =
> +    _Scheduler_EDF_SMP_Node_downcast( node_to_insert );
> +
> +  _RBTree_Initialize_node( &node->Base.Base.Node.RBTree );
> +  _RBTree_Insert_inline(
> +    &self->Ready,
> +    &node->Base.Base.Node.RBTree,
> +    &node->Base.priority,
> +    _Scheduler_EDF_SMP_Less_or_equal
> +  );
> +}
> +
> +static void _Scheduler_EDF_SMP_Insert_ready_fifo(
> +  Scheduler_Context *context,
> +  Scheduler_Node    *node_to_insert
> +)
> +{
> +  Scheduler_EDF_SMP_Context *self =
> +    _Scheduler_EDF_SMP_Get_self( context );
> +  Scheduler_EDF_SMP_Node *node =
> +    _Scheduler_EDF_SMP_Node_downcast( node_to_insert );
> +
> +  _RBTree_Initialize_node( &node->Base.Base.Node.RBTree );
> +  _RBTree_Insert_inline(
> +    &self->Ready,
> +    &node->Base.Base.Node.RBTree,
> +    &node->Base.priority,
> +    _Scheduler_EDF_SMP_Less
> +  );
> +}
> +
> +static void _Scheduler_EDF_SMP_Extract_from_ready(
> +  Scheduler_Context *context,
> +  Scheduler_Node    *node_to_extract
> +)
> +{
> +  Scheduler_EDF_SMP_Context *self =
> +    _Scheduler_EDF_SMP_Get_self( context );
> +  Scheduler_EDF_SMP_Node *node =
> +    _Scheduler_EDF_SMP_Node_downcast( node_to_extract );
> +
> +  _RBTree_Extract( &self->Ready, &node->Base.Base.Node.RBTree );
> +  _Chain_Initialize_node( &node->Base.Base.Node.Chain );
> +}
> +
> +void _Scheduler_EDF_SMP_Block(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *thread,
> +  Scheduler_Node          *node
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_SMP_Block(
> +    context,
> +    thread,
> +    node,
> +    _Scheduler_EDF_SMP_Extract_from_ready,
> +    _Scheduler_EDF_SMP_Get_highest_ready,
> +    _Scheduler_EDF_SMP_Move_from_ready_to_scheduled,
> +    _Scheduler_SMP_Allocate_processor_lazy
> +  );
> +}
> +
> +static bool _Scheduler_EDF_SMP_Enqueue_ordered(
> +  Scheduler_Context    *context,
> +  Scheduler_Node       *node,
> +  Chain_Node_order      order,
> +  Scheduler_SMP_Insert  insert_ready,
> +  Scheduler_SMP_Insert  insert_scheduled
> +)
> +{
> +  return _Scheduler_SMP_Enqueue_ordered(
> +    context,
> +    node,
> +    order,
> +    insert_ready,
> +    insert_scheduled,
> +    _Scheduler_EDF_SMP_Move_from_scheduled_to_ready,
> +    _Scheduler_SMP_Get_lowest_scheduled,
> +    _Scheduler_SMP_Allocate_processor_lazy
> +  );
> +}
> +
> +static bool _Scheduler_EDF_SMP_Enqueue_lifo(
> +  Scheduler_Context *context,
> +  Scheduler_Node    *node
> +)
> +{
> +  return _Scheduler_EDF_SMP_Enqueue_ordered(
> +    context,
> +    node,
> +    _Scheduler_SMP_Insert_priority_lifo_order,
> +    _Scheduler_EDF_SMP_Insert_ready_lifo,
> +    _Scheduler_SMP_Insert_scheduled_lifo
> +  );
> +}
> +
> +static bool _Scheduler_EDF_SMP_Enqueue_fifo(
> +  Scheduler_Context *context,
> +  Scheduler_Node    *node
> +)
> +{
> +  return _Scheduler_EDF_SMP_Enqueue_ordered(
> +    context,
> +    node,
> +    _Scheduler_SMP_Insert_priority_fifo_order,
> +    _Scheduler_EDF_SMP_Insert_ready_fifo,
> +    _Scheduler_SMP_Insert_scheduled_fifo
> +  );
> +}
> +
> +static bool _Scheduler_EDF_SMP_Enqueue_scheduled_ordered(
> +  Scheduler_Context *context,
> +  Scheduler_Node *node,
> +  Chain_Node_order order,
> +  Scheduler_SMP_Insert insert_ready,
> +  Scheduler_SMP_Insert insert_scheduled
> +)
> +{
> +  return _Scheduler_SMP_Enqueue_scheduled_ordered(
> +    context,
> +    node,
> +    order,
> +    _Scheduler_EDF_SMP_Extract_from_ready,
> +    _Scheduler_EDF_SMP_Get_highest_ready,
> +    insert_ready,
> +    insert_scheduled,
> +    _Scheduler_EDF_SMP_Move_from_ready_to_scheduled,
> +    _Scheduler_SMP_Allocate_processor_lazy
> +  );
> +}
> +
> +static bool _Scheduler_EDF_SMP_Enqueue_scheduled_lifo(
> +  Scheduler_Context *context,
> +  Scheduler_Node *node
> +)
> +{
> +  return _Scheduler_EDF_SMP_Enqueue_scheduled_ordered(
> +    context,
> +    node,
> +    _Scheduler_SMP_Insert_priority_lifo_order,
> +    _Scheduler_EDF_SMP_Insert_ready_lifo,
> +    _Scheduler_SMP_Insert_scheduled_lifo
> +  );
> +}
> +
> +static bool _Scheduler_EDF_SMP_Enqueue_scheduled_fifo(
> +  Scheduler_Context *context,
> +  Scheduler_Node *node
> +)
> +{
> +  return _Scheduler_EDF_SMP_Enqueue_scheduled_ordered(
> +    context,
> +    node,
> +    _Scheduler_SMP_Insert_priority_fifo_order,
> +    _Scheduler_EDF_SMP_Insert_ready_fifo,
> +    _Scheduler_SMP_Insert_scheduled_fifo
> +  );
> +}
> +
> +void _Scheduler_EDF_SMP_Unblock(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *thread,
> +  Scheduler_Node          *node
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_SMP_Unblock(
> +    context,
> +    thread,
> +    node,
> +    _Scheduler_EDF_SMP_Do_update,
> +    _Scheduler_EDF_SMP_Enqueue_fifo
> +  );
> +}
> +
> +static bool _Scheduler_EDF_SMP_Do_ask_for_help(
> +  Scheduler_Context *context,
> +  Thread_Control    *the_thread,
> +  Scheduler_Node    *node
> +)
> +{
> +  return _Scheduler_SMP_Ask_for_help(
> +    context,
> +    the_thread,
> +    node,
> +    _Scheduler_SMP_Insert_priority_lifo_order,
> +    _Scheduler_EDF_SMP_Insert_ready_lifo,
> +    _Scheduler_SMP_Insert_scheduled_lifo,
> +    _Scheduler_EDF_SMP_Move_from_scheduled_to_ready,
> +    _Scheduler_SMP_Get_lowest_scheduled,
> +    _Scheduler_SMP_Allocate_processor_lazy
> +  );
> +}
> +
> +void _Scheduler_EDF_SMP_Update_priority(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *thread,
> +  Scheduler_Node          *node
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_SMP_Update_priority(
> +    context,
> +    thread,
> +    node,
> +    _Scheduler_EDF_SMP_Extract_from_ready,
> +    _Scheduler_EDF_SMP_Do_update,
> +    _Scheduler_EDF_SMP_Enqueue_fifo,
> +    _Scheduler_EDF_SMP_Enqueue_lifo,
> +    _Scheduler_EDF_SMP_Enqueue_scheduled_fifo,
> +    _Scheduler_EDF_SMP_Enqueue_scheduled_lifo,
> +    _Scheduler_EDF_SMP_Do_ask_for_help
> +  );
> +}
> +
> +bool _Scheduler_EDF_SMP_Ask_for_help(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Scheduler_Node          *node
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  return _Scheduler_EDF_SMP_Do_ask_for_help( context, the_thread, node );
> +}
> +
> +void _Scheduler_EDF_SMP_Reconsider_help_request(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Scheduler_Node          *node
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_SMP_Reconsider_help_request(
> +    context,
> +    the_thread,
> +    node,
> +    _Scheduler_EDF_SMP_Extract_from_ready
> +  );
> +}
> +
> +void _Scheduler_EDF_SMP_Withdraw_node(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *the_thread,
> +  Scheduler_Node          *node,
> +  Thread_Scheduler_state   next_state
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_SMP_Withdraw_node(
> +    context,
> +    the_thread,
> +    node,
> +    next_state,
> +    _Scheduler_EDF_SMP_Extract_from_ready,
> +    _Scheduler_EDF_SMP_Get_highest_ready,
> +    _Scheduler_EDF_SMP_Move_from_ready_to_scheduled,
> +    _Scheduler_SMP_Allocate_processor_lazy
> +  );
> +}
> +
> +void _Scheduler_EDF_SMP_Add_processor(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *idle
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_SMP_Add_processor(
> +    context,
> +    idle,
> +    _Scheduler_EDF_SMP_Has_ready,
> +    _Scheduler_EDF_SMP_Enqueue_scheduled_fifo
> +  );
> +}
> +
> +Thread_Control *_Scheduler_EDF_SMP_Remove_processor(
> +  const Scheduler_Control *scheduler,
> +  Per_CPU_Control         *cpu
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  return _Scheduler_SMP_Remove_processor(
> +    context,
> +    cpu,
> +    _Scheduler_EDF_SMP_Extract_from_ready,
> +    _Scheduler_EDF_SMP_Enqueue_fifo
> +  );
> +}
> +
> +void _Scheduler_EDF_SMP_Yield(
> +  const Scheduler_Control *scheduler,
> +  Thread_Control          *thread,
> +  Scheduler_Node          *node
> +)
> +{
> +  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
> +
> +  _Scheduler_SMP_Yield(
> +    context,
> +    thread,
> +    node,
> +    _Scheduler_EDF_SMP_Extract_from_ready,
> +    _Scheduler_EDF_SMP_Enqueue_fifo,
> +    _Scheduler_EDF_SMP_Enqueue_scheduled_fifo
> +  );
> +}
> diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/
> Makefile.am
> index 3df76c1d67..6c1bd1294f 100644
> --- a/testsuites/smptests/Makefile.am
> +++ b/testsuites/smptests/Makefile.am
> @@ -42,6 +42,7 @@ _SUBDIRS += smpscheduler03
>  _SUBDIRS += smpscheduler04
>  _SUBDIRS += smpscheduler05
>  _SUBDIRS += smpscheduler06
> +_SUBDIRS += smpscheduler07
>  _SUBDIRS += smpsignal01
>  _SUBDIRS += smpstrongapa01
>  _SUBDIRS += smpswitchextension01
> diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/
> configure.ac
> index 54a75f777d..59b27ef397 100644
> --- a/testsuites/smptests/configure.ac
> +++ b/testsuites/smptests/configure.ac
> @@ -97,6 +97,7 @@ smpscheduler03/Makefile
>  smpscheduler04/Makefile
>  smpscheduler05/Makefile
>  smpscheduler06/Makefile
> +smpscheduler07/Makefile
>  smpsignal01/Makefile
>  smpstrongapa01/Makefile
>  smpswitchextension01/Makefile
> diff --git a/testsuites/smptests/smpscheduler03/test.c
> b/testsuites/smptests/smpscheduler03/test.c
> index 32bd67cdc2..3f6b9e3fd8 100644
> --- a/testsuites/smptests/smpscheduler03/test.c
> +++ b/testsuites/smptests/smpscheduler03/test.c
> @@ -37,6 +37,11 @@ static void apply_priority(
>    Thread_queue_Context *queue_context
>  )
>  {
> +  const Scheduler_Control *scheduler;
> +
> +  scheduler = _Thread_Scheduler_get_home(thread);
> +  new_priority = _Scheduler_Map_priority(scheduler, new_priority);
> +
>    _Thread_queue_Context_initialize(queue_context);
>    _Thread_queue_Context_clear_priority_updates(queue_context);
>    _Thread_Wait_acquire(thread, queue_context);
> diff --git a/testsuites/smptests/smpscheduler07/Makefile.am
> b/testsuites/smptests/smpscheduler07/Makefile.am
> new file mode 100644
> index 0000000000..f981544628
> --- /dev/null
> +++ b/testsuites/smptests/smpscheduler07/Makefile.am
> @@ -0,0 +1,19 @@
> +rtems_tests_PROGRAMS = smpscheduler07
> +smpscheduler07_SOURCES = init.c ../smpscheduler03/test.c
> +
> +dist_rtems_tests_DATA = smpscheduler07.scn smpscheduler07.doc
> +
> +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
> +include $(top_srcdir)/../automake/compile.am
> +include $(top_srcdir)/../automake/leaf.am
> +
> +AM_CPPFLAGS += -I$(top_srcdir)/../support/include
> +
> +LINK_OBJS = $(smpscheduler07_OBJECTS)
> +LINK_LIBS = $(smpscheduler07_LDLIBS)
> +
> +smpscheduler07$(EXEEXT): $(smpscheduler07_OBJECTS)
> $(smpscheduler07_DEPENDENCIES)
> +       @rm -f smpscheduler07$(EXEEXT)
> +       $(make-exe)
> +
> +include $(top_srcdir)/../automake/local.am
> diff --git a/testsuites/smptests/smpscheduler07/init.c
> b/testsuites/smptests/smpscheduler07/init.c
> new file mode 100644
> index 0000000000..cbffe89012
> --- /dev/null
> +++ b/testsuites/smptests/smpscheduler07/init.c
> @@ -0,0 +1,51 @@
> +/*
> + * Copyright (c) 2017 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.org/license/LICENSE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <rtems.h>
> +#include <rtems/test.h>
> +
> +void Init(rtems_task_argument arg);
> +
> +const char rtems_test_name[] = "SMPSCHEDULER 7";
> +
> +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
> +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
> +
> +#define CONFIGURE_MAXIMUM_PROCESSORS 1
> +
> +#define CONFIGURE_SCHEDULER_EDF_SMP
> +
> +#include <rtems/scheduler.h>
> +
> +RTEMS_SCHEDULER_CONTEXT_EDF_SMP(a);
> +
> +#define CONFIGURE_SCHEDULER_CONTROLS \
> +  RTEMS_SCHEDULER_CONTROL_EDF_SMP( a, rtems_build_name('T', 'E', 'S',
> 'T'))
> +
> +#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
> +  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY)
> +
> +#define CONFIGURE_MAXIMUM_TASKS 3
> +
> +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
> +
> +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
> +
> +#define CONFIGURE_INIT
> +
> +#include <rtems/confdefs.h>
> diff --git a/testsuites/smptests/smpscheduler07/smpscheduler07.doc
> b/testsuites/smptests/smpscheduler07/smpscheduler07.doc
> new file mode 100644
> index 0000000000..80f7a2474d
> --- /dev/null
> +++ b/testsuites/smptests/smpscheduler07/smpscheduler07.doc
> @@ -0,0 +1,11 @@
> +This file describes the directives and concepts tested by this test set.
> +
> +test set name: smpscheduler07
> +
> +directives:
> +
> +  - Scheduler operations.
> +
> +concepts:
> +
> +  - Ensure that the scheduler operations basically work.
> diff --git a/testsuites/smptests/smpscheduler07/smpscheduler07.scn
> b/testsuites/smptests/smpscheduler07/smpscheduler07.scn
> new file mode 100644
> index 0000000000..73db66938b
> --- /dev/null
> +++ b/testsuites/smptests/smpscheduler07/smpscheduler07.scn
> @@ -0,0 +1,2 @@
> +*** BEGIN OF TEST SMPSCHEDULER 7 ***
> +*** END OF TEST SMPSCHEDULER 7 ***
> --
> 2.12.3
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20170629/b052fc1b/attachment-0001.html>


More information about the devel mailing list