Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

locking/atomic, arch/frv: Implement atomic{,64}_fetch_{add,sub,and,or,xor}()

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).

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arch@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Peter Zijlstra and committed by
Ingo Molnar
d9c73028 e87fc0ec

+14 -20
+12 -20
arch/frv/include/asm/atomic.h
··· 60 60 return atomic_add_return(i, v) < 0; 61 61 } 62 62 63 - static inline void atomic_add(int i, atomic_t *v) 64 - { 65 - atomic_add_return(i, v); 66 - } 67 - 68 - static inline void atomic_sub(int i, atomic_t *v) 69 - { 70 - atomic_sub_return(i, v); 71 - } 72 - 73 63 static inline void atomic_inc(atomic_t *v) 74 64 { 75 65 atomic_inc_return(v); ··· 73 83 #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) 74 84 #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) 75 85 #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) 86 + 87 + #define atomic_fetch_or atomic_fetch_or 76 88 77 89 /* 78 90 * 64-bit atomic ops ··· 128 136 return atomic64_add_return(i, v) < 0; 129 137 } 130 138 131 - static inline void atomic64_add(long long i, atomic64_t *v) 132 - { 133 - atomic64_add_return(i, v); 134 - } 135 - 136 - static inline void atomic64_sub(long long i, atomic64_t *v) 137 - { 138 - atomic64_sub_return(i, v); 139 - } 140 - 141 139 static inline void atomic64_inc(atomic64_t *v) 142 140 { 143 141 atomic64_inc_return(v); ··· 164 182 } 165 183 166 184 #define ATOMIC_OP(op) \ 185 + static inline int atomic_fetch_##op(int i, atomic_t *v) \ 186 + { \ 187 + return __atomic32_fetch_##op(i, &v->counter); \ 188 + } \ 167 189 static inline void atomic_##op(int i, atomic_t *v) \ 168 190 { \ 169 191 (void)__atomic32_fetch_##op(i, &v->counter); \ 170 192 } \ 171 193 \ 194 + static inline long long atomic64_fetch_##op(long long i, atomic64_t *v) \ 195 + { \ 196 + return __atomic64_fetch_##op(i, &v->counter); \ 197 + } \ 172 198 static inline void atomic64_##op(long long i, atomic64_t *v) \ 173 199 { \ 174 200 (void)__atomic64_fetch_##op(i, &v->counter); \ ··· 185 195 ATOMIC_OP(or) 186 196 ATOMIC_OP(and) 187 197 ATOMIC_OP(xor) 198 + ATOMIC_OP(add) 199 + ATOMIC_OP(sub) 188 200 189 201 #undef ATOMIC_OP 190 202
+2
arch/frv/include/asm/atomic_defs.h
··· 162 162 ATOMIC_FETCH_OP(or) 163 163 ATOMIC_FETCH_OP(and) 164 164 ATOMIC_FETCH_OP(xor) 165 + ATOMIC_FETCH_OP(add) 166 + ATOMIC_FETCH_OP(sub) 165 167 166 168 ATOMIC_OP_RETURN(add) 167 169 ATOMIC_OP_RETURN(sub)