diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-05-02 15:33:23 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-05-05 08:26:27 +0200 |
commit | 145becf0759d39d7779760af8f1e11d623997938 (patch) | |
tree | 104e027282b896e3cf1a35bfcaecd0a6bf25505c /testsuites/smptests/smpipi01 | |
parent | score: SMP_FATAL_SCHEDULER_WITHOUT_PROCESSORS (diff) | |
download | rtems-145becf0759d39d7779760af8f1e11d623997938.tar.bz2 |
score: Add SMP test message handler
This handler can be used to test the inter-processor interrupt
implementation.
Diffstat (limited to '')
-rw-r--r-- | testsuites/smptests/smpipi01/Makefile.am | 19 | ||||
-rw-r--r-- | testsuites/smptests/smpipi01/init.c | 207 | ||||
-rw-r--r-- | testsuites/smptests/smpipi01/smpipi01.doc | 11 | ||||
-rw-r--r-- | testsuites/smptests/smpipi01/smpipi01.scn | 6 |
4 files changed, 243 insertions, 0 deletions
diff --git a/testsuites/smptests/smpipi01/Makefile.am b/testsuites/smptests/smpipi01/Makefile.am new file mode 100644 index 0000000000..a00f1076ca --- /dev/null +++ b/testsuites/smptests/smpipi01/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = smpipi01 +smpipi01_SOURCES = init.c + +dist_rtems_tests_DATA = smpipi01.scn smpipi01.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 = $(smpipi01_OBJECTS) +LINK_LIBS = $(smpipi01_LDLIBS) + +smpipi01$(EXEEXT): $(smpipi01_OBJECTS) $(smpipi01_DEPENDENCIES) + @rm -f smpipi01$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/smptests/smpipi01/init.c b/testsuites/smptests/smpipi01/init.c new file mode 100644 index 0000000000..db0688c5ee --- /dev/null +++ b/testsuites/smptests/smpipi01/init.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2014 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/score/smpimpl.h> +#include <rtems/score/smpbarrier.h> +#include <rtems/counter.h> +#include <rtems.h> + +#include <stdio.h> + +#include "tmacros.h" + +const char rtems_test_name[] = "SMPIPI 1"; + +#define CPU_COUNT 32 + +typedef struct { + uint32_t value; + uint32_t cache_line_separation[31]; +} test_counter; + +typedef struct { + test_counter counters[CPU_COUNT]; + uint32_t copy_counters[CPU_COUNT]; + SMP_barrier_Control barrier; + SMP_barrier_State main_barrier_state; + SMP_barrier_State worker_barrier_state; +} test_context; + +static test_context test_instance = { + .barrier = SMP_BARRIER_CONTROL_INITIALIZER, + .main_barrier_state = SMP_BARRIER_STATE_INITIALIZER, + .worker_barrier_state = SMP_BARRIER_STATE_INITIALIZER +}; + +static void barrier( + test_context *ctx, + SMP_barrier_State *state +) +{ + _SMP_barrier_Wait(&ctx->barrier, state, 2); +} + +static void barrier_handler(Per_CPU_Control *cpu_self) +{ + test_context *ctx = &test_instance; + uint32_t cpu_index_self = _Per_CPU_Get_index(cpu_self); + SMP_barrier_State *bs = &ctx->worker_barrier_state; + + ++ctx->counters[cpu_index_self].value; + + /* (A) */ + barrier(ctx, bs); + + /* (B) */ + barrier(ctx, bs); + + /* (C) */ + barrier(ctx, bs); +} + +static void test_send_message_while_processing_a_message( + test_context *ctx +) +{ + uint32_t cpu_count = rtems_get_processor_count(); + uint32_t cpu_index_self = rtems_get_current_processor(); + uint32_t cpu_index; + SMP_barrier_State *bs = &ctx->main_barrier_state; + + _SMP_Set_test_message_handler(barrier_handler); + + for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { + if (cpu_index != cpu_index_self) { + _SMP_Send_message(cpu_index, SMP_MESSAGE_TEST); + + /* (A) */ + barrier(ctx, bs); + + rtems_test_assert(ctx->counters[cpu_index].value == 1); + _SMP_Send_message(cpu_index, SMP_MESSAGE_TEST); + + /* (B) */ + barrier(ctx, bs); + + rtems_test_assert(ctx->counters[cpu_index].value == 1); + + /* (C) */ + barrier(ctx, bs); + + /* (A) */ + barrier(ctx, bs); + + rtems_test_assert(ctx->counters[cpu_index].value == 2); + + /* (B) */ + barrier(ctx, bs); + + /* (C) */ + barrier(ctx, bs); + + ctx->counters[cpu_index].value = 0; + } + } +} + +static void counter_handler(Per_CPU_Control *cpu_self) +{ + test_context *ctx = &test_instance; + uint32_t cpu_index_self = _Per_CPU_Get_index(cpu_self); + + ++ctx->counters[cpu_index_self].value; +} + +static void test_send_message_flood( + test_context *ctx +) +{ + uint32_t cpu_count = rtems_get_processor_count(); + uint32_t cpu_index_self = rtems_get_current_processor(); + uint32_t cpu_index; + + _SMP_Set_test_message_handler(counter_handler); + + for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { + uint32_t i; + + /* Wait 1us so that all outstanding messages have been processed */ + rtems_counter_delay_nanoseconds(1000000); + + for (i = 0; i < cpu_count; ++i) { + if (i != cpu_index) { + ctx->copy_counters[i] = ctx->counters[i].value; + } + } + + for (i = 0; i < 100000; ++i) { + _SMP_Send_message(cpu_index, SMP_MESSAGE_TEST); + } + + for (i = 0; i < cpu_count; ++i) { + if (i != cpu_index) { + rtems_test_assert(ctx->copy_counters[i] == ctx->counters[i].value); + } + } + } + + for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { + printf( + "inter-processor interrupts for processor %" + PRIu32 "%s: %" PRIu32 "\n", + cpu_index, + cpu_index == cpu_index_self ? " (main)" : "", + ctx->counters[cpu_index].value + ); + } +} + +static void test(void) +{ + test_context *ctx = &test_instance; + + test_send_message_while_processing_a_message(ctx); + test_send_message_flood(ctx); +} + +static void Init(rtems_task_argument arg) +{ + TEST_BEGIN(); + + test(); + + TEST_END(); + rtems_test_exit(0); +} + +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_SMP_APPLICATION + +#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT + +#define CONFIGURE_MAXIMUM_TASKS 1 + +#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/smpipi01/smpipi01.doc b/testsuites/smptests/smpipi01/smpipi01.doc new file mode 100644 index 0000000000..72fe5d23e2 --- /dev/null +++ b/testsuites/smptests/smpipi01/smpipi01.doc @@ -0,0 +1,11 @@ +This file describes the directives and concepts tested by this test set. + +test set name: smpipi01 + +directives: + + - _SMP_Send_message() + +concepts: + + - Ensure that inter-processor interrupts work as expected. diff --git a/testsuites/smptests/smpipi01/smpipi01.scn b/testsuites/smptests/smpipi01/smpipi01.scn new file mode 100644 index 0000000000..255e9519d9 --- /dev/null +++ b/testsuites/smptests/smpipi01/smpipi01.scn @@ -0,0 +1,6 @@ +*** BEGIN OF TEST SMPIPI 1 *** +inter-processor interrupts for processor 0: 12502 +inter-processor interrupts for processor 1: 12502 +inter-processor interrupts for processor 2: 12502 +inter-processor interrupts for processor 3 (main): 99987 +*** END OF TEST SMPIPI 1 *** |