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

x86: Provide atomic_{or,xor,and}

Implement atomic logic ops -- atomic_{or,xor,and}.

These will replace the atomic_{set,clear}_mask functions that are
available on some archs.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Peter Zijlstra and committed by
Thomas Gleixner
7fc1845d ae8c35c8

+54 -8
+25 -8
arch/x86/include/asm/atomic.h
··· 182 182 return xchg(&v->counter, new); 183 183 } 184 184 185 + #define ATOMIC_OP(op) \ 186 + static inline void atomic_##op(int i, atomic_t *v) \ 187 + { \ 188 + asm volatile(LOCK_PREFIX #op"l %1,%0" \ 189 + : "+m" (v->counter) \ 190 + : "ir" (i) \ 191 + : "memory"); \ 192 + } 193 + 194 + #define CONFIG_ARCH_HAS_ATOMIC_OR 195 + 196 + ATOMIC_OP(and) 197 + ATOMIC_OP(or) 198 + ATOMIC_OP(xor) 199 + 200 + #undef ATOMIC_OP 201 + 185 202 /** 186 203 * __atomic_add_unless - add unless the number is already a given value 187 204 * @v: pointer of type atomic_t ··· 236 219 return *v; 237 220 } 238 221 239 - /* These are x86-specific, used by some header files */ 240 - #define atomic_clear_mask(mask, addr) \ 241 - asm volatile(LOCK_PREFIX "andl %0,%1" \ 242 - : : "r" (~(mask)), "m" (*(addr)) : "memory") 222 + static inline __deprecated void atomic_clear_mask(unsigned int mask, atomic_t *v) 223 + { 224 + atomic_and(~mask, v); 225 + } 243 226 244 - #define atomic_set_mask(mask, addr) \ 245 - asm volatile(LOCK_PREFIX "orl %0,%1" \ 246 - : : "r" ((unsigned)(mask)), "m" (*(addr)) \ 247 - : "memory") 227 + static inline __deprecated void atomic_set_mask(unsigned int mask, atomic_t *v) 228 + { 229 + atomic_or(mask, v); 230 + } 248 231 249 232 #ifdef CONFIG_X86_32 250 233 # include <asm/atomic64_32.h>
+14
arch/x86/include/asm/atomic64_32.h
··· 313 313 #undef alternative_atomic64 314 314 #undef __alternative_atomic64 315 315 316 + #define ATOMIC64_OP(op, c_op) \ 317 + static inline void atomic64_##op(long long i, atomic64_t *v) \ 318 + { \ 319 + long long old, c = 0; \ 320 + while ((old = atomic64_cmpxchg(v, c, c c_op i)) != c) \ 321 + c = old; \ 322 + } 323 + 324 + ATOMIC64_OP(and, &) 325 + ATOMIC64_OP(or, |) 326 + ATOMIC64_OP(xor, ^) 327 + 328 + #undef ATOMIC64_OP 329 + 316 330 #endif /* _ASM_X86_ATOMIC64_32_H */
+15
arch/x86/include/asm/atomic64_64.h
··· 220 220 return dec; 221 221 } 222 222 223 + #define ATOMIC64_OP(op) \ 224 + static inline void atomic64_##op(long i, atomic64_t *v) \ 225 + { \ 226 + asm volatile(LOCK_PREFIX #op"q %1,%0" \ 227 + : "+m" (v->counter) \ 228 + : "er" (i) \ 229 + : "memory"); \ 230 + } 231 + 232 + ATOMIC64_OP(and) 233 + ATOMIC64_OP(or) 234 + ATOMIC64_OP(xor) 235 + 236 + #undef ATOMIC64_OP 237 + 223 238 #endif /* _ASM_X86_ATOMIC64_64_H */