Commit c8ca25f2 by Marcus Winter

base: fixed atomic implementation for arm

parent cd283998
......@@ -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) \
: \
: "=&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
......
......@@ -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"
......
......@@ -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) \
: \
: "=&r" (result), "=&r" (tmp) \
: "r" (pointer_to_value), "r" (new_value) \
: "memory", "cc" ); \
return new_value; \
return result; \
}
/* return __sync_fetch_and_add( \
pointer_to_value, new_value); \
}*/
#else
#error "No atomic fetch and store implementation found"
#endif
......
......@@ -90,15 +90,14 @@ 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) \
: "=&r" (result) \
: "r" (pointer_to_value) \
: "memory"); \
return result; \
}
......
......@@ -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
......
......@@ -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
......
......@@ -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"
......
......@@ -89,20 +89,19 @@ 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) \
: \
: "=&r" (result), "=&r" (tmp) \
: "r" (pointer_to_value), "Ir" (value) \
: "memory", "cc" ); \
}
#else
......
......@@ -284,14 +284,14 @@ AtomicTest::AtomicTest() {
typedef enum { RED, GREEN, BLUE } colors_t;
void AtomicTest::BasicTests() {
//embb::base::Atomic<bool> b; // Boolean
embb::base::Atomic<bool> b; // Boolean
embb::base::Atomic<colors_t> c; // Enumeration
embb::base::Atomic<void*> v; // Void pointer
embb::base::Atomic<int> i; // Integer
embb::base::Atomic<int*> 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());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment