[rtems commit] score: Fix atomic compare exchange

Sebastian Huber sebh at rtems.org
Fri Sep 25 19:51:21 UTC 2015


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Sep 25 21:31:00 2015 +0200

score: Fix atomic compare exchange

---

 cpukit/score/cpu/sparc/sparcv8-atomic.c         |  8 ++-
 cpukit/score/include/rtems/score/cpustdatomic.h | 18 +++++--
 testsuites/sptests/spatomic01/init.c            | 65 +++++++++++++++++++------
 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 b1c4f23..2b3bdbc 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 2696e3a..c66dd7e 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 fbfd071..b90ffd0 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[] = {




More information about the vc mailing list