diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-03-03 09:09:24 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-03-06 09:43:58 +0100 |
commit | 8b50a55001ec46f1cb2cfd096cec1df78ab68465 (patch) | |
tree | ed68c824f05263065068b76fb2fe4251b0bcb3de | |
parent | libnetworking: Typo (diff) | |
download | rtems-8b50a55001ec46f1cb2cfd096cec1df78ab68465.tar.bz2 |
score: Add _Atomic_Fence()
-rw-r--r-- | cpukit/score/include/rtems/score/atomic.h | 7 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/cpustdatomic.h | 7 | ||||
-rw-r--r-- | testsuites/smptests/smpatomic01/init.c | 63 | ||||
-rw-r--r-- | testsuites/smptests/smpatomic01/smpatomic01.scn | 26 |
4 files changed, 84 insertions, 19 deletions
diff --git a/cpukit/score/include/rtems/score/atomic.h b/cpukit/score/include/rtems/score/atomic.h index 757eaf70a5..81149ab1a4 100644 --- a/cpukit/score/include/rtems/score/atomic.h +++ b/cpukit/score/include/rtems/score/atomic.h @@ -43,6 +43,13 @@ extern "C" { */ #define ATOMIC_INITIALIZER_FLAG CPU_ATOMIC_INITIALIZER_FLAG +static inline void _Atomic_Fence( + Atomic_Order order +) +{ + _CPU_atomic_Fence( order ); +} + /** * @brief Initializes an atomic type value into a atomic object. * diff --git a/cpukit/score/include/rtems/score/cpustdatomic.h b/cpukit/score/include/rtems/score/cpustdatomic.h index e364eb945e..4023d0cbea 100644 --- a/cpukit/score/include/rtems/score/cpustdatomic.h +++ b/cpukit/score/include/rtems/score/cpustdatomic.h @@ -83,6 +83,13 @@ typedef enum { #define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT +static inline void _CPU_atomic_Fence( + Atomic_Order order +) +{ + atomic_thread_fence( (memory_order) order ); +} + /** * @brief Initializes an atomic type value into a atomic object. * diff --git a/testsuites/smptests/smpatomic01/init.c b/testsuites/smptests/smpatomic01/init.c index 792a17bfaf..8e05307002 100644 --- a/testsuites/smptests/smpatomic01/init.c +++ b/testsuites/smptests/smpatomic01/init.c @@ -21,6 +21,7 @@ #include <rtems/score/atomic.h> #include <rtems/score/smpbarrier.h> #include <rtems.h> +#include <limits.h> #include <string.h> #include "tmacros.h" @@ -40,6 +41,8 @@ typedef struct { Atomic_Ulong atomic_value; unsigned long per_worker_value[CPU_COUNT]; unsigned long normal_value; + char unused_space_for_cache_line_separation[128]; + unsigned long second_value; Atomic_Flag global_flag; } test_context; @@ -74,7 +77,7 @@ static void test_fini( unsigned long actual_value; size_t worker_index; - printf("=== atomic %s test case ==\n", test); + 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]; @@ -255,6 +258,48 @@ static void test_atomic_or_and_fini(test_context *ctx) test_fini(ctx, "or/and", true); } +static void test_atomic_fence_init(test_context *ctx) +{ + ctx->normal_value = 0; + ctx->second_value = 0; + _Atomic_Fence(ATOMIC_ORDER_RELEASE); +} + +static void test_atomic_fence_body(test_context *ctx, size_t worker_index) +{ + if (is_master_worker(worker_index)) { + unsigned long counter = 0; + + while (!stop(ctx)) { + ++counter; + ctx->normal_value = counter; + _Atomic_Fence(ATOMIC_ORDER_RELEASE); + ctx->second_value = counter; + } + } else { + while (!stop(ctx)) { + unsigned long n; + unsigned long s; + + s = ctx->second_value; + _Atomic_Fence(ATOMIC_ORDER_ACQUIRE); + n = ctx->normal_value; + + rtems_test_assert(n - s < LONG_MAX); + } + } +} + +static void test_atomic_fence_fini(test_context *ctx) +{ + printf( + "=== atomic fence test case ===\n" + "normal value = %lu, second value = %lu\n", + ctx->normal_value, + ctx->second_value + ); +} + static const test_case test_cases[] = { { test_atomic_add_init, @@ -276,6 +321,10 @@ static const test_case test_cases[] = { test_atomic_or_and_init, test_atomic_or_and_body, test_atomic_or_and_fini + }, { + test_atomic_fence_init, + test_atomic_fence_body, + test_atomic_fence_fini }, }; @@ -432,7 +481,7 @@ 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"); + puts("=== atomic simple add test case ===\n"); _Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED); _Atomic_Fetch_add_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED); @@ -452,7 +501,7 @@ 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"); + puts("=== atomic simple sub test case ===\n"); _Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED); _Atomic_Fetch_sub_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED); @@ -472,7 +521,7 @@ 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"); + puts("=== atomic simple or test case ===\n"); _Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED); _Atomic_Fetch_or_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED); @@ -492,7 +541,7 @@ 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"); + puts("=== atomic simple and test case ===\n"); _Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED); _Atomic_Fetch_and_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED); @@ -512,7 +561,7 @@ 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"); + puts("=== atomic simple exchange test case ===\n"); _Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED); _Atomic_Exchange_uint(&ctx->atomic_int_value, ib, ATOMIC_ORDER_RELAXED); @@ -532,7 +581,7 @@ 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"); + puts("=== atomic simple compare exchange test case ===\n"); _Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED); _Atomic_Compare_exchange_uint(&ctx->atomic_int_value, &ia, ib, diff --git a/testsuites/smptests/smpatomic01/smpatomic01.scn b/testsuites/smptests/smpatomic01/smpatomic01.scn index 1122fae722..4a8c230f8d 100644 --- a/testsuites/smptests/smpatomic01/smpatomic01.scn +++ b/testsuites/smptests/smpatomic01/smpatomic01.scn @@ -1,29 +1,31 @@ *** 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 == +=== 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 == +=== atomic flag test case === worker 0 value: 5588 worker 1 value: 16019 atomic value: expected = 21607, actual = 21607 -=== atomic sub test case == +=== atomic sub test case === worker 0 value: 4294950967 worker 1 value: 4294930886 atomic value: expected = 4294914557, actual = 4294914557 -=== atomic compare exchange test case == +=== atomic compare exchange test case === worker 0 value: 2950 worker 1 value: 22456 atomic value: expected = 25406, actual = 25406 -=== atomic or/and test case == +=== atomic or/and test case === worker 0 value: 1 worker 1 value: 0 atomic value: expected = 1, actual = 1 +=== atomic fence test case === +normal value = 10759507, second value = 10759507 *** END OF TEST SMPATOMIC 1 *** |