From b7012c88f623e83d4bb31d62c73c0a1ea4fd9b4f Mon Sep 17 00:00:00 2001 From: Michael Schmid Date: Thu, 2 Mar 2017 11:13:20 +0100 Subject: [PATCH] implementation of compare and swap --- base_c/include/embb/base/c/internal/atomic/compare_and_swap.h | 28 +++++++++++----------------- base_c/include/embb/base/c/internal/atomic/fetch_and_add.h | 7 +++---- 2 files changed, 14 insertions(+), 21 deletions(-) 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 bc620b5..065b08f 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 @@ -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" 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 086fc75..5bab66e 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 @@ -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" ); \ -- libgit2 0.26.0