arm/ck_pr: Make sure 64bits load/store are atomic.

Depending on the CPU implementation, ldrd/strd may or may not be atomic.
Use ldrexd/strexd instead.
ck_pring
Olivier Houchard 10 years ago
parent c7adff20ba
commit 421d4d1901

@ -132,9 +132,10 @@ CK_PR_LOAD_S(char, char, "ldrb")
CK_CC_INLINE static uint64_t CK_CC_INLINE static uint64_t
ck_pr_load_64(const uint64_t *target) ck_pr_load_64(const uint64_t *target)
{ {
register uint64_t ret asm("r0"); register uint64_t ret;
__asm __volatile("ldrd %0, [%1]" : "+r" (ret) __asm __volatile("ldrexd %0, [%1]"
: "=&r" (ret)
: "r" (target) : "r" (target)
: "memory", "cc"); : "memory", "cc");
return (ret); return (ret);
@ -170,10 +171,16 @@ CK_PR_STORE_S(char, char, "strb")
CK_CC_INLINE static void CK_CC_INLINE static void
ck_pr_store_64(const uint64_t *target, uint64_t value) ck_pr_store_64(const uint64_t *target, uint64_t value)
{ {
uint64_t tmp;
__asm __volatile("strd %0, [%1]" uint32_t flag;
: __asm __volatile("1: \n"
: "r" (value), "r" (target) "ldrexd %0, [%2]\n"
"strexd %1, %3, [%2]\n"
"teq %1, #0\n"
"it ne \n"
"bne 1\n"
: "=&r" (tmp), "=&r" (flag)
: "r" (target), "r" (value)
: "memory", "cc"); : "memory", "cc");
} }

Loading…
Cancel
Save