Commit b7012c88 by Michael Schmid

implementation of compare and swap

parent 8f69064b
......@@ -132,23 +132,17 @@ EMBB_DEFINE_COMPARE_AND_SWAP(4, "")
EMBB_PLATFORM_INLINE int EMBB_CAT2(embb_internal__atomic_compare_and_swap_, \
EMBB_PARAMETER_SIZE_BYTE)(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) 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) result = 0; \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) oldval = 0; \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) exp_val = 0; \
__asm__ __volatile__ ("dsync\n\t" \
"ld" EMBB_ATOMIC_TC_SIZE_SUFFIX " %[oldval], %[pointer_to_value]\n\t" \
"ld" EMBB_ATOMIC_TC_SIZE_SUFFIX " %[exp_val], %[expected]\n\t" \
"eq %%d15, %[exp_val], %[oldval]\n\t" \
"cmov %[oldval], %%d15, %[desired]\n\t" \
"cmovn %[exp_val], %%d15, %[oldval]\n\t" \
"mov %[result], %%d15\n\t" \
"st" EMBB_ATOMIC_TC_SIZE_SUFFIX " %[pointer_to_value], %[oldval]\n\t" \
"st" EMBB_ATOMIC_TC_SIZE_SUFFIX " %[expected], %[exp_val]\n\t" \
"dsync\n\t" \
: [result]"+d" (result), [expected]"+m" (*expected), [exp_val]"+d" (exp_val),[oldval]"+d" (oldval), [pointer_to_value]"+m"(*pointer_to_value)\
: [desired]"d" (desired) \
: "%d15", "memory", "cc"); \
return result; \
register /*__extension__ */ uint64_t e_reg = ((uint64_t)*expected << 32U) | desired; \
__asm__ __volatile__ ("cmpswap" EMBB_ATOMIC_TC_SIZE_SUFFIX " [%1]0, %A0\n\t" \
: "+d"(e_reg) \
: "a"(pointer_to_value) \
: "memory"); \
__asm__ __volatile__ ("dsync" : : : "memory"); \
if(*pointer_to_value == desired) { \
return 1; \
} else { \
return 0; \
} \
}
#else
#error "No atomic fetch and store implementation found"
......
......@@ -120,16 +120,15 @@ EMBB_DEFINE_FETCH_AND_ADD(4, "")
#elif defined(EMBB_PLATFORM_ARCH_TC)
#if defined(EMBB_PLATFORM_COMPILER_GNUC)
#define EMBB_DEFINE_FETCH_AND_ADD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX) \
#define EMBB_DEFINE_FETCH_AND_ADD(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_TC_SIZE_SUFFIX) \
EMBB_PLATFORM_INLINE EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) EMBB_CAT2(embb_internal__atomic_fetch_and_add_, EMBB_PARAMETER_SIZE_BYTE) \
(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) new_value) { \
EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) \
result=0,tmp1=0; \
__asm__ __volatile__ ("dsync\n\t" \
"ld" EMBB_ATOMIC_X86_SIZE_SUFFIX " %[result], %[pointer_to_value]\n\t" \
"ld" EMBB_ATOMIC_TC_SIZE_SUFFIX " %[result], %[pointer_to_value]\n\t" \
"add %[tmp1],%[new_value], %[result]\n\t" \
"st" EMBB_ATOMIC_X86_SIZE_SUFFIX " %[pointer_to_value], %[tmp1]\n\t" \
"dsync\n\t" \
"st" EMBB_ATOMIC_TC_SIZE_SUFFIX " %[pointer_to_value], %[tmp1]\n\t" \
: [result] "+d" (result), [tmp1]"+d" (tmp1), [pointer_to_value]"+m" (*pointer_to_value) \
: [new_value]"d" (new_value) \
: "memory", "cc" ); \
......
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