summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-06-26 10:27:23 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-06-29 11:15:38 +0200
commit1dbce41bb85ddf1368779a85e3f29815f831094e (patch)
treeb2ee1f4aee2491eeaafb9dc9ea7b77b153116f4a
parentAdd rtems_interrupt_server_handler_iterate() (diff)
downloadrtems-1dbce41bb85ddf1368779a85e3f29815f831094e.tar.bz2
smptests: Split smpscheduler03
Split smpscheduler03 to run the tests with only one processor. Update #3056.
-rw-r--r--testsuites/smptests/Makefile.am2
-rw-r--r--testsuites/smptests/configure.ac2
-rw-r--r--testsuites/smptests/smpscheduler03/Makefile.am2
-rw-r--r--testsuites/smptests/smpscheduler03/init.c661
-rw-r--r--testsuites/smptests/smpscheduler03/smpscheduler03.doc4
-rw-r--r--testsuites/smptests/smpscheduler03/smpscheduler03.scn3
-rw-r--r--testsuites/smptests/smpscheduler03/test.c572
-rw-r--r--testsuites/smptests/smpscheduler05/Makefile.am19
-rw-r--r--testsuites/smptests/smpscheduler05/init.c51
-rw-r--r--testsuites/smptests/smpscheduler05/smpscheduler05.doc11
-rw-r--r--testsuites/smptests/smpscheduler05/smpscheduler05.scn2
-rw-r--r--testsuites/smptests/smpscheduler06/Makefile.am19
-rw-r--r--testsuites/smptests/smpscheduler06/init.c59
-rw-r--r--testsuites/smptests/smpscheduler06/smpscheduler06.doc11
-rw-r--r--testsuites/smptests/smpscheduler06/smpscheduler06.scn2
15 files changed, 761 insertions, 659 deletions
diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am
index 76c02e72d8..3df76c1d67 100644
--- a/testsuites/smptests/Makefile.am
+++ b/testsuites/smptests/Makefile.am
@@ -40,6 +40,8 @@ _SUBDIRS += smpscheduler01
_SUBDIRS += smpscheduler02
_SUBDIRS += smpscheduler03
_SUBDIRS += smpscheduler04
+_SUBDIRS += smpscheduler05
+_SUBDIRS += smpscheduler06
_SUBDIRS += smpsignal01
_SUBDIRS += smpstrongapa01
_SUBDIRS += smpswitchextension01
diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac
index 434fe8dad7..54a75f777d 100644
--- a/testsuites/smptests/configure.ac
+++ b/testsuites/smptests/configure.ac
@@ -95,6 +95,8 @@ smpscheduler01/Makefile
smpscheduler02/Makefile
smpscheduler03/Makefile
smpscheduler04/Makefile
+smpscheduler05/Makefile
+smpscheduler06/Makefile
smpsignal01/Makefile
smpstrongapa01/Makefile
smpswitchextension01/Makefile
diff --git a/testsuites/smptests/smpscheduler03/Makefile.am b/testsuites/smptests/smpscheduler03/Makefile.am
index 5df9c57744..1e352e3de0 100644
--- a/testsuites/smptests/smpscheduler03/Makefile.am
+++ b/testsuites/smptests/smpscheduler03/Makefile.am
@@ -1,5 +1,5 @@
rtems_tests_PROGRAMS = smpscheduler03
-smpscheduler03_SOURCES = init.c
+smpscheduler03_SOURCES = init.c test.c
dist_rtems_tests_DATA = smpscheduler03.scn smpscheduler03.doc
diff --git a/testsuites/smptests/smpscheduler03/init.c b/testsuites/smptests/smpscheduler03/init.c
index 3180c9526a..48ef87a82c 100644
--- a/testsuites/smptests/smpscheduler03/init.c
+++ b/testsuites/smptests/smpscheduler03/init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2014, 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -13,681 +13,36 @@
*/
#ifdef HAVE_CONFIG_H
- #include "config.h"
+#include "config.h"
#endif
-#include <stdio.h>
-#include <inttypes.h>
-
#include <rtems.h>
-#include <rtems/libcsupport.h>
-#include <rtems/score/threadimpl.h>
-#include <rtems/score/schedulersmpimpl.h>
+#include <rtems/test.h>
-#include "tmacros.h"
+void Init(rtems_task_argument arg);
const char rtems_test_name[] = "SMPSCHEDULER 3";
-#define CPU_MAX 3
-
-#define SCHED_NAME(i) rtems_build_name(' ', ' ', ' ', (char) ('A' + (i)))
-
-typedef struct {
- rtems_id barrier_id;
- rtems_id task_id[CPU_MAX];
- uint32_t cpu_index[CPU_MAX];
-} test_context;
-
-static test_context test_instance;
-
-static Scheduler_SMP_Node *get_scheduler_node(Thread_Control *thread)
-{
- return _Scheduler_SMP_Node_downcast(_Thread_Scheduler_get_home_node(thread));
-}
-
-static void apply_priority(
- Thread_Control *thread,
- Priority_Control new_priority,
- bool prepend_it,
- Thread_queue_Context *queue_context
-)
-{
- _Thread_queue_Context_initialize(queue_context);
- _Thread_queue_Context_clear_priority_updates(queue_context);
- _Thread_Wait_acquire(thread, queue_context);
- _Thread_Priority_change(
- thread,
- &thread->Real_priority,
- new_priority,
- prepend_it,
- queue_context
- );
- _Thread_Wait_release(thread, queue_context);
-}
-
-static void change_priority(
- Thread_Control *thread,
- Priority_Control new_priority,
- bool prepend_it
-)
-{
- Thread_queue_Context queue_context;
-
- apply_priority(thread, new_priority, prepend_it, &queue_context);
- _Thread_Priority_update(&queue_context);
-}
-
-static void barrier_wait(test_context *ctx)
-{
- rtems_status_code sc;
-
- sc = rtems_barrier_wait(ctx->barrier_id, RTEMS_NO_TIMEOUT);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-}
-
-static void task(rtems_task_argument arg)
-{
- rtems_test_assert(0);
-}
-
-static rtems_id start_task(rtems_task_priority prio)
-{
- rtems_status_code sc;
- rtems_id task_id;
-
- sc = rtems_task_create(
- rtems_build_name('T', 'A', 'S', 'K'),
- prio,
- RTEMS_MINIMUM_STACK_SIZE,
- RTEMS_DEFAULT_MODES,
- RTEMS_DEFAULT_ATTRIBUTES,
- &task_id
- );
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_task_start(task_id, task, 0);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- return task_id;
-}
-
-static Thread_Control *get_thread_by_id(rtems_id task_id)
-{
- ISR_lock_Context lock_context;
- Thread_Control *thread;
-
- thread = _Thread_Get(task_id, &lock_context);
- rtems_test_assert(thread != NULL);
- _ISR_lock_ISR_enable(&lock_context);
-
- return thread;
-}
-
-static void test_case_change_priority(
- Thread_Control *executing,
- Scheduler_SMP_Node *executing_node,
- Scheduler_SMP_Node_state start_state,
- Priority_Control prio,
- bool prepend_it,
- Scheduler_SMP_Node_state new_state
-)
-{
- Per_CPU_Control *cpu_self;
-
- cpu_self = _Thread_Dispatch_disable();
-
- switch (start_state) {
- case SCHEDULER_SMP_NODE_SCHEDULED:
- change_priority(executing, 1, true);
- break;
- case SCHEDULER_SMP_NODE_READY:
- change_priority(executing, 4, true);
- break;
- default:
- rtems_test_assert(0);
- break;
- }
- rtems_test_assert(executing_node->state == start_state);
-
- change_priority(executing, prio, prepend_it);
- rtems_test_assert(executing_node->state == new_state);
-
- change_priority(executing, 1, true);
- rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
-
- _Thread_Dispatch_enable( cpu_self );
-}
-
-static const Scheduler_SMP_Node_state states[2] = {
- SCHEDULER_SMP_NODE_SCHEDULED,
- SCHEDULER_SMP_NODE_READY
-};
-
-static const Priority_Control priorities[2] = { 2, 5 };
-
-static const bool prepend_it[2] = { true, false };
-
-static void test_change_priority(void)
-{
- rtems_status_code sc;
- rtems_id task_id;
- Thread_Control *executing;
- Scheduler_SMP_Node *executing_node;
- size_t i;
- size_t j;
- size_t k;
-
- task_id = start_task(3);
- executing = _Thread_Get_executing();
- executing_node = get_scheduler_node(executing);
-
- for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
- for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
- for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
- test_case_change_priority(
- executing,
- executing_node,
- states[i],
- priorities[j],
- prepend_it[k],
- states[j]
- );
- }
- }
- }
-
- sc = rtems_task_delete(task_id);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-}
-
-static void update_priority_op(
- Thread_Control *thread,
- Scheduler_SMP_Node *scheduler_node,
- Priority_Control new_priority,
- bool prepend_it
-)
-{
- const Scheduler_Control *scheduler;
- ISR_lock_Context state_lock_context;
- ISR_lock_Context scheduler_lock_context;
- Thread_queue_Context queue_context;
-
- apply_priority(thread, new_priority, prepend_it, &queue_context);
-
- _Thread_State_acquire( thread, &state_lock_context );
- scheduler = _Thread_Scheduler_get_home( thread );
- _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
-
- (*scheduler->Operations.update_priority)(
- scheduler,
- thread,
- &scheduler_node->Base
- );
-
- _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
- _Thread_State_release( thread, &state_lock_context );
-}
-
-static void test_case_update_priority_op(
- Thread_Control *executing,
- Scheduler_SMP_Node *executing_node,
- Thread_Control *other,
- Scheduler_SMP_Node_state start_state,
- Priority_Control prio,
- bool prepend_it,
- Scheduler_SMP_Node_state new_state
-)
-{
- Per_CPU_Control *cpu_self;
-
- cpu_self = _Thread_Dispatch_disable();
-
- switch (start_state) {
- case SCHEDULER_SMP_NODE_SCHEDULED:
- change_priority(executing, 1, true);
- break;
- case SCHEDULER_SMP_NODE_READY:
- change_priority(executing, 4, true);
- break;
- default:
- rtems_test_assert(0);
- break;
- }
- rtems_test_assert(executing_node->state == start_state);
-
- update_priority_op(executing, executing_node, prio, prepend_it);
- rtems_test_assert(executing_node->state == new_state);
-
- if (start_state != new_state) {
- switch (start_state) {
- case SCHEDULER_SMP_NODE_SCHEDULED:
- rtems_test_assert(cpu_self->heir == other);
- break;
- case SCHEDULER_SMP_NODE_READY:
- rtems_test_assert(cpu_self->heir == executing);
- break;
- default:
- rtems_test_assert(0);
- break;
- }
- }
-
- change_priority(executing, 1, true);
- rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
-
- _Thread_Dispatch_enable( cpu_self );
-}
-
-static void test_update_priority_op(void)
-{
- rtems_status_code sc;
- rtems_id task_id;
- Thread_Control *executing;
- Scheduler_SMP_Node *executing_node;
- Thread_Control *other;
- size_t i;
- size_t j;
- size_t k;
-
- task_id = start_task(3);
- executing = _Thread_Get_executing();
- executing_node = get_scheduler_node(executing);
-
- other = get_thread_by_id(task_id);
-
- for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
- for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
- for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
- test_case_update_priority_op(
- executing,
- executing_node,
- other,
- states[i],
- priorities[j],
- prepend_it[k],
- states[j]
- );
- }
- }
- }
-
- sc = rtems_task_delete(task_id);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-}
-
-static void yield_op(
- Thread_Control *thread,
- Scheduler_SMP_Node *scheduler_node
-)
-{
- const Scheduler_Control *scheduler;
- ISR_lock_Context state_lock_context;
- ISR_lock_Context scheduler_lock_context;
-
- _Thread_State_acquire( thread, &state_lock_context );
- scheduler = _Thread_Scheduler_get_home( thread );
- _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
-
- (*scheduler->Operations.yield)(
- scheduler,
- thread,
- &scheduler_node->Base
- );
-
- _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
- _Thread_State_release( thread, &state_lock_context );
-}
-
-static void test_case_yield_op(
- Thread_Control *executing,
- Scheduler_SMP_Node *executing_node,
- Thread_Control *other,
- Scheduler_SMP_Node_state start_state,
- Scheduler_SMP_Node_state new_state
-)
-{
- Per_CPU_Control *cpu_self;
-
- cpu_self = _Thread_Dispatch_disable();
-
- change_priority(executing, 4, false);
- change_priority(other, 4, false);
-
- switch (start_state) {
- case SCHEDULER_SMP_NODE_SCHEDULED:
- switch (new_state) {
- case SCHEDULER_SMP_NODE_SCHEDULED:
- change_priority(executing, 2, false);
- change_priority(other, 3, false);
- break;
- case SCHEDULER_SMP_NODE_READY:
- change_priority(executing, 2, false);
- change_priority(other, 2, false);
- break;
- default:
- rtems_test_assert(0);
- break;
- }
- break;
- case SCHEDULER_SMP_NODE_READY:
- switch (new_state) {
- case SCHEDULER_SMP_NODE_SCHEDULED:
- rtems_test_assert(0);
- break;
- case SCHEDULER_SMP_NODE_READY:
- change_priority(executing, 3, false);
- change_priority(other, 2, false);
- break;
- default:
- rtems_test_assert(0);
- break;
- }
- break;
- default:
- rtems_test_assert(0);
- break;
- }
- rtems_test_assert(executing_node->state == start_state);
-
- yield_op(executing, executing_node);
- rtems_test_assert(executing_node->state == new_state);
-
- switch (new_state) {
- case SCHEDULER_SMP_NODE_SCHEDULED:
- case SCHEDULER_SMP_NODE_READY:
- break;
- default:
- rtems_test_assert(0);
- break;
- }
-
- change_priority(executing, 1, true);
- rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
-
- _Thread_Dispatch_enable( cpu_self );
-}
-
-static void test_yield_op(void)
-{
- rtems_status_code sc;
- rtems_id task_id;
- Thread_Control *executing;
- Scheduler_SMP_Node *executing_node;
- Thread_Control *other;
- size_t i;
- size_t j;
-
- task_id = start_task(2);
- executing = _Thread_Get_executing();
- executing_node = get_scheduler_node(executing);
-
- other = get_thread_by_id(task_id);
-
- for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
- for (j = 0; j < RTEMS_ARRAY_SIZE(states); ++j) {
- if (
- states[i] != SCHEDULER_SMP_NODE_READY
- || states[j] != SCHEDULER_SMP_NODE_SCHEDULED
- ) {
- test_case_yield_op(
- executing,
- executing_node,
- other,
- states[i],
- states[j]
- );
- }
- }
- }
-
- sc = rtems_task_delete(task_id);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-}
-
-static void block_op(
- Thread_Control *thread,
- Scheduler_SMP_Node *scheduler_node
-)
-{
- const Scheduler_Control *scheduler;
- ISR_lock_Context state_lock_context;
- ISR_lock_Context scheduler_lock_context;
-
- _Thread_State_acquire( thread, &state_lock_context );
- scheduler = _Thread_Scheduler_get_home( thread );
- _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
-
- (*scheduler->Operations.block)(scheduler, thread, &scheduler_node->Base);
-
- _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
- _Thread_State_release( thread, &state_lock_context );
-}
-
-static void unblock_op(
- Thread_Control *thread,
- Scheduler_SMP_Node *scheduler_node
-)
-{
- const Scheduler_Control *scheduler;
- ISR_lock_Context state_lock_context;
- ISR_lock_Context scheduler_lock_context;
-
- _Thread_State_acquire( thread, &state_lock_context );
- scheduler = _Thread_Scheduler_get_home( thread );
- _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
-
- (*scheduler->Operations.unblock)(
- scheduler,
- thread,
- &scheduler_node->Base
- );
-
- _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
- _Thread_State_release( thread, &state_lock_context );
-}
-
-static void test_case_unblock_op(
- Thread_Control *executing,
- Scheduler_SMP_Node *executing_node,
- Thread_Control *other,
- Scheduler_SMP_Node_state new_state
-)
-{
- Per_CPU_Control *cpu_self;
-
- cpu_self = _Thread_Dispatch_disable();
-
- switch (new_state) {
- case SCHEDULER_SMP_NODE_SCHEDULED:
- change_priority(executing, 2, false);
- rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
- break;
- case SCHEDULER_SMP_NODE_READY:
- change_priority(executing, 4, false);
- rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_READY);
- break;
- default:
- rtems_test_assert(0);
- break;
- }
-
- block_op(executing, executing_node);
- rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_BLOCKED);
-
- unblock_op(executing, executing_node);
- rtems_test_assert(executing_node->state == new_state);
-
- switch (new_state) {
- case SCHEDULER_SMP_NODE_SCHEDULED:
- case SCHEDULER_SMP_NODE_READY:
- break;
- default:
- rtems_test_assert(0);
- break;
- }
-
- change_priority(executing, 1, true);
- rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
-
- _Thread_Dispatch_enable( cpu_self );
-}
-
-static void test_unblock_op(void)
-{
- rtems_status_code sc;
- rtems_id task_id;
- Thread_Control *executing;
- Scheduler_SMP_Node *executing_node;
- Thread_Control *other;
- size_t i;
-
- task_id = start_task(3);
- executing = _Thread_Get_executing();
- executing_node = get_scheduler_node(executing);
-
- other = get_thread_by_id(task_id);
-
- for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
- test_case_unblock_op(
- executing,
- executing_node,
- other,
- states[i]
- );
- }
-
- sc = rtems_task_delete(task_id);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-}
-
-static void tests(void)
-{
- test_change_priority();
- test_update_priority_op();
- test_yield_op();
- test_unblock_op();
-}
-
-static void test_task(rtems_task_argument arg)
-{
- test_context *ctx = &test_instance;
-
- tests();
-
- ctx->cpu_index[arg] = rtems_get_current_processor();
-
- barrier_wait(ctx);
-
- rtems_task_suspend(RTEMS_SELF);
- rtems_test_assert(0);
-}
-
-static void done(uint32_t cpu_index)
-{
- printf("test done on processor %" PRIu32 "\n", cpu_index);
-}
-
-static void Init(rtems_task_argument arg)
-{
- test_context *ctx = &test_instance;
- rtems_status_code sc;
- rtems_resource_snapshot snapshot;
- uint32_t cpu_count = rtems_get_processor_count();
- uint32_t cpu_index;
-
- TEST_BEGIN();
-
- rtems_resource_snapshot_take(&snapshot);
-
- sc = rtems_barrier_create(
- rtems_build_name('B', 'A', 'R', 'I'),
- RTEMS_BARRIER_AUTOMATIC_RELEASE,
- cpu_count,
- &ctx->barrier_id
- );
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- for (cpu_index = 1; cpu_index < cpu_count; ++cpu_index) {
- rtems_id scheduler_id;
-
- sc = rtems_task_create(
- rtems_build_name('T', 'A', 'S', 'K'),
- 255,
- RTEMS_MINIMUM_STACK_SIZE,
- RTEMS_DEFAULT_MODES,
- RTEMS_DEFAULT_ATTRIBUTES,
- &ctx->task_id[cpu_index]
- );
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_scheduler_ident(SCHED_NAME(cpu_index), &scheduler_id);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_task_set_scheduler(ctx->task_id[cpu_index], scheduler_id, 1);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_task_start(ctx->task_id[cpu_index], test_task, cpu_index);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- }
-
- tests();
-
- barrier_wait(ctx);
-
- sc = rtems_barrier_delete(ctx->barrier_id);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- done(0);
-
- for (cpu_index = 1; cpu_index < cpu_count; ++cpu_index) {
- sc = rtems_task_delete(ctx->task_id[cpu_index]);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- rtems_test_assert(ctx->cpu_index[cpu_index] == cpu_index);
-
- done(cpu_index);
- }
-
- rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
-
- TEST_END();
- rtems_test_exit(0);
-}
-
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
-#define CONFIGURE_MAXIMUM_PROCESSORS CPU_MAX
+#define CONFIGURE_MAXIMUM_PROCESSORS 1
#define CONFIGURE_MAXIMUM_PRIORITY 255
#define CONFIGURE_SCHEDULER_PRIORITY_SMP
-#define CONFIGURE_SCHEDULER_SIMPLE_SMP
-#define CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
#include <rtems/scheduler.h>
RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP(a, CONFIGURE_MAXIMUM_PRIORITY + 1);
-RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b);
-
-RTEMS_SCHEDULER_CONTEXT_PRIORITY_AFFINITY_SMP(
- c,
- CONFIGURE_MAXIMUM_PRIORITY + 1
-);
-
#define CONFIGURE_SCHEDULER_CONTROLS \
- RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP(a, SCHED_NAME(0)), \
- RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(b, SCHED_NAME(1)), \
- RTEMS_SCHEDULER_CONTROL_PRIORITY_AFFINITY_SMP(c, SCHED_NAME(2))
+ RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP(a, rtems_build_name('T', 'E', 'S', 'T'))
#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
- RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
- RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
- RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
+ RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY)
-#define CONFIGURE_MAXIMUM_TASKS 6
-#define CONFIGURE_MAXIMUM_BARRIERS 1
+#define CONFIGURE_MAXIMUM_TASKS 3
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
diff --git a/testsuites/smptests/smpscheduler03/smpscheduler03.doc b/testsuites/smptests/smpscheduler03/smpscheduler03.doc
index aece8197c0..0981ec0d4c 100644
--- a/testsuites/smptests/smpscheduler03/smpscheduler03.doc
+++ b/testsuites/smptests/smpscheduler03/smpscheduler03.doc
@@ -4,8 +4,8 @@ test set name: smpscheduler03
directives:
- - _Scheduler_SMP_Change_priority()
+ - Scheduler operations.
concepts:
- - Ensure that priority changes work.
+ - Ensure that the scheduler operations basically work.
diff --git a/testsuites/smptests/smpscheduler03/smpscheduler03.scn b/testsuites/smptests/smpscheduler03/smpscheduler03.scn
index 48bf937c04..63cbf6ae44 100644
--- a/testsuites/smptests/smpscheduler03/smpscheduler03.scn
+++ b/testsuites/smptests/smpscheduler03/smpscheduler03.scn
@@ -1,5 +1,2 @@
*** BEGIN OF TEST SMPSCHEDULER 3 ***
-test done on processor 0
-test done on processor 1
-test done on processor 2
*** END OF TEST SMPSCHEDULER 3 ***
diff --git a/testsuites/smptests/smpscheduler03/test.c b/testsuites/smptests/smpscheduler03/test.c
new file mode 100644
index 0000000000..32bd67cdc2
--- /dev/null
+++ b/testsuites/smptests/smpscheduler03/test.c
@@ -0,0 +1,572 @@
+/*
+ * Copyright (c) 2014, 2017 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 <rtems.h>
+#include <rtems/libcsupport.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/schedulersmpimpl.h>
+
+#include "tmacros.h"
+
+void Init(rtems_task_argument arg);
+
+static Scheduler_SMP_Node *get_scheduler_node(Thread_Control *thread)
+{
+ return _Scheduler_SMP_Node_downcast(_Thread_Scheduler_get_home_node(thread));
+}
+
+static void apply_priority(
+ Thread_Control *thread,
+ Priority_Control new_priority,
+ bool prepend_it,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Context_initialize(queue_context);
+ _Thread_queue_Context_clear_priority_updates(queue_context);
+ _Thread_Wait_acquire(thread, queue_context);
+ _Thread_Priority_change(
+ thread,
+ &thread->Real_priority,
+ new_priority,
+ prepend_it,
+ queue_context
+ );
+ _Thread_Wait_release(thread, queue_context);
+}
+
+static void change_priority(
+ Thread_Control *thread,
+ Priority_Control new_priority,
+ bool prepend_it
+)
+{
+ Thread_queue_Context queue_context;
+
+ apply_priority(thread, new_priority, prepend_it, &queue_context);
+ _Thread_Priority_update(&queue_context);
+}
+
+static void task(rtems_task_argument arg)
+{
+ rtems_test_assert(0);
+}
+
+static rtems_id start_task(rtems_task_priority prio)
+{
+ rtems_status_code sc;
+ rtems_id task_id;
+
+ sc = rtems_task_create(
+ rtems_build_name('T', 'A', 'S', 'K'),
+ prio,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &task_id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(task_id, task, 0);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ return task_id;
+}
+
+static Thread_Control *get_thread_by_id(rtems_id task_id)
+{
+ ISR_lock_Context lock_context;
+ Thread_Control *thread;
+
+ thread = _Thread_Get(task_id, &lock_context);
+ rtems_test_assert(thread != NULL);
+ _ISR_lock_ISR_enable(&lock_context);
+
+ return thread;
+}
+
+static void test_case_change_priority(
+ Thread_Control *executing,
+ Scheduler_SMP_Node *executing_node,
+ Scheduler_SMP_Node_state start_state,
+ Priority_Control prio,
+ bool prepend_it,
+ Scheduler_SMP_Node_state new_state
+)
+{
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+
+ switch (start_state) {
+ case SCHEDULER_SMP_NODE_SCHEDULED:
+ change_priority(executing, 1, true);
+ break;
+ case SCHEDULER_SMP_NODE_READY:
+ change_priority(executing, 4, true);
+ break;
+ default:
+ rtems_test_assert(0);
+ break;
+ }
+ rtems_test_assert(executing_node->state == start_state);
+
+ change_priority(executing, prio, prepend_it);
+ rtems_test_assert(executing_node->state == new_state);
+
+ change_priority(executing, 1, true);
+ rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
+
+ _Thread_Dispatch_enable( cpu_self );
+}
+
+static const Scheduler_SMP_Node_state states[2] = {
+ SCHEDULER_SMP_NODE_SCHEDULED,
+ SCHEDULER_SMP_NODE_READY
+};
+
+static const Priority_Control priorities[2] = { 2, 5 };
+
+static const bool prepend_it[2] = { true, false };
+
+static void test_change_priority(void)
+{
+ rtems_status_code sc;
+ rtems_id task_id;
+ Thread_Control *executing;
+ Scheduler_SMP_Node *executing_node;
+ size_t i;
+ size_t j;
+ size_t k;
+
+ task_id = start_task(3);
+ executing = _Thread_Get_executing();
+ executing_node = get_scheduler_node(executing);
+
+ for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
+ for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
+ for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
+ test_case_change_priority(
+ executing,
+ executing_node,
+ states[i],
+ priorities[j],
+ prepend_it[k],
+ states[j]
+ );
+ }
+ }
+ }
+
+ sc = rtems_task_delete(task_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void update_priority_op(
+ Thread_Control *thread,
+ Scheduler_SMP_Node *scheduler_node,
+ Priority_Control new_priority,
+ bool prepend_it
+)
+{
+ const Scheduler_Control *scheduler;
+ ISR_lock_Context state_lock_context;
+ ISR_lock_Context scheduler_lock_context;
+ Thread_queue_Context queue_context;
+
+ apply_priority(thread, new_priority, prepend_it, &queue_context);
+
+ _Thread_State_acquire( thread, &state_lock_context );
+ scheduler = _Thread_Scheduler_get_home( thread );
+ _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
+
+ (*scheduler->Operations.update_priority)(
+ scheduler,
+ thread,
+ &scheduler_node->Base
+ );
+
+ _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
+ _Thread_State_release( thread, &state_lock_context );
+}
+
+static void test_case_update_priority_op(
+ Thread_Control *executing,
+ Scheduler_SMP_Node *executing_node,
+ Thread_Control *other,
+ Scheduler_SMP_Node_state start_state,
+ Priority_Control prio,
+ bool prepend_it,
+ Scheduler_SMP_Node_state new_state
+)
+{
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+
+ switch (start_state) {
+ case SCHEDULER_SMP_NODE_SCHEDULED:
+ change_priority(executing, 1, true);
+ break;
+ case SCHEDULER_SMP_NODE_READY:
+ change_priority(executing, 4, true);
+ break;
+ default:
+ rtems_test_assert(0);
+ break;
+ }
+ rtems_test_assert(executing_node->state == start_state);
+
+ update_priority_op(executing, executing_node, prio, prepend_it);
+ rtems_test_assert(executing_node->state == new_state);
+
+ if (start_state != new_state) {
+ switch (start_state) {
+ case SCHEDULER_SMP_NODE_SCHEDULED:
+ rtems_test_assert(cpu_self->heir == other);
+ break;
+ case SCHEDULER_SMP_NODE_READY:
+ rtems_test_assert(cpu_self->heir == executing);
+ break;
+ default:
+ rtems_test_assert(0);
+ break;
+ }
+ }
+
+ change_priority(executing, 1, true);
+ rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
+
+ _Thread_Dispatch_enable( cpu_self );
+}
+
+static void test_update_priority_op(void)
+{
+ rtems_status_code sc;
+ rtems_id task_id;
+ Thread_Control *executing;
+ Scheduler_SMP_Node *executing_node;
+ Thread_Control *other;
+ size_t i;
+ size_t j;
+ size_t k;
+
+ task_id = start_task(3);
+ executing = _Thread_Get_executing();
+ executing_node = get_scheduler_node(executing);
+
+ other = get_thread_by_id(task_id);
+
+ for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
+ for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
+ for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
+ test_case_update_priority_op(
+ executing,
+ executing_node,
+ other,
+ states[i],
+ priorities[j],
+ prepend_it[k],
+ states[j]
+ );
+ }
+ }
+ }
+
+ sc = rtems_task_delete(task_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void yield_op(
+ Thread_Control *thread,
+ Scheduler_SMP_Node *scheduler_node
+)
+{
+ const Scheduler_Control *scheduler;
+ ISR_lock_Context state_lock_context;
+ ISR_lock_Context scheduler_lock_context;
+
+ _Thread_State_acquire( thread, &state_lock_context );
+ scheduler = _Thread_Scheduler_get_home( thread );
+ _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
+
+ (*scheduler->Operations.yield)(
+ scheduler,
+ thread,
+ &scheduler_node->Base
+ );
+
+ _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
+ _Thread_State_release( thread, &state_lock_context );
+}
+
+static void test_case_yield_op(
+ Thread_Control *executing,
+ Scheduler_SMP_Node *executing_node,
+ Thread_Control *other,
+ Scheduler_SMP_Node_state start_state,
+ Scheduler_SMP_Node_state new_state
+)
+{
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+
+ change_priority(executing, 4, false);
+ change_priority(other, 4, false);
+
+ switch (start_state) {
+ case SCHEDULER_SMP_NODE_SCHEDULED:
+ switch (new_state) {
+ case SCHEDULER_SMP_NODE_SCHEDULED:
+ change_priority(executing, 2, false);
+ change_priority(other, 3, false);
+ break;
+ case SCHEDULER_SMP_NODE_READY:
+ change_priority(executing, 2, false);
+ change_priority(other, 2, false);
+ break;
+ default:
+ rtems_test_assert(0);
+ break;
+ }
+ break;
+ case SCHEDULER_SMP_NODE_READY:
+ switch (new_state) {
+ case SCHEDULER_SMP_NODE_SCHEDULED:
+ rtems_test_assert(0);
+ break;
+ case SCHEDULER_SMP_NODE_READY:
+ change_priority(executing, 3, false);
+ change_priority(other, 2, false);
+ break;
+ default:
+ rtems_test_assert(0);
+ break;
+ }
+ break;
+ default:
+ rtems_test_assert(0);
+ break;
+ }
+ rtems_test_assert(executing_node->state == start_state);
+
+ yield_op(executing, executing_node);
+ rtems_test_assert(executing_node->state == new_state);
+
+ switch (new_state) {
+ case SCHEDULER_SMP_NODE_SCHEDULED:
+ case SCHEDULER_SMP_NODE_READY:
+ break;
+ default:
+ rtems_test_assert(0);
+ break;
+ }
+
+ change_priority(executing, 1, true);
+ rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
+
+ _Thread_Dispatch_enable( cpu_self );
+}
+
+static void test_yield_op(void)
+{
+ rtems_status_code sc;
+ rtems_id task_id;
+ Thread_Control *executing;
+ Scheduler_SMP_Node *executing_node;
+ Thread_Control *other;
+ size_t i;
+ size_t j;
+
+ task_id = start_task(2);
+ executing = _Thread_Get_executing();
+ executing_node = get_scheduler_node(executing);
+
+ other = get_thread_by_id(task_id);
+
+ for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
+ for (j = 0; j < RTEMS_ARRAY_SIZE(states); ++j) {
+ if (
+ states[i] != SCHEDULER_SMP_NODE_READY
+ || states[j] != SCHEDULER_SMP_NODE_SCHEDULED
+ ) {
+ test_case_yield_op(
+ executing,
+ executing_node,
+ other,
+ states[i],
+ states[j]
+ );
+ }
+ }
+ }
+
+ sc = rtems_task_delete(task_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void block_op(
+ Thread_Control *thread,
+ Scheduler_SMP_Node *scheduler_node
+)
+{
+ const Scheduler_Control *scheduler;
+ ISR_lock_Context state_lock_context;
+ ISR_lock_Context scheduler_lock_context;
+
+ _Thread_State_acquire( thread, &state_lock_context );
+ scheduler = _Thread_Scheduler_get_home( thread );
+ _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
+
+ (*scheduler->Operations.block)(scheduler, thread, &scheduler_node->Base);
+
+ _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
+ _Thread_State_release( thread, &state_lock_context );
+}
+
+static void unblock_op(
+ Thread_Control *thread,
+ Scheduler_SMP_Node *scheduler_node
+)
+{
+ const Scheduler_Control *scheduler;
+ ISR_lock_Context state_lock_context;
+ ISR_lock_Context scheduler_lock_context;
+
+ _Thread_State_acquire( thread, &state_lock_context );
+ scheduler = _Thread_Scheduler_get_home( thread );
+ _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
+
+ (*scheduler->Operations.unblock)(
+ scheduler,
+ thread,
+ &scheduler_node->Base
+ );
+
+ _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
+ _Thread_State_release( thread, &state_lock_context );
+}
+
+static void test_case_unblock_op(
+ Thread_Control *executing,
+ Scheduler_SMP_Node *executing_node,
+ Thread_Control *other,
+ Scheduler_SMP_Node_state new_state
+)
+{
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+
+ switch (new_state) {
+ case SCHEDULER_SMP_NODE_SCHEDULED:
+ change_priority(executing, 2, false);
+ rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
+ break;
+ case SCHEDULER_SMP_NODE_READY:
+ change_priority(executing, 4, false);
+ rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_READY);
+ break;
+ default:
+ rtems_test_assert(0);
+ break;
+ }
+
+ block_op(executing, executing_node);
+ rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_BLOCKED);
+
+ unblock_op(executing, executing_node);
+ rtems_test_assert(executing_node->state == new_state);
+
+ switch (new_state) {
+ case SCHEDULER_SMP_NODE_SCHEDULED:
+ case SCHEDULER_SMP_NODE_READY:
+ break;
+ default:
+ rtems_test_assert(0);
+ break;
+ }
+
+ change_priority(executing, 1, true);
+ rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
+
+ _Thread_Dispatch_enable( cpu_self );
+}
+
+static void test_unblock_op(void)
+{
+ rtems_status_code sc;
+ rtems_id task_id;
+ Thread_Control *executing;
+ Scheduler_SMP_Node *executing_node;
+ Thread_Control *other;
+ size_t i;
+
+ task_id = start_task(3);
+ executing = _Thread_Get_executing();
+ executing_node = get_scheduler_node(executing);
+
+ other = get_thread_by_id(task_id);
+
+ for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
+ test_case_unblock_op(
+ executing,
+ executing_node,
+ other,
+ states[i]
+ );
+ }
+
+ sc = rtems_task_delete(task_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+void Init(rtems_task_argument arg)
+{
+ rtems_resource_snapshot snapshot;
+ rtems_status_code sc;
+ rtems_id task_id;
+
+ TEST_BEGIN();
+
+ rtems_resource_snapshot_take(&snapshot);
+
+ sc = rtems_task_create(
+ rtems_build_name('T', 'A', 'S', 'K'),
+ 255,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &task_id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ test_change_priority();
+ test_update_priority_op();
+ test_yield_op();
+ test_unblock_op();
+
+ sc = rtems_task_delete(task_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
+
+ TEST_END();
+ rtems_test_exit(0);
+}
diff --git a/testsuites/smptests/smpscheduler05/Makefile.am b/testsuites/smptests/smpscheduler05/Makefile.am
new file mode 100644
index 0000000000..72e54ab863
--- /dev/null
+++ b/testsuites/smptests/smpscheduler05/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = smpscheduler05
+smpscheduler05_SOURCES = init.c ../smpscheduler03/test.c
+
+dist_rtems_tests_DATA = smpscheduler05.scn smpscheduler05.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 = $(smpscheduler05_OBJECTS)
+LINK_LIBS = $(smpscheduler05_LDLIBS)
+
+smpscheduler05$(EXEEXT): $(smpscheduler05_OBJECTS) $(smpscheduler05_DEPENDENCIES)
+ @rm -f smpscheduler05$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/smptests/smpscheduler05/init.c b/testsuites/smptests/smpscheduler05/init.c
new file mode 100644
index 0000000000..83a9786e58
--- /dev/null
+++ b/testsuites/smptests/smpscheduler05/init.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014, 2017 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 <rtems.h>
+#include <rtems/test.h>
+
+void Init(rtems_task_argument arg);
+
+const char rtems_test_name[] = "SMPSCHEDULER 5";
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 1
+
+#define CONFIGURE_SCHEDULER_SIMPLE_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(a);
+
+#define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_SIMPLE_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/smpscheduler05/smpscheduler05.doc b/testsuites/smptests/smpscheduler05/smpscheduler05.doc
new file mode 100644
index 0000000000..7589164b18
--- /dev/null
+++ b/testsuites/smptests/smpscheduler05/smpscheduler05.doc
@@ -0,0 +1,11 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smpscheduler05
+
+directives:
+
+ - Scheduler operations.
+
+concepts:
+
+ - Ensure that the scheduler operations basically work.
diff --git a/testsuites/smptests/smpscheduler05/smpscheduler05.scn b/testsuites/smptests/smpscheduler05/smpscheduler05.scn
new file mode 100644
index 0000000000..27ea755c9f
--- /dev/null
+++ b/testsuites/smptests/smpscheduler05/smpscheduler05.scn
@@ -0,0 +1,2 @@
+*** BEGIN OF TEST SMPSCHEDULER 5 ***
+*** END OF TEST SMPSCHEDULER 5 ***
diff --git a/testsuites/smptests/smpscheduler06/Makefile.am b/testsuites/smptests/smpscheduler06/Makefile.am
new file mode 100644
index 0000000000..4835343fde
--- /dev/null
+++ b/testsuites/smptests/smpscheduler06/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = smpscheduler06
+smpscheduler06_SOURCES = init.c ../smpscheduler03/test.c
+
+dist_rtems_tests_DATA = smpscheduler06.scn smpscheduler06.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 = $(smpscheduler06_OBJECTS)
+LINK_LIBS = $(smpscheduler06_LDLIBS)
+
+smpscheduler06$(EXEEXT): $(smpscheduler06_OBJECTS) $(smpscheduler06_DEPENDENCIES)
+ @rm -f smpscheduler06$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/smptests/smpscheduler06/init.c b/testsuites/smptests/smpscheduler06/init.c
new file mode 100644
index 0000000000..96cae11200
--- /dev/null
+++ b/testsuites/smptests/smpscheduler06/init.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 2017 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 <rtems.h>
+#include <rtems/test.h>
+
+void Init(rtems_task_argument arg);
+
+const char rtems_test_name[] = "SMPSCHEDULER 6";
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 1
+
+#define CONFIGURE_MAXIMUM_PRIORITY 255
+
+#define CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_CONTEXT_PRIORITY_AFFINITY_SMP(
+ a,
+ CONFIGURE_MAXIMUM_PRIORITY + 1
+);
+
+#define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_PRIORITY_AFFINITY_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/smpscheduler06/smpscheduler06.doc b/testsuites/smptests/smpscheduler06/smpscheduler06.doc
new file mode 100644
index 0000000000..c2d6e2cd94
--- /dev/null
+++ b/testsuites/smptests/smpscheduler06/smpscheduler06.doc
@@ -0,0 +1,11 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smpscheduler06
+
+directives:
+
+ - Scheduler operations.
+
+concepts:
+
+ - Ensure that the scheduler operations basically work.
diff --git a/testsuites/smptests/smpscheduler06/smpscheduler06.scn b/testsuites/smptests/smpscheduler06/smpscheduler06.scn
new file mode 100644
index 0000000000..9b718bc866
--- /dev/null
+++ b/testsuites/smptests/smpscheduler06/smpscheduler06.scn
@@ -0,0 +1,2 @@
+*** BEGIN OF TEST SMPSCHEDULER 6 ***
+*** END OF TEST SMPSCHEDULER 6 ***