[rtems commit] smptests/smpmigration01: New test

Sebastian Huber sebh at rtems.org
Mon Aug 5 11:40:51 UTC 2013


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Aug  2 11:37:28 2013 +0200

smptests/smpmigration01: New test

---

 testsuites/smptests/Makefile.am                    |    1 +
 testsuites/smptests/configure.ac                   |    1 +
 testsuites/smptests/smpmigration01/Makefile.am     |   19 ++
 testsuites/smptests/smpmigration01/init.c          |  209 ++++++++++++++++++++
 .../smptests/smpmigration01/smpmigration01.doc     |   15 ++
 .../smptests/smpmigration01/smpmigration01.scn     |   17 ++
 6 files changed, 262 insertions(+), 0 deletions(-)

diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am
index dbd0603..22e69b4 100644
--- a/testsuites/smptests/Makefile.am
+++ b/testsuites/smptests/Makefile.am
@@ -19,6 +19,7 @@ SUBDIRS += smpatomic05
 SUBDIRS += smpatomic06
 SUBDIRS += smpatomic07
 SUBDIRS += smplock01
+SUBDIRS += smpmigration01
 SUBDIRS += smpschedule01
 SUBDIRS += smpsignal01
 SUBDIRS += smpunsupported01
diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac
index 92e2a41..08aaeef 100644
--- a/testsuites/smptests/configure.ac
+++ b/testsuites/smptests/configure.ac
@@ -54,6 +54,7 @@ smpatomic05/Makefile
 smpatomic06/Makefile
 smpatomic07/Makefile
 smplock01/Makefile
+smpmigration01/Makefile
 smppsxsignal01/Makefile
 smpschedule01/Makefile
 smpsignal01/Makefile
diff --git a/testsuites/smptests/smpmigration01/Makefile.am b/testsuites/smptests/smpmigration01/Makefile.am
new file mode 100644
index 0000000..12cef96
--- /dev/null
+++ b/testsuites/smptests/smpmigration01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = smpmigration01
+smpmigration01_SOURCES = init.c
+
+dist_rtems_tests_DATA = smpmigration01.scn smpmigration01.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 = $(smpmigration01_OBJECTS)
+LINK_LIBS = $(smpmigration01_LDLIBS)
+
+smpmigration01$(EXEEXT): $(smpmigration01_OBJECTS) $(smpmigration01_DEPENDENCIES)
+	@rm -f smpmigration01$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/smptests/smpmigration01/init.c b/testsuites/smptests/smpmigration01/init.c
new file mode 100644
index 0000000..ccad57f
--- /dev/null
+++ b/testsuites/smptests/smpmigration01/init.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2013 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.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include "tmacros.h"
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#define CPU_COUNT 2
+
+#define RUNNER_COUNT (CPU_COUNT + 1)
+
+#define PRIO_STOP 2
+
+#define PRIO_HIGH 3
+
+#define PRIO_NORMAL 4
+
+/* FIXME: Use atomic operations instead of volatile */
+
+typedef struct {
+  uint32_t counter;
+  uint32_t unused_space_for_cache_line_alignment[7];
+} cache_aligned_counter;
+
+typedef struct {
+  cache_aligned_counter tokens_per_cpu[CPU_COUNT];
+  volatile cache_aligned_counter cycles_per_cpu[CPU_COUNT];
+} test_counters;
+
+typedef struct {
+  test_counters counters[RUNNER_COUNT];
+  volatile rtems_task_argument token;
+  rtems_id runner_ids[RUNNER_COUNT];
+} test_context;
+
+CPU_STRUCTURE_ALIGNMENT static test_context ctx_instance;
+
+static void change_prio(rtems_id task, rtems_task_priority prio)
+{
+  rtems_status_code sc;
+  rtems_task_priority unused;
+
+  sc = rtems_task_set_priority(task, prio, &unused);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void runner(rtems_task_argument self)
+{
+  test_context *ctx = &ctx_instance;
+  rtems_task_argument next = (self + 1) % RUNNER_COUNT;
+  rtems_id next_runner = ctx->runner_ids[next];
+  test_counters *counters = &ctx->counters[self];
+  test_counters *next_counters = &ctx->counters[next];
+
+  while (true) {
+    uint32_t current_cpu = rtems_smp_get_current_processor();
+
+    ++counters->cycles_per_cpu[current_cpu].counter;
+
+    if (ctx->token == self) {
+      uint32_t other_cpu = (current_cpu + 1) % CPU_COUNT;
+      uint32_t snapshot;
+
+      ++counters->tokens_per_cpu[current_cpu].counter;
+
+      change_prio(next_runner, PRIO_HIGH);
+
+      snapshot = next_counters->cycles_per_cpu[other_cpu].counter;
+      while (next_counters->cycles_per_cpu[other_cpu].counter == snapshot) {
+        /* Wait for other thread to resume execution */
+      }
+
+      ctx->token = next;
+
+      change_prio(RTEMS_SELF, PRIO_NORMAL);
+    }
+  }
+}
+
+static void stopper(rtems_task_argument arg)
+{
+  (void) arg;
+
+  while (true) {
+    /* Do nothing */
+  }
+}
+
+static void test(void)
+{
+  test_context *ctx = &ctx_instance;
+  rtems_status_code sc;
+  rtems_task_argument runner_index;
+  rtems_id stopper_id;
+  uint32_t expected_tokens;
+  uint32_t total_delta;
+
+  sc = rtems_task_create(
+    rtems_build_name('S', 'T', 'O', 'P'),
+    PRIO_STOP,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &stopper_id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) {
+    sc = rtems_task_create(
+      rtems_build_name('R', 'U', 'N', (char) ('0' + runner_index)),
+      PRIO_HIGH + runner_index,
+      RTEMS_MINIMUM_STACK_SIZE,
+      RTEMS_DEFAULT_MODES,
+      RTEMS_DEFAULT_ATTRIBUTES,
+      &ctx->runner_ids[runner_index]
+    );
+    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+    sc = rtems_task_start(ctx->runner_ids[runner_index], runner, runner_index);
+    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+  }
+
+  sc = rtems_task_wake_after(10 * rtems_clock_get_ticks_per_second());
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(stopper_id, stopper, 0);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) {
+    test_counters *counters = &ctx->counters[runner_index];
+    size_t cpu;
+
+    printf("runner %" PRIuPTR "\n", runner_index);
+
+    for (cpu = 0; cpu < CPU_COUNT; ++cpu) {
+      printf(
+        "\tcpu %zu tokens %" PRIu32 "\n"
+        "\tcpu %zu cycles %" PRIu32 "\n",
+        cpu,
+        counters->tokens_per_cpu[cpu].counter,
+        cpu,
+        counters->cycles_per_cpu[cpu].counter
+      );
+    }
+  }
+
+  expected_tokens = ctx->counters[0].tokens_per_cpu[0].counter;
+  total_delta = 0;
+  for (runner_index = 0; runner_index < RUNNER_COUNT; ++runner_index) {
+    test_counters *counters = &ctx->counters[runner_index];
+    size_t cpu;
+
+    for (cpu = 0; cpu < CPU_COUNT; ++cpu) {
+      uint32_t tokens = counters->tokens_per_cpu[cpu].counter;
+      uint32_t delta = tokens > expected_tokens ?
+        tokens - expected_tokens : expected_tokens - tokens;
+
+      rtems_test_assert(delta <= 1);
+
+      total_delta += delta;
+    }
+  }
+
+  rtems_test_assert(total_delta <= (RUNNER_COUNT * CPU_COUNT - 1));
+}
+
+static void Init(rtems_task_argument arg)
+{
+  puts("\n\n*** TEST SMPMIGRATION 1 ***");
+
+  if (rtems_smp_get_processor_count() >= 2) {
+    test();
+  }
+
+  puts("*** END OF TEST SMPMIGRATION 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 (2 + RUNNER_COUNT)
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/smptests/smpmigration01/smpmigration01.doc b/testsuites/smptests/smpmigration01/smpmigration01.doc
new file mode 100644
index 0000000..e30bf40
--- /dev/null
+++ b/testsuites/smptests/smpmigration01/smpmigration01.doc
@@ -0,0 +1,15 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smpmigration01
+
+The screen file was obtained on a PowerPC QorIQ P1020E target running with a
+processor frequency of 800MHz.
+
+directives:
+
+  - _Thread_Dispatch()
+  - _Scheduler_simple_smp_Allocate_processor()
+
+concepts:
+
+  - Ensure that thread migration works.
diff --git a/testsuites/smptests/smpmigration01/smpmigration01.scn b/testsuites/smptests/smpmigration01/smpmigration01.scn
new file mode 100644
index 0000000..dc3bae2
--- /dev/null
+++ b/testsuites/smptests/smpmigration01/smpmigration01.scn
@@ -0,0 +1,17 @@
+*** TEST SMPMIGRATION 1 ***
+runner 0
+        cpu 0 tokens 411501
+        cpu 0 cycles 9464534
+        cpu 1 tokens 411501
+        cpu 1 cycles 9464802
+runner 1
+        cpu 0 tokens 411500
+        cpu 0 cycles 41936630
+        cpu 1 tokens 411501
+        cpu 1 cycles 42009945
+runner 2
+        cpu 0 tokens 411501
+        cpu 0 cycles 6583983
+        cpu 1 tokens 411500
+        cpu 1 cycles 6583701
+*** END OF TEST SMPMIGRATION 1 ***




More information about the vc mailing list