summaryrefslogtreecommitdiffstats
path: root/testsuites
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-06-11 10:00:25 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-06-14 16:26:09 +0200
commit8b222be707cacfd634c04c7c752536d5d16cbeba (patch)
tree32f815f51325117e85809c018decd74f1fd4b76d /testsuites
parentscheduler: New simple SMP scheduler implementation (diff)
downloadrtems-8b222be707cacfd634c04c7c752536d5d16cbeba.tar.bz2
smptests/smpschedule01: New test
Diffstat (limited to 'testsuites')
-rw-r--r--testsuites/smptests/Makefile.am1
-rw-r--r--testsuites/smptests/configure.ac1
-rw-r--r--testsuites/smptests/smpschedule01/Makefile.am19
-rw-r--r--testsuites/smptests/smpschedule01/init.c209
-rw-r--r--testsuites/smptests/smpschedule01/smpschedule01.doc14
-rw-r--r--testsuites/smptests/smpschedule01/smpschedule01.scn2
6 files changed, 246 insertions, 0 deletions
diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am
index 70e10001ca..86991678a7 100644
--- a/testsuites/smptests/Makefile.am
+++ b/testsuites/smptests/Makefile.am
@@ -20,6 +20,7 @@ SUBDIRS += smpatomic05
SUBDIRS += smpatomic06
SUBDIRS += smpatomic07
SUBDIRS += smplock01
+SUBDIRS += smpschedule01
endif
include $(top_srcdir)/../automake/subdirs.am
diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac
index 6a2a443026..e8e4d728c7 100644
--- a/testsuites/smptests/configure.ac
+++ b/testsuites/smptests/configure.ac
@@ -49,5 +49,6 @@ smpatomic05/Makefile
smpatomic06/Makefile
smpatomic07/Makefile
smplock01/Makefile
+smpschedule01/Makefile
])
AC_OUTPUT
diff --git a/testsuites/smptests/smpschedule01/Makefile.am b/testsuites/smptests/smpschedule01/Makefile.am
new file mode 100644
index 0000000000..bd1db04d64
--- /dev/null
+++ b/testsuites/smptests/smpschedule01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = smpschedule01
+smpschedule01_SOURCES = init.c
+
+dist_rtems_tests_DATA = smpschedule01.scn smpschedule01.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 = $(smpschedule01_OBJECTS)
+LINK_LIBS = $(smpschedule01_LDLIBS)
+
+smpschedule01$(EXEEXT): $(smpschedule01_OBJECTS) $(smpschedule01_DEPENDENCIES)
+ @rm -f smpschedule01$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/smptests/smpschedule01/init.c b/testsuites/smptests/smpschedule01/init.c
new file mode 100644
index 0000000000..9c5794c3e9
--- /dev/null
+++ b/testsuites/smptests/smpschedule01/init.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2013 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.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tmacros.h"
+
+#define CPU_COUNT 2
+
+#define TASK_COUNT 4
+
+#define FIRST_TASK_PRIORITY 1
+
+#define SECOND_TASK_READY RTEMS_EVENT_0
+
+static rtems_id task_ids[TASK_COUNT];
+
+static void suspend(size_t i)
+{
+ rtems_status_code sc = rtems_task_suspend(task_ids[i]);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void resume(size_t i)
+{
+ rtems_status_code sc = rtems_task_resume(task_ids[i]);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void task(rtems_task_argument arg)
+{
+ rtems_task_priority task_priority;
+ rtems_status_code sc;
+
+ sc = rtems_task_set_priority(
+ RTEMS_SELF,
+ RTEMS_CURRENT_PRIORITY,
+ &task_priority
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ if (arg == 1) {
+ sc = rtems_event_send(task_ids[0], SECOND_TASK_READY);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ }
+
+ while (true) {
+ /* Do nothing */
+ }
+}
+
+static bool is_per_cpu_state_ok(void)
+{
+ bool ok = true;
+ uint32_t n = rtems_processors_get_count();
+ uint32_t i;
+
+ for (i = 0; i < n; ++i) {
+ const Thread_Control *thread = _Per_CPU_Information[i].executing;
+ uint32_t count = 0;
+ uint32_t j;
+
+ for (j = 0; j < n; ++j) {
+ const Per_CPU_Control *cpu = &_Per_CPU_Information[j];
+ const Thread_Control *executing = cpu->executing;
+ const Thread_Control *heir = cpu->heir;
+
+ if (i != j) {
+ count += executing == thread;
+ count += heir == thread;
+ } else {
+ ++count;
+ }
+
+ ok = ok && executing->cpu == cpu;
+ ok = ok && heir->cpu == cpu;
+ }
+
+ ok = ok && (count == 1);
+ }
+
+ return ok;
+}
+
+static void test_scheduler_cross(void)
+{
+ bool per_cpu_state_ok;
+
+ _Thread_Disable_dispatch();
+
+ suspend(0);
+ suspend(1);
+ resume(0);
+ resume(1);
+
+ per_cpu_state_ok = is_per_cpu_state_ok();
+
+ _Thread_Enable_dispatch();
+
+ rtems_test_assert(per_cpu_state_ok);
+}
+
+static void test_scheduler_move_heir(void)
+{
+ bool per_cpu_state_ok;
+
+ _Thread_Disable_dispatch();
+
+ suspend(2);
+ suspend(3);
+ suspend(0);
+ resume(2);
+ suspend(1);
+ resume(3);
+ resume(0);
+
+ per_cpu_state_ok = is_per_cpu_state_ok();
+
+ resume(1);
+
+ _Thread_Enable_dispatch();
+
+ rtems_test_assert(per_cpu_state_ok);
+}
+
+static void test(void)
+{
+ rtems_event_set events;
+ rtems_status_code sc;
+ rtems_task_argument task_index;
+
+ task_ids[0] = rtems_task_self();
+
+ for (task_index = 1; task_index < TASK_COUNT; ++task_index) {
+ rtems_id task_id;
+
+ sc = rtems_task_create(
+ rtems_build_name('T', 'A', 'S', 'K'),
+ FIRST_TASK_PRIORITY + task_index,
+ 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, task_index);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ task_ids[task_index] = task_id;
+ }
+
+ sc = rtems_event_receive(
+ SECOND_TASK_READY,
+ RTEMS_EVENT_ALL | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(events == SECOND_TASK_READY);
+
+ test_scheduler_cross();
+ test_scheduler_move_heir();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ puts("\n\n*** TEST SMPSCHEDULE 1 ***");
+
+ test();
+
+ puts("*** END OF TEST SMPSCHEDULE 1 ***");
+
+ rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_SMP_APPLICATION
+
+#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
+
+#define CONFIGURE_MAXIMUM_TASKS TASK_COUNT
+
+#define CONFIGURE_INIT_TASK_PRIORITY FIRST_TASK_PRIORITY
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/smptests/smpschedule01/smpschedule01.doc b/testsuites/smptests/smpschedule01/smpschedule01.doc
new file mode 100644
index 0000000000..9727d4f515
--- /dev/null
+++ b/testsuites/smptests/smpschedule01/smpschedule01.doc
@@ -0,0 +1,14 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smpschedule01
+
+directives:
+
+ - _Scheduler_simple_smp_Enqueue_priority_fifo
+ - _Scheduler_simple_smp_Enqueue_priority_lifo
+ - _Scheduler_simple_smp_Extract
+
+concepts:
+
+ - Ensure that the per-processor state is consistent after a sequence of
+ scheduling events.
diff --git a/testsuites/smptests/smpschedule01/smpschedule01.scn b/testsuites/smptests/smpschedule01/smpschedule01.scn
new file mode 100644
index 0000000000..e290a64706
--- /dev/null
+++ b/testsuites/smptests/smpschedule01/smpschedule01.scn
@@ -0,0 +1,2 @@
+*** TEST SMPSCHEDULE 1 ***
+*** END OF TEST SMPSCHEDULE 1 ***