summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-04-29 12:09:32 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-02 07:46:17 +0200
commit981eed21761cd0036f0ac61042adea09d8a595a2 (patch)
tree199a5373376456b11fa6a9c61cfe3a80b024e49b
parentposix: Avoid Giant lock in _POSIX_signals_Send() (diff)
downloadrtems-981eed21761cd0036f0ac61042adea09d8a595a2.tar.bz2
score: Add dummy Strong APA scheduler
Start with a copy of the Priority SMP scheduler implementation. Update #2510.
-rw-r--r--cpukit/sapi/include/confdefs.h29
-rw-r--r--cpukit/sapi/include/rtems/scheduler.h20
-rw-r--r--cpukit/score/Makefile.am2
-rw-r--r--cpukit/score/include/rtems/score/schedulerstrongapa.h145
-rw-r--r--cpukit/score/preinstall.am4
-rw-r--r--cpukit/score/src/schedulerstrongapa.c396
-rw-r--r--testsuites/smptests/Makefile.am1
-rw-r--r--testsuites/smptests/configure.ac1
-rw-r--r--testsuites/smptests/smpstrongapa01/Makefile.am19
-rw-r--r--testsuites/smptests/smpstrongapa01/init.c54
-rw-r--r--testsuites/smptests/smpstrongapa01/smpstrongapa01.doc11
-rw-r--r--testsuites/smptests/smpstrongapa01/smpstrongapa01.scn2
12 files changed, 684 insertions, 0 deletions
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index 006cdbd6f5..ceed2a4b9d 100644
--- a/cpukit/sapi/include/confdefs.h
+++ b/cpukit/sapi/include/confdefs.h
@@ -771,6 +771,7 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
* - CONFIGURE_SCHEDULER_PRIORITY_SMP - Deterministic Priority SMP Scheduler
* - CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP - Deterministic
* Priority SMP Affinity Scheduler
+ * - CONFIGURE_SCHEDULER_STRONG_APA - Strong APA Scheduler
* - CONFIGURE_SCHEDULER_SIMPLE - Light-weight Priority Scheduler
* - CONFIGURE_SCHEDULER_SIMPLE_SMP - Simple SMP Priority Scheduler
* - CONFIGURE_SCHEDULER_EDF - EDF Scheduler
@@ -795,6 +796,7 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
!defined(CONFIGURE_SCHEDULER_PRIORITY) && \
!defined(CONFIGURE_SCHEDULER_PRIORITY_SMP) && \
!defined(CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP) && \
+ !defined(CONFIGURE_SCHEDULER_STRONG_APA) && \
!defined(CONFIGURE_SCHEDULER_SIMPLE) && \
!defined(CONFIGURE_SCHEDULER_SIMPLE_SMP) && \
!defined(CONFIGURE_SCHEDULER_EDF) && \
@@ -890,6 +892,30 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
#endif
/*
+ * If the Strong APA Scheduler is selected, then configure for
+ * it.
+ */
+#if defined(CONFIGURE_SCHEDULER_STRONG_APA)
+ #if !defined(CONFIGURE_SCHEDULER_NAME)
+ /** Configure the name of the scheduler instance */
+ #define CONFIGURE_SCHEDULER_NAME rtems_build_name('M', 'A', 'P', 'A')
+ #endif
+
+ #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
+ /** Configure the context needed by the scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTEXT \
+ RTEMS_SCHEDULER_CONTEXT_STRONG_APA( \
+ dflt, \
+ CONFIGURE_MAXIMUM_PRIORITY + 1 \
+ )
+
+ /** Configure the controls for this scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_STRONG_APA(dflt, CONFIGURE_SCHEDULER_NAME)
+ #endif
+#endif
+
+/*
* If the Simple Priority Scheduler is selected, then configure for it.
*/
#if defined(CONFIGURE_SCHEDULER_SIMPLE)
@@ -3264,6 +3290,9 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
#ifdef CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
Scheduler_priority_affinity_SMP_Node Priority_affinity_SMP;
#endif
+ #ifdef CONFIGURE_SCHEDULER_STRONG_APA
+ Scheduler_strong_APA_Node Strong_APA;
+ #endif
#ifdef CONFIGURE_SCHEDULER_USER_PER_THREAD
CONFIGURE_SCHEDULER_USER_PER_THREAD User;
#endif
diff --git a/cpukit/sapi/include/rtems/scheduler.h b/cpukit/sapi/include/rtems/scheduler.h
index a1afa668a9..39dff903d4 100644
--- a/cpukit/sapi/include/rtems/scheduler.h
+++ b/cpukit/sapi/include/rtems/scheduler.h
@@ -151,6 +151,26 @@
}
#endif
+#ifdef CONFIGURE_SCHEDULER_STRONG_APA
+ #include <rtems/score/schedulerstrongapa.h>
+
+ #define RTEMS_SCHEDULER_CONTEXT_STRONG_APA_NAME( name ) \
+ RTEMS_SCHEDULER_CONTEXT_NAME( strong_APA_ ## name )
+
+ #define RTEMS_SCHEDULER_CONTEXT_STRONG_APA( name, prio_count ) \
+ static struct { \
+ Scheduler_strong_APA_Context Base; \
+ Chain_Control Ready[ ( prio_count ) ]; \
+ } RTEMS_SCHEDULER_CONTEXT_STRONG_APA_NAME( name )
+
+ #define RTEMS_SCHEDULER_CONTROL_STRONG_APA( name, obj_name ) \
+ { \
+ &RTEMS_SCHEDULER_CONTEXT_STRONG_APA_NAME( name ).Base.Base.Base, \
+ SCHEDULER_STRONG_APA_ENTRY_POINTS, \
+ ( obj_name ) \
+ }
+#endif
+
#ifdef CONFIGURE_SCHEDULER_SIMPLE
#include <rtems/score/schedulersimple.h>
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index c2aec62293..937a9ce1ca 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -128,6 +128,7 @@ if HAS_SMP
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
+include_rtems_score_HEADERS += include/rtems/score/schedulerstrongapa.h
endif
## src
@@ -148,6 +149,7 @@ libscore_a_SOURCES += src/schedulerchangeroot.c
libscore_a_SOURCES += src/schedulerpriorityaffinitysmp.c
libscore_a_SOURCES += src/schedulerprioritysmp.c
libscore_a_SOURCES += src/schedulersimplesmp.c
+libscore_a_SOURCES += src/schedulerstrongapa.c
libscore_a_SOURCES += src/schedulersmpdebug.c
libscore_a_SOURCES += src/smp.c
libscore_a_SOURCES += src/smplock.c
diff --git a/cpukit/score/include/rtems/score/schedulerstrongapa.h b/cpukit/score/include/rtems/score/schedulerstrongapa.h
new file mode 100644
index 0000000000..5222cd0605
--- /dev/null
+++ b/cpukit/score/include/rtems/score/schedulerstrongapa.h
@@ -0,0 +1,145 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedulerStrongAPA
+ *
+ * @brief Strong APA Scheduler API
+ */
+
+/*
+ * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@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.
+ */
+
+#ifndef _RTEMS_SCORE_SCHEDULERSTRONGAPA_H
+#define _RTEMS_SCORE_SCHEDULERSTRONGAPA_H
+
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/schedulersmp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreSchedulerStrongAPA Strong APA Scheduler
+ *
+ * @ingroup ScoreSchedulerSMP
+ *
+ * This is an implementation of the global fixed priority scheduler (G-FP). It
+ * uses one ready chain per priority to ensure constant time insert operations.
+ * The scheduled chain uses linear insert operations and has at most processor
+ * count entries. Since the processor and priority count are constants all
+ * scheduler operations complete in a bounded execution time.
+ *
+ * The the_thread preempt mode will be ignored.
+ *
+ * @{
+ */
+
+/**
+ * @brief Scheduler context specialization for Strong APA
+ * schedulers.
+ */
+typedef struct {
+ Scheduler_SMP_Context Base;
+ Priority_bit_map_Control Bit_map;
+ Chain_Control Ready[ RTEMS_ZERO_LENGTH_ARRAY ];
+} Scheduler_strong_APA_Context;
+
+/**
+ * @brief Scheduler node specialization for Strong APA
+ * schedulers.
+ */
+typedef struct {
+ /**
+ * @brief SMP scheduler node.
+ */
+ Scheduler_SMP_Node Base;
+
+ /**
+ * @brief The associated ready queue of this node.
+ */
+ Scheduler_priority_Ready_queue Ready_queue;
+} Scheduler_strong_APA_Node;
+
+/**
+ * @brief Entry points for the Strong APA Scheduler.
+ */
+#define SCHEDULER_STRONG_APA_ENTRY_POINTS \
+ { \
+ _Scheduler_strong_APA_Initialize, \
+ _Scheduler_default_Schedule, \
+ _Scheduler_strong_APA_Yield, \
+ _Scheduler_strong_APA_Block, \
+ _Scheduler_strong_APA_Unblock, \
+ _Scheduler_strong_APA_Change_priority, \
+ _Scheduler_strong_APA_Ask_for_help, \
+ _Scheduler_strong_APA_Node_initialize, \
+ _Scheduler_default_Node_destroy, \
+ _Scheduler_strong_APA_Update_priority, \
+ _Scheduler_priority_Priority_compare, \
+ _Scheduler_default_Release_job, \
+ _Scheduler_default_Tick, \
+ _Scheduler_SMP_Start_idle \
+ SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
+ }
+
+void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler );
+
+void _Scheduler_strong_APA_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+);
+
+void _Scheduler_strong_APA_Block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+);
+
+Thread_Control *_Scheduler_strong_APA_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+);
+
+Thread_Control *_Scheduler_strong_APA_Change_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ bool prepend_it
+);
+
+Thread_Control *_Scheduler_strong_APA_Ask_for_help(
+ const Scheduler_Control *scheduler,
+ Thread_Control *needs_help,
+ Thread_Control *offers_help
+);
+
+void _Scheduler_strong_APA_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Control new_priority
+);
+
+Thread_Control *_Scheduler_strong_APA_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERSTRONGAPA_H */
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index 3a70bfa54b..348185a528 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -446,4 +446,8 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerpriorityaffinitysmp.
$(PROJECT_INCLUDE)/rtems/score/schedulersimplesmp.h: include/rtems/score/schedulersimplesmp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulersimplesmp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulersimplesmp.h
+
+$(PROJECT_INCLUDE)/rtems/score/schedulerstrongapa.h: include/rtems/score/schedulerstrongapa.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerstrongapa.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerstrongapa.h
endif
diff --git a/cpukit/score/src/schedulerstrongapa.c b/cpukit/score/src/schedulerstrongapa.c
new file mode 100644
index 0000000000..09efde9cf9
--- /dev/null
+++ b/cpukit/score/src/schedulerstrongapa.c
@@ -0,0 +1,396 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedulerStrongAPA
+ *
+ * @brief Strong APA Scheduler Implementation
+ */
+
+/*
+ * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@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.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/score/schedulerstrongapa.h>
+#include <rtems/score/schedulerpriorityimpl.h>
+#include <rtems/score/schedulersmpimpl.h>
+
+static Scheduler_strong_APA_Context *_Scheduler_strong_APA_Get_self(
+ Scheduler_Context *context
+)
+{
+ return (Scheduler_strong_APA_Context *) context;
+}
+
+static Scheduler_strong_APA_Node *
+_Scheduler_strong_APA_Node_downcast( Scheduler_Node *node )
+{
+ return (Scheduler_strong_APA_Node *) node;
+}
+
+static void _Scheduler_strong_APA_Move_from_scheduled_to_ready(
+ Scheduler_Context *context,
+ Scheduler_Node *scheduled_to_ready
+)
+{
+ Scheduler_strong_APA_Context *self =
+ _Scheduler_strong_APA_Get_self( context );
+ Scheduler_strong_APA_Node *node =
+ _Scheduler_strong_APA_Node_downcast( scheduled_to_ready );
+
+ _Chain_Extract_unprotected( &node->Base.Base.Node );
+ _Scheduler_priority_Ready_queue_enqueue_first(
+ &node->Base.Base.Node,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
+}
+
+static void _Scheduler_strong_APA_Move_from_ready_to_scheduled(
+ Scheduler_Context *context,
+ Scheduler_Node *ready_to_scheduled
+)
+{
+ Scheduler_strong_APA_Context *self =
+ _Scheduler_strong_APA_Get_self( context );
+ Scheduler_strong_APA_Node *node =
+ _Scheduler_strong_APA_Node_downcast( ready_to_scheduled );
+
+ _Scheduler_priority_Ready_queue_extract(
+ &node->Base.Base.Node,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
+ _Chain_Insert_ordered_unprotected(
+ &self->Base.Scheduled,
+ &node->Base.Base.Node,
+ _Scheduler_SMP_Insert_priority_fifo_order
+ );
+}
+
+static void _Scheduler_strong_APA_Insert_ready_lifo(
+ Scheduler_Context *context,
+ Scheduler_Node *the_thread
+)
+{
+ Scheduler_strong_APA_Context *self =
+ _Scheduler_strong_APA_Get_self( context );
+ Scheduler_strong_APA_Node *node =
+ _Scheduler_strong_APA_Node_downcast( the_thread );
+
+ _Scheduler_priority_Ready_queue_enqueue(
+ &node->Base.Base.Node,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
+}
+
+static void _Scheduler_strong_APA_Insert_ready_fifo(
+ Scheduler_Context *context,
+ Scheduler_Node *the_thread
+)
+{
+ Scheduler_strong_APA_Context *self =
+ _Scheduler_strong_APA_Get_self( context );
+ Scheduler_strong_APA_Node *node =
+ _Scheduler_strong_APA_Node_downcast( the_thread );
+
+ _Scheduler_priority_Ready_queue_enqueue_first(
+ &node->Base.Base.Node,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
+}
+
+static void _Scheduler_strong_APA_Extract_from_ready(
+ Scheduler_Context *context,
+ Scheduler_Node *the_thread
+)
+{
+ Scheduler_strong_APA_Context *self =
+ _Scheduler_strong_APA_Get_self( context );
+ Scheduler_strong_APA_Node *node =
+ _Scheduler_strong_APA_Node_downcast( the_thread );
+
+ _Scheduler_priority_Ready_queue_extract(
+ &node->Base.Base.Node,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
+}
+
+static void _Scheduler_strong_APA_Do_update(
+ Scheduler_Context *context,
+ Scheduler_Node *node_to_update,
+ Priority_Control new_priority
+)
+{
+ Scheduler_strong_APA_Context *self =
+ _Scheduler_strong_APA_Get_self( context );
+ Scheduler_strong_APA_Node *node =
+ _Scheduler_strong_APA_Node_downcast( node_to_update );
+
+ _Scheduler_SMP_Node_update_priority( &node->Base, new_priority );
+ _Scheduler_priority_Ready_queue_update(
+ &node->Ready_queue,
+ new_priority,
+ &self->Bit_map,
+ &self->Ready[ 0 ]
+ );
+}
+
+static Scheduler_strong_APA_Context *
+_Scheduler_strong_APA_Get_context( const Scheduler_Control *scheduler )
+{
+ return (Scheduler_strong_APA_Context *) _Scheduler_Get_context( scheduler );
+}
+
+void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler )
+{
+ Scheduler_strong_APA_Context *self =
+ _Scheduler_strong_APA_Get_context( scheduler );
+
+ _Scheduler_SMP_Initialize( &self->Base );
+ _Priority_bit_map_Initialize( &self->Bit_map );
+ _Scheduler_priority_Ready_queue_initialize( &self->Ready[ 0 ] );
+}
+
+void _Scheduler_strong_APA_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+)
+{
+ Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( the_thread );
+
+ _Scheduler_SMP_Node_initialize( node, the_thread );
+}
+
+void _Scheduler_strong_APA_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Control new_priority
+)
+{
+ Scheduler_Context *context = _Scheduler_Get_context( scheduler );
+ Scheduler_Node *node = _Scheduler_Thread_get_node( the_thread );
+
+ _Scheduler_strong_APA_Do_update( context, node, new_priority );
+}
+
+static Scheduler_Node *_Scheduler_strong_APA_Get_highest_ready(
+ Scheduler_Context *context,
+ Scheduler_Node *node
+)
+{
+ Scheduler_strong_APA_Context *self =
+ _Scheduler_strong_APA_Get_self( context );
+
+ (void) node;
+
+ return (Scheduler_Node *) _Scheduler_priority_Ready_queue_first(
+ &self->Bit_map,
+ &self->Ready[ 0 ]
+ );
+}
+
+void _Scheduler_strong_APA_Block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+)
+{
+ Scheduler_Context *context = _Scheduler_Get_context( scheduler );
+
+ _Scheduler_SMP_Block(
+ context,
+ the_thread,
+ _Scheduler_strong_APA_Extract_from_ready,
+ _Scheduler_strong_APA_Get_highest_ready,
+ _Scheduler_strong_APA_Move_from_ready_to_scheduled,
+ _Scheduler_SMP_Allocate_processor_lazy
+ );
+}
+
+static Thread_Control *_Scheduler_strong_APA_Enqueue_ordered(
+ Scheduler_Context *context,
+ Scheduler_Node *node,
+ Thread_Control *needs_help,
+ Chain_Node_order order,
+ Scheduler_SMP_Insert insert_ready,
+ Scheduler_SMP_Insert insert_scheduled
+)
+{
+ return _Scheduler_SMP_Enqueue_ordered(
+ context,
+ node,
+ needs_help,
+ order,
+ insert_ready,
+ insert_scheduled,
+ _Scheduler_strong_APA_Move_from_scheduled_to_ready,
+ _Scheduler_SMP_Get_lowest_scheduled,
+ _Scheduler_SMP_Allocate_processor_lazy
+ );
+}
+
+static Thread_Control *_Scheduler_strong_APA_Enqueue_lifo(
+ Scheduler_Context *context,
+ Scheduler_Node *node,
+ Thread_Control *needs_help
+)
+{
+ return _Scheduler_strong_APA_Enqueue_ordered(
+ context,
+ node,
+ needs_help,
+ _Scheduler_SMP_Insert_priority_lifo_order,
+ _Scheduler_strong_APA_Insert_ready_lifo,
+ _Scheduler_SMP_Insert_scheduled_lifo
+ );
+}
+
+static Thread_Control *_Scheduler_strong_APA_Enqueue_fifo(
+ Scheduler_Context *context,
+ Scheduler_Node *node,
+ Thread_Control *needs_help
+)
+{
+ return _Scheduler_strong_APA_Enqueue_ordered(
+ context,
+ node,
+ needs_help,
+ _Scheduler_SMP_Insert_priority_fifo_order,
+ _Scheduler_strong_APA_Insert_ready_fifo,
+ _Scheduler_SMP_Insert_scheduled_fifo
+ );
+}
+
+static Thread_Control *_Scheduler_strong_APA_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_strong_APA_Extract_from_ready,
+ _Scheduler_strong_APA_Get_highest_ready,
+ insert_ready,
+ insert_scheduled,
+ _Scheduler_strong_APA_Move_from_ready_to_scheduled,
+ _Scheduler_SMP_Allocate_processor_lazy
+ );
+}
+
+static Thread_Control *_Scheduler_strong_APA_Enqueue_scheduled_lifo(
+ Scheduler_Context *context,
+ Scheduler_Node *node
+)
+{
+ return _Scheduler_strong_APA_Enqueue_scheduled_ordered(
+ context,
+ node,
+ _Scheduler_SMP_Insert_priority_lifo_order,
+ _Scheduler_strong_APA_Insert_ready_lifo,
+ _Scheduler_SMP_Insert_scheduled_lifo
+ );
+}
+
+static Thread_Control *_Scheduler_strong_APA_Enqueue_scheduled_fifo(
+ Scheduler_Context *context,
+ Scheduler_Node *node
+)
+{
+ return _Scheduler_strong_APA_Enqueue_scheduled_ordered(
+ context,
+ node,
+ _Scheduler_SMP_Insert_priority_fifo_order,
+ _Scheduler_strong_APA_Insert_ready_fifo,
+ _Scheduler_SMP_Insert_scheduled_fifo
+ );
+}
+
+Thread_Control *_Scheduler_strong_APA_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+)
+{
+ Scheduler_Context *context = _Scheduler_Get_context( scheduler );
+
+ return _Scheduler_SMP_Unblock(
+ context,
+ the_thread,
+ _Scheduler_strong_APA_Enqueue_fifo
+ );
+}
+
+Thread_Control *_Scheduler_strong_APA_Change_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Control new_priority,
+ bool prepend_it
+)
+{
+ Scheduler_Context *context = _Scheduler_Get_context( scheduler );
+
+ return _Scheduler_SMP_Change_priority(
+ context,
+ the_thread,
+ new_priority,
+ prepend_it,
+ _Scheduler_strong_APA_Extract_from_ready,
+ _Scheduler_strong_APA_Do_update,
+ _Scheduler_strong_APA_Enqueue_fifo,
+ _Scheduler_strong_APA_Enqueue_lifo,
+ _Scheduler_strong_APA_Enqueue_scheduled_fifo,
+ _Scheduler_strong_APA_Enqueue_scheduled_lifo
+ );
+}
+
+Thread_Control *_Scheduler_strong_APA_Ask_for_help(
+ const Scheduler_Control *scheduler,
+ Thread_Control *offers_help,
+ Thread_Control *needs_help
+)
+{
+ Scheduler_Context *context = _Scheduler_Get_context( scheduler );
+
+ return _Scheduler_SMP_Ask_for_help(
+ context,
+ offers_help,
+ needs_help,
+ _Scheduler_strong_APA_Enqueue_fifo
+ );
+}
+
+Thread_Control *_Scheduler_strong_APA_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+)
+{
+ Scheduler_Context *context = _Scheduler_Get_context( scheduler );
+
+ return _Scheduler_SMP_Yield(
+ context,
+ the_thread,
+ _Scheduler_strong_APA_Extract_from_ready,
+ _Scheduler_strong_APA_Enqueue_fifo,
+ _Scheduler_strong_APA_Enqueue_scheduled_fifo
+ );
+}
diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am
index 610f3137c4..8ab12dc1fd 100644
--- a/testsuites/smptests/Makefile.am
+++ b/testsuites/smptests/Makefile.am
@@ -38,6 +38,7 @@ SUBDIRS += smpscheduler02
SUBDIRS += smpscheduler03
SUBDIRS += smpschedsem01
SUBDIRS += smpsignal01
+SUBDIRS += smpstrongapa01
SUBDIRS += smpswitchextension01
SUBDIRS += smpthreadlife01
SUBDIRS += smpunsupported01
diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac
index a89b796afe..3611e326ad 100644
--- a/testsuites/smptests/configure.ac
+++ b/testsuites/smptests/configure.ac
@@ -57,6 +57,7 @@ AM_CONDITIONAL(HAS_CPUSET,test x"${ac_cv_header_sys_cpuset_h}" = x"yes")
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile
+smpstrongapa01/Makefile
smp01/Makefile
smp02/Makefile
smp03/Makefile
diff --git a/testsuites/smptests/smpstrongapa01/Makefile.am b/testsuites/smptests/smpstrongapa01/Makefile.am
new file mode 100644
index 0000000000..b51c779f96
--- /dev/null
+++ b/testsuites/smptests/smpstrongapa01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = smpstrongapa01
+smpstrongapa01_SOURCES = init.c
+
+dist_rtems_tests_DATA = smpstrongapa01.scn smpstrongapa01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(smpstrongapa01_OBJECTS)
+LINK_LIBS = $(smpstrongapa01_LDLIBS)
+
+smpstrongapa01$(EXEEXT): $(smpstrongapa01_OBJECTS) $(smpstrongapa01_DEPENDENCIES)
+ @rm -f smpstrongapa01$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/smptests/smpstrongapa01/init.c b/testsuites/smptests/smpstrongapa01/init.c
new file mode 100644
index 0000000000..5594d74c61
--- /dev/null
+++ b/testsuites/smptests/smpstrongapa01/init.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@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 "tmacros.h"
+
+const char rtems_test_name[] = "SMPSTRONGAPA 1";
+
+static void test(void)
+{
+}
+
+static void Init(rtems_task_argument arg)
+{
+ TEST_BEGIN();
+
+ test();
+
+ TEST_END();
+ rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_SMP_APPLICATION
+
+#define CONFIGURE_SMP_MAXIMUM_PROCESSORS 2
+
+#define CONFIGURE_SCHEDULER_STRONG_APA
+
+#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/smpstrongapa01/smpstrongapa01.doc b/testsuites/smptests/smpstrongapa01/smpstrongapa01.doc
new file mode 100644
index 0000000000..9e9376227a
--- /dev/null
+++ b/testsuites/smptests/smpstrongapa01/smpstrongapa01.doc
@@ -0,0 +1,11 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smpstrongapa01
+
+directives:
+
+ TBD
+
+concepts:
+
+ TBD
diff --git a/testsuites/smptests/smpstrongapa01/smpstrongapa01.scn b/testsuites/smptests/smpstrongapa01/smpstrongapa01.scn
new file mode 100644
index 0000000000..d6f5f5467a
--- /dev/null
+++ b/testsuites/smptests/smpstrongapa01/smpstrongapa01.scn
@@ -0,0 +1,2 @@
+*** BEGIN OF TEST SMPSTRONGAPA 1 ***
+*** END OF TEST SMPSTRONGAPA 1 ***