Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1410117
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH -v2 02/33] locking,arc: Implement atomic_fetch_{add,sub,and,andnot,or,xor}() |
| Date | 2016-05-31 12:40 +0200 |
| Message-ID | <rEPfB-1vx-89@gated-at.bofh.it> (permalink) |
| References | <rEPfz-1vx-3@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
Implement FETCH-OP atomic primitives, these are very similar to the
existing OP-RETURN primitives we already have, except they return the
value of the atomic variable _before_ modification.
This is especially useful for irreversible operations -- such as
bitops (because it becomes impossible to reconstruct the state prior
to modification).
Acked-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
arch/arc/include/asm/atomic.h | 103 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 94 insertions(+), 9 deletions(-)
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -104,6 +104,37 @@ static inline int atomic_##op##_return(i
return val; \
}
+#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
+static inline int atomic_fetch_##op(int i, atomic_t *v) \
+{ \
+ unsigned int val, orig; \
+ SCOND_FAIL_RETRY_VAR_DEF \
+ \
+ /* \
+ * Explicit full memory barrier needed before/after as \
+ * LLOCK/SCOND thmeselves don't provide any such semantics \
+ */ \
+ smp_mb(); \
+ \
+ __asm__ __volatile__( \
+ "1: llock %[orig], [%[ctr]] \n" \
+ " " #asm_op " %[val], %[orig], %[i] \n" \
+ " scond %[val], [%[ctr]] \n" \
+ " \n" \
+ SCOND_FAIL_RETRY_ASM \
+ \
+ : [val] "=&r" (val), \
+ [orig] "=&r" (orig) \
+ SCOND_FAIL_RETRY_VARS \
+ : [ctr] "r" (&v->counter), \
+ [i] "ir" (i) \
+ : "cc"); \
+ \
+ smp_mb(); \
+ \
+ return orig; \
+}
+
#else /* !CONFIG_ARC_HAS_LLSC */
#ifndef CONFIG_SMP
@@ -166,21 +197,46 @@ static inline int atomic_##op##_return(i
return temp; \
}
+#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
+static inline int atomic_fetch_##op(int i, atomic_t *v) \
+{ \
+ unsigned long flags; \
+ unsigned long orig; \
+ \
+ /* \
+ * spin lock/unlock provides the needed smp_mb() before/after \
+ */ \
+ atomic_ops_lock(flags); \
+ orig = v->counter; \
+ v->counter c_op i; \
+ atomic_ops_unlock(flags); \
+ \
+ return orig; \
+}
+
#endif /* !CONFIG_ARC_HAS_LLSC */
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
- ATOMIC_OP_RETURN(op, c_op, asm_op)
+ ATOMIC_OP_RETURN(op, c_op, asm_op) \
+ ATOMIC_FETCH_OP(op, c_op, asm_op)
ATOMIC_OPS(add, +=, add)
ATOMIC_OPS(sub, -=, sub)
#define atomic_andnot atomic_andnot
-ATOMIC_OP(and, &=, and)
-ATOMIC_OP(andnot, &= ~, bic)
-ATOMIC_OP(or, |=, or)
-ATOMIC_OP(xor, ^=, xor)
+#define atomic_fetch_or atomic_fetch_or
+
+#undef ATOMIC_OPS
+#define ATOMIC_OPS(op, c_op, asm_op) \
+ ATOMIC_OP(op, c_op, asm_op) \
+ ATOMIC_FETCH_OP(op, c_op, asm_op)
+
+ATOMIC_OPS(and, &=, and)
+ATOMIC_OPS(andnot, &= ~, bic)
+ATOMIC_OPS(or, |=, or)
+ATOMIC_OPS(xor, ^=, xor)
#undef SCOND_FAIL_RETRY_VAR_DEF
#undef SCOND_FAIL_RETRY_ASM
@@ -245,22 +301,51 @@ static inline int atomic_##op##_return(i
return temp; \
}
+#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
+static inline int atomic_fetch_##op(int i, atomic_t *v) \
+{ \
+ unsigned int temp = i; \
+ \
+ /* Explicit full memory barrier needed before/after */ \
+ smp_mb(); \
+ \
+ __asm__ __volatile__( \
+ " mov r2, %0\n" \
+ " mov r3, %1\n" \
+ " .word %2\n" \
+ " mov %0, r2" \
+ : "+r"(temp) \
+ : "r"(&v->counter), "i"(asm_op) \
+ : "r2", "r3", "memory"); \
+ \
+ smp_mb(); \
+ \
+ return temp; \
+}
+
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
- ATOMIC_OP_RETURN(op, c_op, asm_op)
+ ATOMIC_OP_RETURN(op, c_op, asm_op) \
+ ATOMIC_FETCH_OP(op, c_op, asm_op)
ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
#define atomic_sub(i, v) atomic_add(-(i), (v))
#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
-ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
+#undef ATOMIC_OPS
+#define ATOMIC_OPS(op, c_op, asm_op) \
+ ATOMIC_OP(op, c_op, asm_op) \
+ ATOMIC_FETCH_OP(op, c_op, asm_op)
+
+ATOMIC_OPS(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
-ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
-ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
+ATOMIC_OPS(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
+ATOMIC_OPS(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
#endif /* CONFIG_ARC_PLAT_EZNPS */
#undef ATOMIC_OPS
+#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH -v2 00/33] implement atomic_fetch_$op Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 23/33] locking,tile: Implement atomic{,64}_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 31/33] locking,mips: Convert to _relaxed atomics Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 01/33] locking,alpha: Implement atomic{,64}_fetch_{add,sub,and,andnot,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 17/33] locking,mn10300: Implement atomic_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 07/33] locking,avr32: Implement atomic_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 29/33] locking: Remove the deprecated atomic_{set,clear}_mask() functions Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 21/33] locking,sh: Implement atomic_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 30/33] locking,alpha: Convert to _relaxed atomics Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 02/33] locking,arc: Implement atomic_fetch_{add,sub,and,andnot,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 08/33] locking,blackfin: Implement atomic_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 16/33] locking,mips: Implement atomic{,64}_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 05/33] arm64: atomic: generate LSE non-return cases using common macros Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 10/33] locking,h8300: Implement atomic_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 22/33] locking,sparc: Implement atomic{,64}_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
Re: [PATCH -v2 22/33] locking,sparc: Implement atomic{,64}_fetch_{add,sub,and,or,xor}() David Miller <davem@davemloft.net> - 2016-05-31 20:00 +0200
[PATCH -v2 12/33] locking,ia64: Implement atomic{,64}_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 04/33] locking,arm64: Implement atomic{,64}_fetch_{add,sub,and,andnot,or,xor}{,_relaxed,_acquire,_release}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 33/33] locking,rwsem: Employ atomic_long_fetch_add() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 13/33] locking,m32r: Implement atomic_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 06/33] locking,arm64: Implement atomic{,64}_fetch_{add,sub,and,andnot,or,xor}{,_relaxed,_acquire,_release}() for LSE instructions Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 26/33] locking: Fix atomic64_relaxed bits Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 27/33] locking: Implement atomic{,64,_long}_fetch_{add,sub,and,andnot,or,xor}{,_relaxed,_acquire,_release}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:40 +0200
[PATCH -v2 11/33] locking,hexagon: Implement atomic_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:50 +0200
[PATCH -v2 20/33] locking,s390: Implement atomic{,64}_fetch_{add,sub,and,or,xor}() Peter Zijlstra <peterz@infradead.org> - 2016-05-31 12:50 +0200
Re: [PATCH -v2 00/33] implement atomic_fetch_$op Will Deacon <will.deacon@arm.com> - 2016-06-01 16:10 +0200
Re: [PATCH -v2 00/33] implement atomic_fetch_$op Vineet Gupta <Vineet.Gupta1@synopsys.com> - 2016-06-02 11:30 +0200
Re: [PATCH -v2 00/33] implement atomic_fetch_$op Peter Zijlstra <peterz@infradead.org> - 2016-06-02 11:40 +0200
Re: [PATCH -v2 00/33] implement atomic_fetch_$op Peter Zijlstra <peterz@infradead.org> - 2016-06-08 14:50 +0200
Re: [PATCH -v2 00/33] implement atomic_fetch_$op Ingo Molnar <mingo@kernel.org> - 2016-06-08 15:00 +0200
Re: [PATCH -v2 00/33] implement atomic_fetch_$op Peter Zijlstra <peterz@infradead.org> - 2016-06-08 15:40 +0200
Re: [PATCH -v2 00/33] implement atomic_fetch_$op Vineet Gupta <vgupta@synopsys.com> - 2016-06-08 16:30 +0200
Re: [PATCH -v2 00/33] implement atomic_fetch_$op Peter Zijlstra <peterz@infradead.org> - 2016-06-08 16:40 +0200
csiph-web