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>
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
#define atomic_andnot atomic_andnot
#define atomic64_andnot atomic64_andnot
ATOMIC_OPS(add, +=, add)
ATOMIC_OPS(sub, -=, sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
#define atomic_andnot atomic_andnot
ATOMIC_OP(and, &=, and)
ATOMIC_OPS(add, +=, add)
ATOMIC_OPS(sub, -=, sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
#define atomic_andnot atomic_andnot
ATOMIC_OP(and, &=, and)
ATOMIC_OPS(add, add)
ATOMIC_OPS(sub, sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
#define atomic_andnot atomic_andnot
ATOMIC_OP(and, and)
(void)__atomic_##op##_return(i, v); \
}
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and, and)
ATOMIC_OP(or, or)
ATOMIC_OP(xor, eor)
#define atomic_add_return(i, v) __raw_atomic_add_asm(&(v)->counter, i)
#define atomic_sub_return(i, v) __raw_atomic_add_asm(&(v)->counter, -(i))
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
#define atomic_or(i, v) (void)__raw_atomic_or_asm(&(v)->counter, i)
#define atomic_and(i, v) (void)__raw_atomic_and_asm(&(v)->counter, i)
#define atomic_xor(i, v) (void)__raw_atomic_xor_asm(&(v)->counter, i)
(void)__atomic64_fetch_##op(i, &v->counter); \
}
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(or)
ATOMIC_OP(and)
ATOMIC_OP(xor)
ATOMIC_OP_RETURN(add, +=)
ATOMIC_OP_RETURN(sub, -=)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and, &=)
ATOMIC_OP(or, |=)
ATOMIC_OP(xor, ^=)
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
: ia64_atomic_sub(__ia64_asr_i, v); \
})
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and, &)
ATOMIC_OP(or, |)
ATOMIC_OP(xor, ^)
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
ATOMIC_OPS(add, +=, add)
ATOMIC_OPS(sub, -=, sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and, &=, and)
ATOMIC_OP(or, |=, or)
ATOMIC_OP(xor, ^=, eor)
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
ATOMIC_OPS(add, +=, addu)
ATOMIC_OPS(sub, -=, subu)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and, &=, and)
ATOMIC_OP(or, |=, or)
ATOMIC_OP(xor, ^=, xor)
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
ATOMIC_OPS(add, +=)
ATOMIC_OPS(sub, -=)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and, &=)
ATOMIC_OP(or, |=)
ATOMIC_OP(xor, ^=)
ATOMIC_OPS(add, add)
ATOMIC_OPS(sub, subf)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and, and)
ATOMIC_OP(or, or)
ATOMIC_OP(xor, xor)
__ATOMIC64_LOOP(v, i, __ATOMIC64_##OP, __ATOMIC64_NO_BARRIER); \
}
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC64_OP(and, AND)
ATOMIC64_OP(or, OR)
ATOMIC64_OP(xor, XOR)
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
#include <asm/barrier.h>
#include <asm-generic/atomic64.h>
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
#define ATOMIC_INIT(i) { (i) }
int atomic_add_return(int, atomic_t *);
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
_atomic_##op((unsigned long *)&v->counter, i); \
}
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
return oldval;
}
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
static inline void atomic_and(int i, atomic_t *v)
{
__insn_fetchand4((void *)&v->counter, i);
: "memory"); \
}
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-
ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
ATOMIC_OP(and, &)
#endif
-#ifndef atomic_clear_mask
-#define atomic_clear_mask(i, v) atomic_and(~(i), (v))
-#endif
-
#ifndef atomic_or
-#ifndef CONFIG_ARCH_HAS_ATOMIC_OR
-#define CONFIG_ARCH_HAS_ATOMIC_OR
-#endif
ATOMIC_OP(or, |)
#endif
-#ifndef atomic_set_mask
-#define atomic_set_mask(i, v) atomic_or((i), (v))
+#ifndef atomic_xor
+ATOMIC_OP(xor, ^)
#endif
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
+static inline __deprecated void atomic_clear_mask(unsigned int mask, atomic_t *v)
+{
+ atomic_and(~mask, v);
+}
+
+static inline __deprecated void atomic_set_mask(unsigned int mask, atomic_t *v)
+{
+ atomic_or(mask, v);
+}
+
/*
* Atomic operations that C can't guarantee us. Useful for
* resource counting etc..
ATOMIC64_OPS(add)
ATOMIC64_OPS(sub)
+ATOMIC64_OP(and)
+ATOMIC64_OP(or)
+ATOMIC64_OP(xor)
+
#undef ATOMIC64_OPS
#undef ATOMIC64_OP_RETURN
#undef ATOMIC64_OP
}
#endif
-#ifndef CONFIG_ARCH_HAS_ATOMIC_OR
-static inline void atomic_or(int i, atomic_t *v)
-{
- int old;
- int new;
-
- do {
- old = atomic_read(v);
- new = old | i;
- } while (atomic_cmpxchg(v, old, new) != old);
-}
-#endif /* #ifndef CONFIG_ARCH_HAS_ATOMIC_OR */
-
#include <asm-generic/atomic-long.h>
#ifdef CONFIG_GENERIC_ATOMIC64
#include <asm-generic/atomic64.h>
ATOMIC64_OPS(add, +=)
ATOMIC64_OPS(sub, -=)
+ATOMIC64_OP(and, &=)
+ATOMIC64_OP(or, |=)
+ATOMIC64_OP(xor, ^=)
#undef ATOMIC64_OPS
#undef ATOMIC64_OP_RETURN