[rtems commit] score: Add SMP EDF scheduler

Sebastian Huber sebh at rtems.org
Fri Jun 30 06:00:57 UTC 2017


Module:    rtems
Branch:    master
Commit:    f3d9f2288e957caabaa1a312096cb72f8e748807
Changeset: http://git.rtems.org/rtems/commit/?id=f3d9f2288e957caabaa1a312096cb72f8e748807

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Jun 26 10:35:45 2017 +0200

score: Add SMP EDF scheduler

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(-)

diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index 604539b..77b80d1 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 0b20aab..fae0db4 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 a3de792..46b4417 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 0000000..8f6e857
--- /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 4d468e5..da23154 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 0b70bce..2338297 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 c19d9b9..068a0db 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 0000000..270f9a4
--- /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 3df76c1..6c1bd12 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 54a75f7..59b27ef 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 32bd67c..3f6b9e3 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 0000000..f981544
--- /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 0000000..cbffe89
--- /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 0000000..80f7a24
--- /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 0000000..73db669
--- /dev/null
+++ b/testsuites/smptests/smpscheduler07/smpscheduler07.scn
@@ -0,0 +1,2 @@
+*** BEGIN OF TEST SMPSCHEDULER 7 ***
+*** END OF TEST SMPSCHEDULER 7 ***



More information about the vc mailing list