Commit 19db52cd by Tobias Schuele

Merge branch 'development' of https://github.com/siemens/embb into development

parents 334832ca c8ca25f2
...@@ -101,22 +101,23 @@ EMBB_DEFINE_AND_ASSIGN(8, "q") ...@@ -101,22 +101,23 @@ EMBB_DEFINE_AND_ASSIGN(8, "q")
volatile* pointer_to_value, \ volatile* pointer_to_value, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
value) { \ value) { \
register \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
t1, t2, t3; \ tmp, result; \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"dmb\n\t" \ "dmb\n\t" \
"loop_%=:\n\t" \ "loop_%=:\n\t" \
"ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %0\n\t" \ "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%2]\n\t" \
"and %3, %2, %1\n\t" \ "and %0, %0, %3\n\t" \
"strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %4, %3, %0\n\t" \ "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %0, [%2]\n\t" \
"teq %4, #0\n\t" \ "teq %1, #0\n\t" \
"bne loop_%=\n\t" \ "bne loop_%=\n\t" \
"isb" \ "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" ); \ : "memory", "cc" ); \
} }
/* __sync_fetch_and_and(pointer_to_value, value); \
}*/
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
#endif #endif
......
...@@ -95,29 +95,27 @@ EMBB_DEFINE_COMPARE_AND_SWAP(8, "q") ...@@ -95,29 +95,27 @@ EMBB_DEFINE_COMPARE_AND_SWAP(8, "q")
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
volatile* expected, \ volatile* expected, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) desired) { \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) desired) { \
register \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
result, t1, t2; \ oldval, res; \
__asm__ __volatile__ ("dmb" : : : "memory"); \
do { \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"dmb\n\t" \ "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, [%2]\n\t" \
"ldr %4, %1\n\t" \ "mov %0, #0\n\t" \
"loop_%=:\n\t" \ "teq %1, %3\n\t" \
"ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %3, %0\n\t" \ "it eq\n\t" \
"mov %2, #1\n\t" \ "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX "eq %0, %4, [%2]\n\t" \
"cmp %3, %4\n\t" \ : "=&r" (res), "=&r" (oldval) \
"bne fail_%=\n\t" \ : "r" (pointer_to_value), "Ir" (*expected), "r" (desired) \
"strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %5, %0\n\t" \ : "cc" ); \
"teq %2, #0\n\t" \ } while (res); \
"bne loop_%=\n\t" \ __asm__ __volatile__ ("isb" : : : "memory"); \
"fail_%=:\n\t" \ if (oldval == *expected) { \
"str %3, %1\n\t" \ return 1; \
"eor %2, %2, #1\n\t" \ } else { \
"isb" \ *expected = oldval; \
: "+m" (*pointer_to_value), "+m" (*expected), \ return 0; \
"=r" (result), "=r" (t1), "=r" (t2), "+r" (desired) \ } \
: \
: "memory", "cc" ); \
return result; \
} }
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
......
...@@ -91,24 +91,25 @@ EMBB_DEFINE_FETCH_AND_ADD(8, "q") ...@@ -91,24 +91,25 @@ EMBB_DEFINE_FETCH_AND_ADD(8, "q")
volatile* pointer_to_value, \ volatile* pointer_to_value, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
new_value) { \ new_value) { \
register \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
t1, t2, t3; \ tmp, result; \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"dmb\n\t" \ "dmb\n\t" \
"loop_%=:\n\t" \ "loop_%=:\n\t" \
"ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %0\n\t" \ "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%2]\n\t" \
"add %3, %2, %1\n\t" \ "add %1, %0, %3\n\t" \
"strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %4, %3, %0\n\t" \ "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %1, [%2]\n\t" \
"teq %4, #0\n\t" \ "teq %1, #0\n\t" \
"bne loop_%=\n\t" \ "bne loop_%=\n\t" \
"mov %1, %2\n\t" \
"isb" \ "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" ); \ : "memory", "cc" ); \
return new_value; \ return result; \
} }
/* return __sync_fetch_and_add( \
pointer_to_value, new_value); \
}*/
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
#endif #endif
......
...@@ -90,17 +90,16 @@ EMBB_DEFINE_LOAD(8, "q") ...@@ -90,17 +90,16 @@ EMBB_DEFINE_LOAD(8, "q")
EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(\ EMBB_CAT2(embb_internal__atomic_load_, EMBB_PARAMETER_SIZE_BYTE)(\
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
volatile* pointer_to_value) { \ volatile* pointer_to_value) { \
/* no fence required for loads */ \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
register EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
result; \ result; \
__asm__ __volatile__(\ __asm__ __volatile__(\
"dmb\n\t" \ "dmb\n\t" \
"ldr" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, %1\n\t" \ "ldr" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%1]\n\t" \
"dmb" \ "dmb" \
: "=r" (result) \ : "=&r" (result) \
: "m" (*pointer_to_value) \ : "r" (pointer_to_value) \
: "memory"); \ : "memory"); \
return result; \ return result; \
} }
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
......
...@@ -88,20 +88,19 @@ EMBB_DEFINE_OR_ASSIGN(8, "q") ...@@ -88,20 +88,19 @@ EMBB_DEFINE_OR_ASSIGN(8, "q")
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
volatile* pointer_to_value, \ volatile* pointer_to_value, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) 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) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
t1, t2, t3; \ result, tmp; \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"dmb\n\t" \ "dmb\n\t" \
"loop_%=:\n\t" \ "loop_%=:\n\t" \
"ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %0\n\t" \ "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%2]\n\t" \
"orr %3, %2, %1\n\t" \ "orr %0, %0, %3\n\t" \
"strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %4, %3, %0\n\t" \ "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %0, [%2]\n\t" \
"teq %4, #0\n\t" \ "teq %1, #0\n\t" \
"bne loop_%=\n\t" \ "bne loop_%=\n\t" \
"isb" \ "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" ); \ : "memory", "cc" ); \
} }
#else #else
......
...@@ -89,11 +89,15 @@ EMBB_DEFINE_STORE(8, "q") ...@@ -89,11 +89,15 @@ EMBB_DEFINE_STORE(8, "q")
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) {\ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) {\
__asm__ __volatile__( \ __asm__ __volatile__( \
"dmb\n\t" \ "dmb\n\t" \
"str" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %0" \ "str" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, [%0]" \
: "+m" (*pointer_to_value), "+r" (new_value) \
: \ : \
: "r" (pointer_to_value), "r" (new_value) \
: "memory"); \ : "memory"); \
} }
/* __sync_synchronize(); \
*pointer_to_value = new_value; \
__sync_synchronize(); \
}*/
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
#endif #endif
......
...@@ -91,23 +91,20 @@ EMBB_DEFINE_SWAP(8, "q") ...@@ -91,23 +91,20 @@ EMBB_DEFINE_SWAP(8, "q")
volatile* pointer_to_value, \ volatile* pointer_to_value, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_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) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
t1, t2; \ tmp, result; \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"dmb\n\t" \ "dmb\n\t" \
"loop_%=:\n\t" \ "loop_%=:\n\t" \
"ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %0\n\t" \ "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%3]\n\t" \
"strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %3, %1, %0\n\t" \ "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %2, [%3]\n\t" \
"teq %3, #0\n\t" \ "teq %1, #0\n\t" \
"bne loop_%=\n\t" \ "bne loop_%=\n\t" \
"mov %1, %2\n\t" \
"isb" \ "isb" \
: "+m" (*pointer_to_value), \ : "=&r" (result), "=&r" (tmp) \
"+r" (new_value), "=r" (t1), "=r" (t2) \ : "r" (new_value), "r" (pointer_to_value) \
: \
: "memory", "cc" ); \ : "memory", "cc" ); \
return new_value; \ return result; \
} }
#else #else
#error "No atomic fetch and store implementation found" #error "No atomic fetch and store implementation found"
......
...@@ -89,21 +89,20 @@ EMBB_DEFINE_XOR_ASSIGN(8, "q") ...@@ -89,21 +89,20 @@ EMBB_DEFINE_XOR_ASSIGN(8, "q")
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
volatile* pointer_to_value, \ volatile* pointer_to_value, \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) 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) \ EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
t1, t2, t3; \ result, tmp; \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"dmb\n\t" \ "dmb\n\t" \
"loop_%=:\n\t" \ "loop_%=:\n\t" \
"ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %2, %0\n\t" \ "ldrex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %0, [%2]\n\t" \
"eor %3, %2, %1\n\t" \ "eor %0, %0, %3\n\t" \
"strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %4, %3, %0\n\t" \ "strex" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, %0, [%2]\n\t" \
"teq %4, #0\n\t" \ "teq %1, #0\n\t" \
"bne loop_%=\n\t" \ "bne loop_%=\n\t" \
"isb" \ "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" ); \ : "memory", "cc" ); \
} }
#else #else
#error "No atomic or assign implementation found" #error "No atomic or assign implementation found"
......
...@@ -284,14 +284,14 @@ AtomicTest::AtomicTest() { ...@@ -284,14 +284,14 @@ AtomicTest::AtomicTest() {
typedef enum { RED, GREEN, BLUE } colors_t; typedef enum { RED, GREEN, BLUE } colors_t;
void AtomicTest::BasicTests() { 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<colors_t> c; // Enumeration
embb::base::Atomic<void*> v; // Void pointer embb::base::Atomic<void*> v; // Void pointer
embb::base::Atomic<int> i; // Integer embb::base::Atomic<int> i; // Integer
embb::base::Atomic<int*> n; // Non-void pointer embb::base::Atomic<int*> n; // Non-void pointer
//template specializations //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(!c.IsArithmetic() && !c.IsInteger() && !c.IsPointer());
PT_EXPECT(!v.IsArithmetic() && !v.IsInteger() && !v.IsPointer()); PT_EXPECT(!v.IsArithmetic() && !v.IsInteger() && !v.IsPointer());
PT_EXPECT(i.IsArithmetic() && i.IsInteger() && !i.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