diff --git a/base_c/include/embb/base/c/internal/atomic/and_assign.h b/base_c/include/embb/base/c/internal/atomic/and_assign.h index 534e679..86a0209 100644 --- a/base_c/include/embb/base/c/internal/atomic/and_assign.h +++ b/base_c/include/embb/base/c/internal/atomic/and_assign.h @@ -101,22 +101,23 @@ EMBB_DEFINE_AND_ASSIGN(8, "q") volatile* pointer_to_value, \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ value) { \ - register \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ - t1, t2, t3; \ + tmp, result; \ __asm__ __volatile__ ( \ "dmb\n\t" \ "loop_%=:\n\t" \ - "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %0\n\t" \ - "and %3, %2, %1\n\t" \ - "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %4, %3, %0\n\t" \ - "teq %4, #0\n\t" \ + "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%2]\n\t" \ + "and %0, %0, %3\n\t" \ + "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %0, [%2]\n\t" \ + "teq %1, #0\n\t" \ "bne loop_%=\n\t" \ "isb" \ - : "+m" (*pointer_to_value), "+r" (value), "=r" (t1), "=r" (t2), "=r" (t3) \ - : \ - : "memory", "cc" ); \ + : "=&r" (result), "=&r" (tmp) \ + : "r" (pointer_to_value), "Ir" (value) \ + : "memory", "cc" ); \ } +/* __sync_fetch_and_and(pointer_to_value, value); \ + }*/ #else #error "No atomic fetch and store implementation found" #endif diff --git a/base_c/include/embb/base/c/internal/atomic/compare_and_swap.h b/base_c/include/embb/base/c/internal/atomic/compare_and_swap.h index 41a01ba..01c4adf 100644 --- a/base_c/include/embb/base/c/internal/atomic/compare_and_swap.h +++ b/base_c/include/embb/base/c/internal/atomic/compare_and_swap.h @@ -95,29 +95,27 @@ EMBB_DEFINE_COMPARE_AND_SWAP(8, "q") EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ volatile* expected, \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) desired) { \ - register \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ - result, t1, t2; \ + oldval, res; \ + __asm__ __volatile__ ("dmb" : : : "memory"); \ + do { \ __asm__ __volatile__ ( \ - "dmb\n\t" \ - "ldr %4, %1\n\t" \ - "loop_%=:\n\t" \ - "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %3, %0\n\t" \ - "mov %2, #1\n\t" \ - "cmp %3, %4\n\t" \ - "bne fail_%=\n\t" \ - "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %5, %0\n\t" \ - "teq %2, #0\n\t" \ - "bne loop_%=\n\t" \ - "fail_%=:\n\t" \ - "str %3, %1\n\t" \ - "eor %2, %2, #1\n\t" \ - "isb" \ - : "+m" (*pointer_to_value), "+m" (*expected), \ - "=r" (result), "=r" (t1), "=r" (t2), "+r" (desired) \ - : \ - : "memory", "cc" ); \ - return result; \ + "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, [%2]\n\t" \ + "mov %0, #0\n\t" \ + "teq %1, %3\n\t" \ + "it eq\n\t" \ + "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX "eq %0, %4, [%2]\n\t" \ + : "=&r" (res), "=&r" (oldval) \ + : "r" (pointer_to_value), "Ir" (*expected), "r" (desired) \ + : "cc" ); \ + } while (res); \ + __asm__ __volatile__ ("isb" : : : "memory"); \ + if (oldval == *expected) { \ + return 1; \ + } else { \ + *expected = oldval; \ + return 0; \ + } \ } #else #error "No atomic fetch and store implementation found" diff --git a/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h b/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h index 3ea2490..b0061a4 100644 --- a/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h +++ b/base_c/include/embb/base/c/internal/atomic/fetch_and_add.h @@ -91,24 +91,25 @@ EMBB_DEFINE_FETCH_AND_ADD(8, "q") volatile* pointer_to_value, \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ new_value) { \ - register \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ - t1, t2, t3; \ + tmp, result; \ __asm__ __volatile__ ( \ "dmb\n\t" \ "loop_%=:\n\t" \ - "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %0\n\t" \ - "add %3, %2, %1\n\t" \ - "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %4, %3, %0\n\t" \ - "teq %4, #0\n\t" \ + "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%2]\n\t" \ + "add %1, %0, %3\n\t" \ + "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %1, [%2]\n\t" \ + "teq %1, #0\n\t" \ "bne loop_%=\n\t" \ - "mov %1, %2\n\t" \ "isb" \ - : "+m" (*pointer_to_value), "+r" (new_value), "=r" (t1), "=r" (t2), "=r" (t3) \ - : \ - : "memory", "cc" ); \ - return new_value; \ + : "=&r" (result), "=&r" (tmp) \ + : "r" (pointer_to_value), "r" (new_value) \ + : "memory", "cc" ); \ + return result; \ } +/* return __sync_fetch_and_add( \ + pointer_to_value, new_value); \ + }*/ #else #error "No atomic fetch and store implementation found" #endif diff --git a/base_c/include/embb/base/c/internal/atomic/load.h b/base_c/include/embb/base/c/internal/atomic/load.h index effb300..ebf4c20 100644 --- a/base_c/include/embb/base/c/internal/atomic/load.h +++ b/base_c/include/embb/base/c/internal/atomic/load.h @@ -90,17 +90,16 @@ EMBB_DEFINE_LOAD(8, "q") EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ volatile* pointer_to_value) { \ - /* no fence required for loads */ \ - register EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ + EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ result; \ __asm__ __volatile__(\ "dmb\n\t" \ - "ldr" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, %1\n\t" \ + "ldr" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%1]\n\t" \ "dmb" \ - : "=r" (result) \ - : "m" (*pointer_to_value) \ - : "memory"); \ - return result; \ + : "=&r" (result) \ + : "r" (pointer_to_value) \ + : "memory"); \ + return result; \ } #else #error "No atomic fetch and store implementation found" diff --git a/base_c/include/embb/base/c/internal/atomic/or_assign.h b/base_c/include/embb/base/c/internal/atomic/or_assign.h index 58a68f2..a1f2b12 100644 --- a/base_c/include/embb/base/c/internal/atomic/or_assign.h +++ b/base_c/include/embb/base/c/internal/atomic/or_assign.h @@ -88,20 +88,19 @@ EMBB_DEFINE_OR_ASSIGN(8, "q") EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ volatile* pointer_to_value, \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \ - register \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ - t1, t2, t3; \ + result, tmp; \ __asm__ __volatile__ ( \ "dmb\n\t" \ "loop_%=:\n\t" \ - "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %0\n\t" \ - "orr %3, %2, %1\n\t" \ - "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %4, %3, %0\n\t" \ - "teq %4, #0\n\t" \ + "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%2]\n\t" \ + "orr %0, %0, %3\n\t" \ + "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %0, [%2]\n\t" \ + "teq %1, #0\n\t" \ "bne loop_%=\n\t" \ "isb" \ - : "+m" (*pointer_to_value), "+r" (value), "=r" (t1), "=r" (t2), "=r" (t3) \ - : \ + : "=&r" (result), "=&r" (tmp) \ + : "r" (pointer_to_value), "Ir" (value) \ : "memory", "cc" ); \ } #else diff --git a/base_c/include/embb/base/c/internal/atomic/store.h b/base_c/include/embb/base/c/internal/atomic/store.h index 59724c2..060385c 100644 --- a/base_c/include/embb/base/c/internal/atomic/store.h +++ b/base_c/include/embb/base/c/internal/atomic/store.h @@ -89,11 +89,15 @@ EMBB_DEFINE_STORE(8, "q") EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) {\ __asm__ __volatile__( \ "dmb\n\t" \ - "str" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %0" \ - : "+m" (*pointer_to_value), "+r" (new_value) \ + "str" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, [%0]" \ : \ + : "r" (pointer_to_value), "r" (new_value) \ : "memory"); \ } +/* __sync_synchronize(); \ + *pointer_to_value = new_value; \ + __sync_synchronize(); \ + }*/ #else #error "No atomic fetch and store implementation found" #endif diff --git a/base_c/include/embb/base/c/internal/atomic/swap.h b/base_c/include/embb/base/c/internal/atomic/swap.h index 6476021..e0e80ed 100644 --- a/base_c/include/embb/base/c/internal/atomic/swap.h +++ b/base_c/include/embb/base/c/internal/atomic/swap.h @@ -91,23 +91,20 @@ EMBB_DEFINE_SWAP(8, "q") volatile* pointer_to_value, \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value)\ { \ - register \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ - t1, t2; \ + tmp, result; \ __asm__ __volatile__ ( \ "dmb\n\t" \ "loop_%=:\n\t" \ - "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %0\n\t" \ - "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %3, %1, %0\n\t" \ - "teq %3, #0\n\t" \ + "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%3]\n\t" \ + "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %2, [%3]\n\t" \ + "teq %1, #0\n\t" \ "bne loop_%=\n\t" \ - "mov %1, %2\n\t" \ "isb" \ - : "+m" (*pointer_to_value), \ - "+r" (new_value), "=r" (t1), "=r" (t2) \ - : \ + : "=&r" (result), "=&r" (tmp) \ + : "r" (new_value), "r" (pointer_to_value) \ : "memory", "cc" ); \ - return new_value; \ + return result; \ } #else #error "No atomic fetch and store implementation found" diff --git a/base_c/include/embb/base/c/internal/atomic/xor_assign.h b/base_c/include/embb/base/c/internal/atomic/xor_assign.h index c5a00bd..3e2b908 100644 --- a/base_c/include/embb/base/c/internal/atomic/xor_assign.h +++ b/base_c/include/embb/base/c/internal/atomic/xor_assign.h @@ -89,21 +89,20 @@ EMBB_DEFINE_XOR_ASSIGN(8, "q") EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ volatile* pointer_to_value, \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) value) { \ - register \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ - t1, t2, t3; \ + result, tmp; \ __asm__ __volatile__ ( \ "dmb\n\t" \ "loop_%=:\n\t" \ - "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %0\n\t" \ - "eor %3, %2, %1\n\t" \ - "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %4, %3, %0\n\t" \ - "teq %4, #0\n\t" \ + "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%2]\n\t" \ + "eor %0, %0, %3\n\t" \ + "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %0, [%2]\n\t" \ + "teq %1, #0\n\t" \ "bne loop_%=\n\t" \ "isb" \ - : "+m" (*pointer_to_value), "+r" (value), "=r" (t1), "=r" (t2), "=r" (t3) \ - : \ - : "memory", "cc" ); \ + : "=&r" (result), "=&r" (tmp) \ + : "r" (pointer_to_value), "Ir" (value) \ + : "memory", "cc" ); \ } #else #error "No atomic or assign implementation found" diff --git a/base_cpp/test/atomic_test.cc b/base_cpp/test/atomic_test.cc index fc0445a..156dca4 100644 --- a/base_cpp/test/atomic_test.cc +++ b/base_cpp/test/atomic_test.cc @@ -284,14 +284,14 @@ AtomicTest::AtomicTest() { typedef enum { RED, GREEN, BLUE } colors_t; void AtomicTest::BasicTests() { - //embb::base::Atomic b; // Boolean + embb::base::Atomic b; // Boolean embb::base::Atomic c; // Enumeration embb::base::Atomic v; // Void pointer embb::base::Atomic i; // Integer embb::base::Atomic n; // Non-void pointer //template specializations - //PT_EXPECT(!b.IsArithmetic() && !b.IsInteger() && !b.IsPointer()); + PT_EXPECT(!b.IsArithmetic() && !b.IsInteger() && !b.IsPointer()); PT_EXPECT(!c.IsArithmetic() && !c.IsInteger() && !c.IsPointer()); PT_EXPECT(!v.IsArithmetic() && !v.IsInteger() && !v.IsPointer()); PT_EXPECT(i.IsArithmetic() && i.IsInteger() && !i.IsPointer());