From 33e18a4f4e406add8a688271b77a40a4dd4908d2 Mon Sep 17 00:00:00 2001 From: WeiY Date: Sat, 28 Sep 2013 14:54:38 +0800 Subject: rename smpatomic08 to smpatomic01 --- testsuites/smptests/Makefile.am | 2 +- testsuites/smptests/configure.ac | 2 +- testsuites/smptests/smpatomic01/Makefile.am | 19 + testsuites/smptests/smpatomic01/init.c | 595 ++++++++++++++++++++++++ testsuites/smptests/smpatomic01/smpatomic01.doc | 12 + testsuites/smptests/smpatomic01/smpatomic01.scn | 29 ++ testsuites/smptests/smpatomic08/Makefile.am | 19 - testsuites/smptests/smpatomic08/init.c | 595 ------------------------ testsuites/smptests/smpatomic08/smpatomic08.doc | 12 - testsuites/smptests/smpatomic08/smpatomic08.scn | 23 - 10 files changed, 657 insertions(+), 651 deletions(-) create mode 100644 testsuites/smptests/smpatomic01/Makefile.am create mode 100644 testsuites/smptests/smpatomic01/init.c create mode 100644 testsuites/smptests/smpatomic01/smpatomic01.doc create mode 100644 testsuites/smptests/smpatomic01/smpatomic01.scn delete mode 100644 testsuites/smptests/smpatomic08/Makefile.am delete mode 100644 testsuites/smptests/smpatomic08/init.c delete mode 100644 testsuites/smptests/smpatomic08/smpatomic08.doc delete mode 100644 testsuites/smptests/smpatomic08/smpatomic08.scn diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am index d8b5a3edd1..3fa0d200e9 100644 --- a/testsuites/smptests/Makefile.am +++ b/testsuites/smptests/Makefile.am @@ -12,7 +12,7 @@ SUBDIRS += smp07 SUBDIRS += smp08 SUBDIRS += smp09 if ATOMIC -SUBDIRS += smpatomic08 +SUBDIRS += smpatomic01 endif SUBDIRS += smplock01 SUBDIRS += smpmigration01 diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac index 35f704dbdc..3536c1127b 100644 --- a/testsuites/smptests/configure.ac +++ b/testsuites/smptests/configure.ac @@ -46,7 +46,7 @@ smp06/Makefile smp07/Makefile smp08/Makefile smp09/Makefile -smpatomic08/Makefile +smpatomic01/Makefile smplock01/Makefile smpmigration01/Makefile smppsxsignal01/Makefile diff --git a/testsuites/smptests/smpatomic01/Makefile.am b/testsuites/smptests/smpatomic01/Makefile.am new file mode 100644 index 0000000000..f26cb54046 --- /dev/null +++ b/testsuites/smptests/smpatomic01/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = smpatomic01 +smpatomic01_SOURCES = init.c + +dist_rtems_tests_DATA = smpatomic01.scn smpatomic01.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 = $(smpatomic01_OBJECTS) +LINK_LIBS = $(smpatomic01_LDLIBS) + +smpatomic01$(EXEEXT): $(smpatomic01_OBJECTS) $(smpatomic01_DEPENDENCIES) + @rm -f smpatomic01$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/smptests/smpatomic01/init.c b/testsuites/smptests/smpatomic01/init.c new file mode 100644 index 0000000000..feffe5efb4 --- /dev/null +++ b/testsuites/smptests/smpatomic01/init.c @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * Copyright (c) 2013 Deng Hengyi. + * + * 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 +#include +#include + +#include "tmacros.h" + +/* FIXME: Add barrier to Score */ + +typedef struct { + Atomic_Ulong value; + Atomic_Ulong sense; +} SMP_barrier_Control; + +typedef struct { + unsigned long sense; +} SMP_barrier_State; + +#define SMP_BARRIER_CONTROL_INITIALIZER \ + { ATOMIC_INITIALIZER_ULONG( 0 ), ATOMIC_INITIALIZER_ULONG( 0 ) } + +#define SMP_BARRIER_STATE_INITIALIZER { 0 } + +static void _SMP_barrier_Wait( + SMP_barrier_Control *control, + SMP_barrier_State *state, + unsigned long count +) +{ + unsigned long sense = ~state->sense; + unsigned long previous_value; + + state->sense = sense; + + previous_value = _Atomic_Fetch_add_ulong( + &control->value, + 1, + ATOMIC_ORDER_RELAXED + ); + + if ( previous_value + 1 == count ) { + _Atomic_Store_ulong( &control->value, 0, ATOMIC_ORDER_RELAXED ); + _Atomic_Store_ulong( &control->sense, sense, ATOMIC_ORDER_RELEASE ); + } else { + while ( + _Atomic_Load_ulong( &control->sense, ATOMIC_ORDER_ACQUIRE ) != sense + ) { + /* Wait */ + } + } +} + +#define MASTER_PRIORITY 1 + +#define WORKER_PRIORITY 2 + +#define CPU_COUNT 32 + +typedef struct { + Atomic_Ulong stop; + SMP_barrier_Control barrier; + size_t worker_count; + rtems_id stop_worker_timer_id; + Atomic_Ulong atomic_value; + unsigned long per_worker_value[CPU_COUNT]; + unsigned long normal_value; + Atomic_Flag global_flag; +} test_context; + +typedef struct { + void (*init)(test_context *ctx); + void (*body)(test_context *ctx, size_t worker_index); + void (*fini)(test_context *ctx); +} test_case; + +static test_context test_instance = { + .stop = ATOMIC_INITIALIZER_ULONG(0), + .barrier = SMP_BARRIER_CONTROL_INITIALIZER +}; + +static bool stop(test_context *ctx) +{ + return _Atomic_Load_ulong(&ctx->stop, ATOMIC_ORDER_RELAXED) != 0; +} + +static bool is_master_worker(size_t worker_index) +{ + return worker_index == 0; +} + +static void test_fini( + test_context *ctx, + const char *test, + bool atomic +) +{ + unsigned long expected_value = 0; + unsigned long actual_value; + size_t worker_index; + + printf("=== atomic %s test case ==\n", test); + + for (worker_index = 0; worker_index < ctx->worker_count; ++worker_index) { + unsigned long worker_value = ctx->per_worker_value[worker_index]; + + expected_value += worker_value; + + printf( + "worker %zu value: %lu\n", + worker_index, + worker_value + ); + } + + if (atomic) { + actual_value = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); + } else { + actual_value = ctx->normal_value; + } + + printf( + "atomic value: expected = %lu, actual = %lu\n", + expected_value, + actual_value + ); + + rtems_test_assert(expected_value == actual_value); +} + +static void test_atomic_add_init(test_context *ctx) +{ + _Atomic_Init_ulong(&ctx->atomic_value, 0); +} + +static void test_atomic_add_body(test_context *ctx, size_t worker_index) +{ + unsigned long counter = 0; + + while (!stop(ctx)) { + ++counter; + _Atomic_Fetch_add_ulong(&ctx->atomic_value, 1, ATOMIC_ORDER_RELAXED); + } + + ctx->per_worker_value[worker_index] = counter; +} + +static void test_atomic_add_fini(test_context *ctx) +{ + test_fini(ctx, "add", true); +} + +static void test_atomic_flag_init(test_context *ctx) +{ + _Atomic_Flag_clear(&ctx->global_flag, ATOMIC_ORDER_RELEASE); + ctx->normal_value = 0; +} + +static void test_atomic_flag_body(test_context *ctx, size_t worker_index) +{ + unsigned long counter = 0; + + while (!stop(ctx)) { + while (_Atomic_Flag_test_and_set(&ctx->global_flag, ATOMIC_ORDER_ACQUIRE)) { + /* Wait */ + } + + ++counter; + ++ctx->normal_value; + + _Atomic_Flag_clear(&ctx->global_flag, ATOMIC_ORDER_RELEASE); + } + + ctx->per_worker_value[worker_index] = counter; +} + +static void test_atomic_flag_fini(test_context *ctx) +{ + test_fini(ctx, "flag", false); +} + +static void test_atomic_sub_init(test_context *ctx) +{ + _Atomic_Init_ulong(&ctx->atomic_value, 0); +} + +static void test_atomic_sub_body(test_context *ctx, size_t worker_index) +{ + unsigned long counter = 0; + + while (!stop(ctx)) { + --counter; + _Atomic_Fetch_sub_ulong(&ctx->atomic_value, 1, ATOMIC_ORDER_RELAXED); + } + + ctx->per_worker_value[worker_index] = counter; +} + +static void test_atomic_sub_fini(test_context *ctx) +{ + test_fini(ctx, "sub", true); +} + +static void test_atomic_compare_exchange_init(test_context *ctx) +{ + _Atomic_Init_ulong(&ctx->atomic_value, 0); + ctx->normal_value = 0; +} + +static void test_atomic_compare_exchange_body(test_context *ctx, size_t worker_index) +{ + unsigned long counter = 0; + + while (!stop(ctx)) { + bool success; + + do { + unsigned long zero = 0; + + success = _Atomic_Compare_exchange_ulong( + &ctx->atomic_value, + &zero, + 1, + ATOMIC_ORDER_ACQUIRE, + ATOMIC_ORDER_RELAXED + ); + } while (!success); + + ++counter; + ++ctx->normal_value; + + _Atomic_Store_ulong(&ctx->atomic_value, 0, ATOMIC_ORDER_RELEASE); + } + + ctx->per_worker_value[worker_index] = counter; +} + +static void test_atomic_compare_exchange_fini(test_context *ctx) +{ + test_fini(ctx, "compare exchange", false); +} + +static void test_atomic_or_and_init(test_context *ctx) +{ + _Atomic_Init_ulong(&ctx->atomic_value, 0); +} + +static void test_atomic_or_and_body(test_context *ctx, size_t worker_index) +{ + unsigned long the_bit = 1UL << worker_index; + unsigned long current_bit = 0; + + while (!stop(ctx)) { + unsigned long previous; + + if (current_bit != 0) { + previous = _Atomic_Fetch_and_ulong( + &ctx->atomic_value, + ~the_bit, + ATOMIC_ORDER_RELAXED + ); + current_bit = 0; + } else { + previous = _Atomic_Fetch_or_ulong( + &ctx->atomic_value, + the_bit, + ATOMIC_ORDER_RELAXED + ); + current_bit = the_bit; + } + + rtems_test_assert((previous & the_bit) != current_bit); + } + + ctx->per_worker_value[worker_index] = current_bit; +} + +static void test_atomic_or_and_fini(test_context *ctx) +{ + test_fini(ctx, "or/and", true); +} + +static const test_case test_cases[] = { + { + test_atomic_add_init, + test_atomic_add_body, + test_atomic_add_fini + }, { + test_atomic_flag_init, + test_atomic_flag_body, + test_atomic_flag_fini + }, { + test_atomic_sub_init, + test_atomic_sub_body, + test_atomic_sub_fini + }, { + test_atomic_compare_exchange_init, + test_atomic_compare_exchange_body, + test_atomic_compare_exchange_fini + }, { + test_atomic_or_and_init, + test_atomic_or_and_body, + test_atomic_or_and_fini + }, +}; + +#define TEST_COUNT RTEMS_ARRAY_SIZE(test_cases) + +static void stop_worker_timer(rtems_id timer_id, void *arg) +{ + test_context *ctx = arg; + + _Atomic_Store_ulong(&ctx->stop, 1, ATOMIC_ORDER_RELAXED); +} + +static void start_worker_stop_timer(test_context *ctx) +{ + rtems_status_code sc; + + _Atomic_Store_ulong(&ctx->stop, 0, ATOMIC_ORDER_RELEASE); + + sc = rtems_timer_fire_after( + ctx->stop_worker_timer_id, + rtems_clock_get_ticks_per_second(), + stop_worker_timer, + ctx + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + +static void run_tests(test_context *ctx, size_t worker_index) +{ + SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER; + size_t test; + + for (test = 0; test < TEST_COUNT; ++test) { + const test_case *tc = &test_cases[test]; + + if (is_master_worker(worker_index)) { + start_worker_stop_timer(ctx); + (*tc->init)(ctx); + } + + _SMP_barrier_Wait(&ctx->barrier, &bs, ctx->worker_count); + + (*tc->body)(ctx, worker_index); + + _SMP_barrier_Wait(&ctx->barrier, &bs, ctx->worker_count); + + if (is_master_worker(worker_index)) { + (*tc->fini)(ctx); + } + } +} + +static void worker_task(size_t worker_index) +{ + test_context *ctx = &test_instance; + + run_tests(ctx, worker_index); + + (void) rtems_task_suspend(RTEMS_SELF); + rtems_test_assert(0); +} + +static void test_static_and_dynamic_initialization(void) +{ + static Atomic_Ulong static_ulong = + ATOMIC_INITIALIZER_ULONG(0xdeadbeefUL); + static Atomic_Pointer static_ptr = + ATOMIC_INITIALIZER_PTR(&static_ptr); + static Atomic_Flag static_flag = ATOMIC_INITIALIZER_FLAG; + + Atomic_Ulong stack_ulong; + Atomic_Pointer stack_ptr; + Atomic_Flag stack_flag; + + puts("=== static and dynamic initialization test case ==="); + + _Atomic_Init_ulong(&stack_ulong, 0xdeadbeefUL); + _Atomic_Init_ptr(&stack_ptr, &static_ptr); + _Atomic_Flag_clear(&stack_flag, ATOMIC_ORDER_RELAXED); + + rtems_test_assert( + memcmp(&stack_ulong, &static_ulong, sizeof(stack_ulong)) == 0 + ); + rtems_test_assert( + memcmp(&stack_ptr, &static_ptr, sizeof(stack_ptr)) == 0 + ); + rtems_test_assert( + memcmp(&stack_flag, &static_flag, sizeof(stack_flag)) == 0 + ); + + rtems_test_assert( + _Atomic_Load_ulong(&stack_ulong, ATOMIC_ORDER_RELAXED) == 0xdeadbeefUL + ); + rtems_test_assert( + _Atomic_Load_ptr(&stack_ptr, ATOMIC_ORDER_RELAXED) == &static_ptr + ); + rtems_test_assert( + !_Atomic_Flag_test_and_set(&stack_flag, ATOMIC_ORDER_RELAXED) + ); +} + +static void test(void) +{ + test_context *ctx = &test_instance; + rtems_status_code sc; + size_t worker_index; + + test_static_and_dynamic_initialization(); + + ctx->worker_count = rtems_smp_get_processor_count(); + + sc = rtems_timer_create( + rtems_build_name('S', 'T', 'O', 'P'), + &ctx->stop_worker_timer_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + for (worker_index = 1; worker_index < ctx->worker_count; ++worker_index) { + rtems_id worker_id; + + sc = rtems_task_create( + rtems_build_name('W', 'O', 'R', 'K'), + WORKER_PRIORITY, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &worker_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start(worker_id, worker_task, worker_index); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + } + + run_tests(ctx, 0); +} + +typedef void (*simple_test_body)(test_context *ctx); + +static void test_simple_atomic_add_body(test_context *ctx) +{ + unsigned long a = 2, b = 1; + unsigned long c; + + puts("=== atomic simple add test case ==\n"); + + _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); + _Atomic_Fetch_add_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED); + c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); + rtems_test_assert(c == (a + b)); +} + +static void test_simple_atomic_sub_body(test_context *ctx) +{ + unsigned long a = 2, b = 1; + unsigned long c; + + puts("=== atomic simple sub test case ==\n"); + + _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); + _Atomic_Fetch_sub_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED); + c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); + rtems_test_assert(c == (a - b)); +} + +static void test_simple_atomic_or_body(test_context *ctx) +{ + unsigned long a = 2, b = 1; + unsigned long c; + + puts("=== atomic simple or test case ==\n"); + + _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); + _Atomic_Fetch_or_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED); + c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); + rtems_test_assert(c == (a | b)); +} + +static void test_simple_atomic_and_body(test_context *ctx) +{ + unsigned long a = 2, b = 1; + unsigned long c; + + puts("=== atomic simple and test case ==\n"); + + _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); + _Atomic_Fetch_and_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED); + c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); + rtems_test_assert(c == (a & b)); +} + +static void test_simple_atomic_exchange_body(test_context *ctx) +{ + unsigned long a = 2, b = 1; + unsigned long c; + + puts("=== atomic simple exchange test case ==\n"); + + _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); + _Atomic_Exchange_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED); + c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); + rtems_test_assert(c == b); +} + +static void test_simple_atomic_compare_exchange_body(test_context *ctx) +{ + unsigned long a = 2, b = 1; + unsigned long c; + + puts("=== atomic simple compare exchange test case ==\n"); + + _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); + _Atomic_Compare_exchange_ulong(&ctx->atomic_value, &a, b, + ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED); + c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); + rtems_test_assert(c == b); +} + +static const simple_test_body simple_test_bodies[] = { + test_simple_atomic_add_body, + test_simple_atomic_sub_body, + test_simple_atomic_or_body, + test_simple_atomic_and_body, + test_simple_atomic_exchange_body, + test_simple_atomic_compare_exchange_body, +}; + +#define SIMPLE_TEST_COUNT RTEMS_ARRAY_SIZE(simple_test_bodies) + +static void simple_tests(void) +{ + test_context *ctx = &test_instance; + size_t test; + + for (test = 0; test < SIMPLE_TEST_COUNT; ++test) { + const simple_test_body *test_body = &simple_test_bodies[test]; + + (*test_body)(ctx); + } +} + +static void Init(rtems_task_argument arg) +{ + puts("\n\n*** TEST SMPATOMIC 1 ***"); + + simple_tests(); + + test(); + + puts("*** END OF TEST SMPATOMIC 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 CPU_COUNT + +#define CONFIGURE_MAXIMUM_TIMERS 1 + +#define CONFIGURE_INIT_TASK_PRIORITY MASTER_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 diff --git a/testsuites/smptests/smpatomic01/smpatomic01.doc b/testsuites/smptests/smpatomic01/smpatomic01.doc new file mode 100644 index 0000000000..e4a0f515ad --- /dev/null +++ b/testsuites/smptests/smpatomic01/smpatomic01.doc @@ -0,0 +1,12 @@ +This file describes the directives and concepts tested by this test set. + +test set name: smpatomic01 + +directives: + + - ATOMIC_* + - _Atomic_* + +concepts: + + - Ensure that the atomic operations work. diff --git a/testsuites/smptests/smpatomic01/smpatomic01.scn b/testsuites/smptests/smpatomic01/smpatomic01.scn new file mode 100644 index 0000000000..1122fae722 --- /dev/null +++ b/testsuites/smptests/smpatomic01/smpatomic01.scn @@ -0,0 +1,29 @@ +*** TEST SMPATOMIC 1 *** +=== atomic simple add test case == +=== atomic simple sub test case == +=== atomic simple or test case == +=== atomic simple and test case == +=== atomic simple exchange test case == +=== atomic simple compare exchange test case == +=== static and dynamic initialization test case === +=== atomic add test case == +worker 0 value: 16686 +worker 1 value: 36405 +atomic value: expected = 53091, actual = 53091 +=== atomic flag test case == +worker 0 value: 5588 +worker 1 value: 16019 +atomic value: expected = 21607, actual = 21607 +=== atomic sub test case == +worker 0 value: 4294950967 +worker 1 value: 4294930886 +atomic value: expected = 4294914557, actual = 4294914557 +=== atomic compare exchange test case == +worker 0 value: 2950 +worker 1 value: 22456 +atomic value: expected = 25406, actual = 25406 +=== atomic or/and test case == +worker 0 value: 1 +worker 1 value: 0 +atomic value: expected = 1, actual = 1 +*** END OF TEST SMPATOMIC 1 *** diff --git a/testsuites/smptests/smpatomic08/Makefile.am b/testsuites/smptests/smpatomic08/Makefile.am deleted file mode 100644 index f6abd55c49..0000000000 --- a/testsuites/smptests/smpatomic08/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -rtems_tests_PROGRAMS = smpatomic08 -smpatomic08_SOURCES = init.c - -dist_rtems_tests_DATA = smpatomic08.scn smpatomic08.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 = $(smpatomic08_OBJECTS) -LINK_LIBS = $(smpatomic08_LDLIBS) - -smpatomic08$(EXEEXT): $(smpatomic08_OBJECTS) $(smpatomic08_DEPENDENCIES) - @rm -f smpatomic08$(EXEEXT) - $(make-exe) - -include $(top_srcdir)/../automake/local.am diff --git a/testsuites/smptests/smpatomic08/init.c b/testsuites/smptests/smpatomic08/init.c deleted file mode 100644 index 1120b2b2b1..0000000000 --- a/testsuites/smptests/smpatomic08/init.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * Copyright (c) 2013 Deng Hengyi. - * - * 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 -#include -#include - -#include "tmacros.h" - -/* FIXME: Add barrier to Score */ - -typedef struct { - Atomic_Ulong value; - Atomic_Ulong sense; -} SMP_barrier_Control; - -typedef struct { - unsigned long sense; -} SMP_barrier_State; - -#define SMP_BARRIER_CONTROL_INITIALIZER \ - { ATOMIC_INITIALIZER_ULONG( 0 ), ATOMIC_INITIALIZER_ULONG( 0 ) } - -#define SMP_BARRIER_STATE_INITIALIZER { 0 } - -static void _SMP_barrier_Wait( - SMP_barrier_Control *control, - SMP_barrier_State *state, - unsigned long count -) -{ - unsigned long sense = ~state->sense; - unsigned long previous_value; - - state->sense = sense; - - previous_value = _Atomic_Fetch_add_ulong( - &control->value, - 1, - ATOMIC_ORDER_RELAXED - ); - - if ( previous_value + 1 == count ) { - _Atomic_Store_ulong( &control->value, 0, ATOMIC_ORDER_RELAXED ); - _Atomic_Store_ulong( &control->sense, sense, ATOMIC_ORDER_RELEASE ); - } else { - while ( - _Atomic_Load_ulong( &control->sense, ATOMIC_ORDER_ACQUIRE ) != sense - ) { - /* Wait */ - } - } -} - -#define MASTER_PRIORITY 1 - -#define WORKER_PRIORITY 2 - -#define CPU_COUNT 32 - -typedef struct { - Atomic_Ulong stop; - SMP_barrier_Control barrier; - size_t worker_count; - rtems_id stop_worker_timer_id; - Atomic_Ulong atomic_value; - unsigned long per_worker_value[CPU_COUNT]; - unsigned long normal_value; - Atomic_Flag global_flag; -} test_context; - -typedef struct { - void (*init)(test_context *ctx); - void (*body)(test_context *ctx, size_t worker_index); - void (*fini)(test_context *ctx); -} test_case; - -static test_context test_instance = { - .stop = ATOMIC_INITIALIZER_ULONG(0), - .barrier = SMP_BARRIER_CONTROL_INITIALIZER -}; - -static bool stop(test_context *ctx) -{ - return _Atomic_Load_ulong(&ctx->stop, ATOMIC_ORDER_RELAXED) != 0; -} - -static bool is_master_worker(size_t worker_index) -{ - return worker_index == 0; -} - -static void test_fini( - test_context *ctx, - const char *test, - bool atomic -) -{ - unsigned long expected_value = 0; - unsigned long actual_value; - size_t worker_index; - - printf("=== atomic %s test case ==\n", test); - - for (worker_index = 0; worker_index < ctx->worker_count; ++worker_index) { - unsigned long worker_value = ctx->per_worker_value[worker_index]; - - expected_value += worker_value; - - printf( - "worker %zu value: %lu\n", - worker_index, - worker_value - ); - } - - if (atomic) { - actual_value = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); - } else { - actual_value = ctx->normal_value; - } - - printf( - "atomic value: expected = %lu, actual = %lu\n", - expected_value, - actual_value - ); - - rtems_test_assert(expected_value == actual_value); -} - -static void test_atomic_add_init(test_context *ctx) -{ - _Atomic_Init_ulong(&ctx->atomic_value, 0); -} - -static void test_atomic_add_body(test_context *ctx, size_t worker_index) -{ - unsigned long counter = 0; - - while (!stop(ctx)) { - ++counter; - _Atomic_Fetch_add_ulong(&ctx->atomic_value, 1, ATOMIC_ORDER_RELAXED); - } - - ctx->per_worker_value[worker_index] = counter; -} - -static void test_atomic_add_fini(test_context *ctx) -{ - test_fini(ctx, "add", true); -} - -static void test_atomic_flag_init(test_context *ctx) -{ - _Atomic_Flag_clear(&ctx->global_flag, ATOMIC_ORDER_RELEASE); - ctx->normal_value = 0; -} - -static void test_atomic_flag_body(test_context *ctx, size_t worker_index) -{ - unsigned long counter = 0; - - while (!stop(ctx)) { - while (_Atomic_Flag_test_and_set(&ctx->global_flag, ATOMIC_ORDER_ACQUIRE)) { - /* Wait */ - } - - ++counter; - ++ctx->normal_value; - - _Atomic_Flag_clear(&ctx->global_flag, ATOMIC_ORDER_RELEASE); - } - - ctx->per_worker_value[worker_index] = counter; -} - -static void test_atomic_flag_fini(test_context *ctx) -{ - test_fini(ctx, "flag", false); -} - -static void test_atomic_sub_init(test_context *ctx) -{ - _Atomic_Init_ulong(&ctx->atomic_value, 0); -} - -static void test_atomic_sub_body(test_context *ctx, size_t worker_index) -{ - unsigned long counter = 0; - - while (!stop(ctx)) { - --counter; - _Atomic_Fetch_sub_ulong(&ctx->atomic_value, 1, ATOMIC_ORDER_RELAXED); - } - - ctx->per_worker_value[worker_index] = counter; -} - -static void test_atomic_sub_fini(test_context *ctx) -{ - test_fini(ctx, "sub", true); -} - -static void test_atomic_compare_exchange_init(test_context *ctx) -{ - _Atomic_Init_ulong(&ctx->atomic_value, 0); - ctx->normal_value = 0; -} - -static void test_atomic_compare_exchange_body(test_context *ctx, size_t worker_index) -{ - unsigned long counter = 0; - - while (!stop(ctx)) { - bool success; - - do { - unsigned long zero = 0; - - success = _Atomic_Compare_exchange_ulong( - &ctx->atomic_value, - &zero, - 1, - ATOMIC_ORDER_ACQUIRE, - ATOMIC_ORDER_RELAXED - ); - } while (!success); - - ++counter; - ++ctx->normal_value; - - _Atomic_Store_ulong(&ctx->atomic_value, 0, ATOMIC_ORDER_RELEASE); - } - - ctx->per_worker_value[worker_index] = counter; -} - -static void test_atomic_compare_exchange_fini(test_context *ctx) -{ - test_fini(ctx, "compare exchange", false); -} - -static void test_atomic_or_and_init(test_context *ctx) -{ - _Atomic_Init_ulong(&ctx->atomic_value, 0); -} - -static void test_atomic_or_and_body(test_context *ctx, size_t worker_index) -{ - unsigned long the_bit = 1UL << worker_index; - unsigned long current_bit = 0; - - while (!stop(ctx)) { - unsigned long previous; - - if (current_bit != 0) { - previous = _Atomic_Fetch_and_ulong( - &ctx->atomic_value, - ~the_bit, - ATOMIC_ORDER_RELAXED - ); - current_bit = 0; - } else { - previous = _Atomic_Fetch_or_ulong( - &ctx->atomic_value, - the_bit, - ATOMIC_ORDER_RELAXED - ); - current_bit = the_bit; - } - - rtems_test_assert((previous & the_bit) != current_bit); - } - - ctx->per_worker_value[worker_index] = current_bit; -} - -static void test_atomic_or_and_fini(test_context *ctx) -{ - test_fini(ctx, "or/and", true); -} - -static const test_case test_cases[] = { - { - test_atomic_add_init, - test_atomic_add_body, - test_atomic_add_fini - }, { - test_atomic_flag_init, - test_atomic_flag_body, - test_atomic_flag_fini - }, { - test_atomic_sub_init, - test_atomic_sub_body, - test_atomic_sub_fini - }, { - test_atomic_compare_exchange_init, - test_atomic_compare_exchange_body, - test_atomic_compare_exchange_fini - }, { - test_atomic_or_and_init, - test_atomic_or_and_body, - test_atomic_or_and_fini - }, -}; - -#define TEST_COUNT RTEMS_ARRAY_SIZE(test_cases) - -static void stop_worker_timer(rtems_id timer_id, void *arg) -{ - test_context *ctx = arg; - - _Atomic_Store_ulong(&ctx->stop, 1, ATOMIC_ORDER_RELAXED); -} - -static void start_worker_stop_timer(test_context *ctx) -{ - rtems_status_code sc; - - _Atomic_Store_ulong(&ctx->stop, 0, ATOMIC_ORDER_RELEASE); - - sc = rtems_timer_fire_after( - ctx->stop_worker_timer_id, - rtems_clock_get_ticks_per_second(), - stop_worker_timer, - ctx - ); - rtems_test_assert(sc == RTEMS_SUCCESSFUL); -} - -static void run_tests(test_context *ctx, size_t worker_index) -{ - SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER; - size_t test; - - for (test = 0; test < TEST_COUNT; ++test) { - const test_case *tc = &test_cases[test]; - - if (is_master_worker(worker_index)) { - start_worker_stop_timer(ctx); - (*tc->init)(ctx); - } - - _SMP_barrier_Wait(&ctx->barrier, &bs, ctx->worker_count); - - (*tc->body)(ctx, worker_index); - - _SMP_barrier_Wait(&ctx->barrier, &bs, ctx->worker_count); - - if (is_master_worker(worker_index)) { - (*tc->fini)(ctx); - } - } -} - -static void worker_task(size_t worker_index) -{ - test_context *ctx = &test_instance; - - run_tests(ctx, worker_index); - - (void) rtems_task_suspend(RTEMS_SELF); - rtems_test_assert(0); -} - -static void test_static_and_dynamic_initialization(void) -{ - static Atomic_Ulong static_ulong = - ATOMIC_INITIALIZER_ULONG(0xdeadbeefUL); - static Atomic_Pointer static_ptr = - ATOMIC_INITIALIZER_PTR(&static_ptr); - static Atomic_Flag static_flag = ATOMIC_INITIALIZER_FLAG; - - Atomic_Ulong stack_ulong; - Atomic_Pointer stack_ptr; - Atomic_Flag stack_flag; - - puts("=== static and dynamic initialization test case ==="); - - _Atomic_Init_ulong(&stack_ulong, 0xdeadbeefUL); - _Atomic_Init_ptr(&stack_ptr, &static_ptr); - _Atomic_Flag_clear(&stack_flag, ATOMIC_ORDER_RELAXED); - - rtems_test_assert( - memcmp(&stack_ulong, &static_ulong, sizeof(stack_ulong)) == 0 - ); - rtems_test_assert( - memcmp(&stack_ptr, &static_ptr, sizeof(stack_ptr)) == 0 - ); - rtems_test_assert( - memcmp(&stack_flag, &static_flag, sizeof(stack_flag)) == 0 - ); - - rtems_test_assert( - _Atomic_Load_ulong(&stack_ulong, ATOMIC_ORDER_RELAXED) == 0xdeadbeefUL - ); - rtems_test_assert( - _Atomic_Load_ptr(&stack_ptr, ATOMIC_ORDER_RELAXED) == &static_ptr - ); - rtems_test_assert( - !_Atomic_Flag_test_and_set(&stack_flag, ATOMIC_ORDER_RELAXED) - ); -} - -static void test(void) -{ - test_context *ctx = &test_instance; - rtems_status_code sc; - size_t worker_index; - - test_static_and_dynamic_initialization(); - - ctx->worker_count = rtems_smp_get_processor_count(); - - sc = rtems_timer_create( - rtems_build_name('S', 'T', 'O', 'P'), - &ctx->stop_worker_timer_id - ); - rtems_test_assert(sc == RTEMS_SUCCESSFUL); - - for (worker_index = 1; worker_index < ctx->worker_count; ++worker_index) { - rtems_id worker_id; - - sc = rtems_task_create( - rtems_build_name('W', 'O', 'R', 'K'), - WORKER_PRIORITY, - RTEMS_MINIMUM_STACK_SIZE, - RTEMS_DEFAULT_MODES, - RTEMS_DEFAULT_ATTRIBUTES, - &worker_id - ); - rtems_test_assert(sc == RTEMS_SUCCESSFUL); - - sc = rtems_task_start(worker_id, worker_task, worker_index); - rtems_test_assert(sc == RTEMS_SUCCESSFUL); - } - - run_tests(ctx, 0); -} - -typedef void (*simple_test_body)(test_context *ctx); - -static void test_simple_atomic_add_body(test_context *ctx) -{ - unsigned long a = 2, b = 1; - unsigned long c; - - puts("=== atomic simple add test case ==\n"); - - _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); - _Atomic_Fetch_add_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED); - c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); - rtems_test_assert(c == (a + b)); -} - -static void test_simple_atomic_sub_body(test_context *ctx) -{ - unsigned long a = 2, b = 1; - unsigned long c; - - puts("=== atomic simple sub test case ==\n"); - - _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); - _Atomic_Fetch_sub_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED); - c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); - rtems_test_assert(c == (a - b)); -} - -static void test_simple_atomic_or_body(test_context *ctx) -{ - unsigned long a = 2, b = 1; - unsigned long c; - - puts("=== atomic simple or test case ==\n"); - - _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); - _Atomic_Fetch_or_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED); - c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); - rtems_test_assert(c == (a | b)); -} - -static void test_simple_atomic_and_body(test_context *ctx) -{ - unsigned long a = 2, b = 1; - unsigned long c; - - puts("=== atomic simple and test case ==\n"); - - _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); - _Atomic_Fetch_and_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED); - c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); - rtems_test_assert(c == (a & b)); -} - -static void test_simple_atomic_exchange_body(test_context *ctx) -{ - unsigned long a = 2, b = 1; - unsigned long c; - - puts("=== atomic simple exchange test case ==\n"); - - _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); - _Atomic_Exchange_ulong(&ctx->atomic_value, b, ATOMIC_ORDER_RELAXED); - c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); - rtems_test_assert(c == b); -} - -static void test_simple_atomic_compare_exchange_body(test_context *ctx) -{ - unsigned long a = 2, b = 1; - unsigned long c; - - puts("=== atomic simple compare exchange test case ==\n"); - - _Atomic_Store_ulong(&ctx->atomic_value, a, ATOMIC_ORDER_RELAXED); - _Atomic_Compare_exchange_ulong(&ctx->atomic_value, &a, b, - ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED); - c = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED); - rtems_test_assert(c == b); -} - -static const simple_test_body simple_test_bodies[] = { - test_simple_atomic_add_body, - test_simple_atomic_sub_body, - test_simple_atomic_or_body, - test_simple_atomic_and_body, - test_simple_atomic_exchange_body, - test_simple_atomic_compare_exchange_body, -}; - -#define SIMPLE_TEST_COUNT RTEMS_ARRAY_SIZE(simple_test_bodies) - -static void simple_tests(void) -{ - test_context *ctx = &test_instance; - size_t test; - - for (test = 0; test < SIMPLE_TEST_COUNT; ++test) { - const simple_test_body *test_body = &simple_test_bodies[test]; - - (*test_body)(ctx); - } -} - -static void Init(rtems_task_argument arg) -{ - puts("\n\n*** TEST SMPATOMIC 8 ***"); - - simple_tests(); - - test(); - - puts("*** END OF TEST SMPATOMIC 8 ***"); - - 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 CPU_COUNT - -#define CONFIGURE_MAXIMUM_TIMERS 1 - -#define CONFIGURE_INIT_TASK_PRIORITY MASTER_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 diff --git a/testsuites/smptests/smpatomic08/smpatomic08.doc b/testsuites/smptests/smpatomic08/smpatomic08.doc deleted file mode 100644 index 629e43189f..0000000000 --- a/testsuites/smptests/smpatomic08/smpatomic08.doc +++ /dev/null @@ -1,12 +0,0 @@ -This file describes the directives and concepts tested by this test set. - -test set name: smpatomic08 - -directives: - - - ATOMIC_* - - _Atomic_* - -concepts: - - - Ensure that the atomic operations work. diff --git a/testsuites/smptests/smpatomic08/smpatomic08.scn b/testsuites/smptests/smpatomic08/smpatomic08.scn deleted file mode 100644 index 28d46809a0..0000000000 --- a/testsuites/smptests/smpatomic08/smpatomic08.scn +++ /dev/null @@ -1,23 +0,0 @@ -*** TEST SMPATOMIC 8 *** -=== static and dynamic initialization test case === -=== atomic add test case == -worker 0 value: 16686 -worker 1 value: 36405 -atomic value: expected = 53091, actual = 53091 -=== atomic flag test case == -worker 0 value: 5588 -worker 1 value: 16019 -atomic value: expected = 21607, actual = 21607 -=== atomic sub test case == -worker 0 value: 4294950967 -worker 1 value: 4294930886 -atomic value: expected = 4294914557, actual = 4294914557 -=== atomic compare exchange test case == -worker 0 value: 2950 -worker 1 value: 22456 -atomic value: expected = 25406, actual = 25406 -=== atomic or/and test case == -worker 0 value: 1 -worker 1 value: 0 -atomic value: expected = 1, actual = 1 -*** END OF TEST SMPATOMIC 8 *** -- cgit v1.2.3