summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-09-25 21:31:00 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-09-25 21:48:24 +0200
commit1f7c5c88ca384baa312a0714c6e93174605418a7 (patch)
treefeeef5efadbbc839a35f8f8d0d393c43578d1ad6
parentARMv7M: Improve exception handler routine and add comments on SP selection (diff)
downloadrtems-1f7c5c88ca384baa312a0714c6e93174605418a7.tar.bz2
score: Fix atomic compare exchange
-rw-r--r--cpukit/score/cpu/sparc/sparcv8-atomic.c8
-rw-r--r--cpukit/score/include/rtems/score/cpustdatomic.h18
-rw-r--r--testsuites/sptests/spatomic01/init.c65
3 files changed, 70 insertions, 21 deletions
diff --git a/cpukit/score/cpu/sparc/sparcv8-atomic.c b/cpukit/score/cpu/sparc/sparcv8-atomic.c
index b1c4f23c88..2b3bdbc451 100644
--- a/cpukit/score/cpu/sparc/sparcv8-atomic.c
+++ b/cpukit/score/cpu/sparc/sparcv8-atomic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2014-2015 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -118,12 +118,16 @@ bool __atomic_compare_exchange_4(
{
bool equal;
ISR_Level level;
+ uint32_t actual;
level = _SPARCV8_Acquire_the_one_lock();
- equal = *mem == *expected;
+ actual = *mem;
+ equal = ( actual == *expected );
if ( equal ) {
*mem = desired;
+ } else {
+ *expected = actual;
}
_SPARCV8_Release_the_one_lock( level );
diff --git a/cpukit/score/include/rtems/score/cpustdatomic.h b/cpukit/score/include/rtems/score/cpustdatomic.h
index 2696e3afbc..c66dd7eb34 100644
--- a/cpukit/score/include/rtems/score/cpustdatomic.h
+++ b/cpukit/score/include/rtems/score/cpustdatomic.h
@@ -577,13 +577,17 @@ static inline bool _CPU_atomic_Compare_exchange_uint( CPU_atomic_Uint *obj, unsi
#else
bool success;
ISR_Level level;
+ unsigned int actual;
(void) succ;
(void) fail;
_ISR_Disable( level );
- success = *obj == *expected;
+ actual = *obj;
+ success = ( actual == *expected );
if ( success ) {
*obj = desired;
+ } else {
+ *expected = actual;
}
_ISR_Enable( level );
@@ -600,13 +604,17 @@ static inline bool _CPU_atomic_Compare_exchange_ulong( CPU_atomic_Ulong *obj, un
#else
bool success;
ISR_Level level;
+ unsigned long actual;
(void) succ;
(void) fail;
_ISR_Disable( level );
- success = *obj == *expected;
+ actual = *obj;
+ success = ( actual == *expected );
if ( success ) {
*obj = desired;
+ } else {
+ *expected = actual;
}
_ISR_Enable( level );
@@ -623,13 +631,17 @@ static inline bool _CPU_atomic_Compare_exchange_ptr( CPU_atomic_Pointer *obj, vo
#else
bool success;
ISR_Level level;
+ uintptr_t actual;
(void) succ;
(void) fail;
_ISR_Disable( level );
- success = *obj == (uintptr_t) *expected;
+ actual = *obj;
+ success = ( actual == (uintptr_t) *expected );
if ( success ) {
*obj = (uintptr_t) desired;
+ } else {
+ *expected = (void *) actual;
}
_ISR_Enable( level );
diff --git a/testsuites/sptests/spatomic01/init.c b/testsuites/sptests/spatomic01/init.c
index fbfd071832..b90ffd05f5 100644
--- a/testsuites/sptests/spatomic01/init.c
+++ b/testsuites/sptests/spatomic01/init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2013-2015 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -189,24 +189,57 @@ static void test_simple_atomic_exchange_body(test_context *ctx)
static void test_simple_atomic_compare_exchange_body(test_context *ctx)
{
- unsigned int ia = 8, ib = 4;
- unsigned int ic;
- unsigned long a = 2, b = 1;
- unsigned long c;
+ unsigned int ei;
+ unsigned int vi;
+ unsigned long el;
+ unsigned long vl;
+ bool success;
puts("=== atomic simple compare exchange test case ===");
- _Atomic_Store_uint(&ctx->atomic_int_value, ia, ATOMIC_ORDER_RELAXED);
- _Atomic_Compare_exchange_uint(&ctx->atomic_int_value, &ia, ib,
- ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED);
- ic = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
- rtems_test_assert(ic == ib);
-
- _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);
+ _Atomic_Store_uint(&ctx->atomic_int_value, 1, ATOMIC_ORDER_RELAXED);
+ ei = 2;
+ success = _Atomic_Compare_exchange_uint(
+ &ctx->atomic_int_value,
+ &ei,
+ 3,
+ ATOMIC_ORDER_RELAXED,
+ ATOMIC_ORDER_RELAXED
+ );
+ rtems_test_assert(!success);
+ rtems_test_assert(ei == 1);
+ success = _Atomic_Compare_exchange_uint(
+ &ctx->atomic_int_value,
+ &ei,
+ 3,
+ ATOMIC_ORDER_RELAXED,
+ ATOMIC_ORDER_RELAXED
+ );
+ rtems_test_assert(success);
+ vi = _Atomic_Load_uint(&ctx->atomic_int_value, ATOMIC_ORDER_RELAXED);
+ rtems_test_assert(vi == 3);
+
+ _Atomic_Store_ulong(&ctx->atomic_value, 10, ATOMIC_ORDER_RELAXED);
+ el = 11;
+ success = _Atomic_Compare_exchange_ulong(
+ &ctx->atomic_value,
+ &el,
+ 12,
+ ATOMIC_ORDER_RELAXED,
+ ATOMIC_ORDER_RELAXED
+ );
+ rtems_test_assert(!success);
+ rtems_test_assert(el == 10);
+ success = _Atomic_Compare_exchange_ulong(
+ &ctx->atomic_value,
+ &el,
+ 12,
+ ATOMIC_ORDER_RELAXED,
+ ATOMIC_ORDER_RELAXED
+ );
+ rtems_test_assert(success);
+ vl = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
+ rtems_test_assert(vl == 12);
}
static const simple_test_body simple_test_bodies[] = {