[U-Boot] [PATCH v4 01/11] arm: add atomic functions with return support
Antoine Tenart
antoine.tenart at free-electrons.com
Sun Apr 30 13:29:46 UTC 2017
Implement three atomic functions to allow making an atomic operation
that returns the value. Adds: atomic_add_return(), atomic_sub_return(),
atomic_inc_return() and atomic_dec_return().
This is heavily based on the Linux implementation of such functions for
ARM.
Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
Cc: Albert Aribaud <albert.u.boot at aribaud.net>
Cc: Mark Rutland <mark.rutland at arm.com>
---
arch/arm/include/asm/atomic.h | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
index 171f4d979281..4bfe62afaca1 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
@@ -73,6 +73,42 @@ static inline void atomic_dec(volatile atomic_t *v)
local_irq_restore(flags);
}
+#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
+static inline int atomic_##op##_return(int i, volatile atomic_t *v) \
+{ \
+ unsigned long tmp; \
+ int result; \
+ \
+ /* prefetch */ \
+ __asm__ __volatile__("pld\t%a0" \
+ :: "p" (&v->counter)); \
+ \
+ __asm__ __volatile__("@ atomic_" #op "_return\n" \
+"1: ldrex %0, [%3]\n" \
+" " #asm_op " %0, %0, %4\n" \
+" strex %1, %0, [%3]\n" \
+" teq %1, #0\n" \
+" bne 1b" \
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
+ : "r" (&v->counter), "Ir" (i) \
+ : "cc"); \
+ \
+ return result; \
+}
+
+ATOMIC_OP_RETURN(add, +=, add)
+ATOMIC_OP_RETURN(sub, -=, sub)
+
+static inline int atomic_inc_return(volatile atomic_t *v)
+{
+ return atomic_add_return(1, v);
+}
+
+static inline int atomic_dec_return(volatile atomic_t *v)
+{
+ return atomic_sub_return(1, v);
+}
+
static inline int atomic_dec_and_test(volatile atomic_t *v)
{
unsigned long flags = 0;
--
2.11.0
More information about the U-Boot
mailing list