locking,arch,mn10300: Fold atomic_ops
authorPeter Zijlstra <peterz@infradead.org>
Wed, 26 Mar 2014 16:59:04 +0000 (17:59 +0100)
committerIngo Molnar <mingo@kernel.org>
Thu, 14 Aug 2014 10:48:10 +0000 (12:48 +0200)
Many of the atomic op implementations are the same except for one
instruction; fold the lot into a few CPP macros and reduce LoC.

This also prepares for easy addition of new ops.

Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: linux-am33-list@redhat.com
Link: http://lkml.kernel.org/r/20140508135852.605324173@infradead.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/mn10300/include/asm/atomic.h

index cadeb1e2cdfcfa1f473ac44f1e63a3a81b0c2fa9..5be655e83e709dbaf762efac0e3befea8dfd0d9f 100644 (file)
@@ -33,7 +33,6 @@
  * @v: pointer of type atomic_t
  *
  * Atomically reads the value of @v.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
  */
 #define atomic_read(v) (ACCESS_ONCE((v)->counter))
 
  * @i: required value
  *
  * Atomically sets the value of @v to @i.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
  */
 #define atomic_set(v, i) (((v)->counter) = (i))
 
-/**
- * atomic_add_return - add integer to atomic variable
- * @i: integer value to add
- * @v: pointer of type atomic_t
- *
- * Atomically adds @i to @v and returns the result
- * Note that the guaranteed useful range of an atomic_t is only 24 bits.
- */
-static inline int atomic_add_return(int i, atomic_t *v)
-{
-       int retval;
-#ifdef CONFIG_SMP
-       int status;
-
-       asm volatile(
-               "1:     mov     %4,(_AAR,%3)    \n"
-               "       mov     (_ADR,%3),%1    \n"
-               "       add     %5,%1           \n"
-               "       mov     %1,(_ADR,%3)    \n"
-               "       mov     (_ADR,%3),%0    \n"     /* flush */
-               "       mov     (_ASR,%3),%0    \n"
-               "       or      %0,%0           \n"
-               "       bne     1b              \n"
-               : "=&r"(status), "=&r"(retval), "=m"(v->counter)
-               : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i)
-               : "memory", "cc");
-
-#else
-       unsigned long flags;
+#define ATOMIC_OP(op)                                                  \
+static inline void atomic_##op(int i, atomic_t *v)                     \
+{                                                                      \
+       int retval, status;                                             \
+                                                                       \
+       asm volatile(                                                   \
+               "1:     mov     %4,(_AAR,%3)    \n"                     \
+               "       mov     (_ADR,%3),%1    \n"                     \
+               "       " #op " %5,%1           \n"                     \
+               "       mov     %1,(_ADR,%3)    \n"                     \
+               "       mov     (_ADR,%3),%0    \n"     /* flush */     \
+               "       mov     (_ASR,%3),%0    \n"                     \
+               "       or      %0,%0           \n"                     \
+               "       bne     1b              \n"                     \
+               : "=&r"(status), "=&r"(retval), "=m"(v->counter)        \
+               : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i)   \
+               : "memory", "cc");                                      \
+}
 
-       flags = arch_local_cli_save();
-       retval = v->counter;
-       retval += i;
-       v->counter = retval;
-       arch_local_irq_restore(flags);
-#endif
-       return retval;
+#define ATOMIC_OP_RETURN(op)                                           \
+static inline int atomic_##op##_return(int i, atomic_t *v)             \
+{                                                                      \
+       int retval, status;                                             \
+                                                                       \
+       asm volatile(                                                   \
+               "1:     mov     %4,(_AAR,%3)    \n"                     \
+               "       mov     (_ADR,%3),%1    \n"                     \
+               "       " #op " %5,%1           \n"                     \
+               "       mov     %1,(_ADR,%3)    \n"                     \
+               "       mov     (_ADR,%3),%0    \n"     /* flush */     \
+               "       mov     (_ASR,%3),%0    \n"                     \
+               "       or      %0,%0           \n"                     \
+               "       bne     1b              \n"                     \
+               : "=&r"(status), "=&r"(retval), "=m"(v->counter)        \
+               : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i)   \
+               : "memory", "cc");                                      \
+       return retval;                                                  \
 }
 
-/**
- * atomic_sub_return - subtract integer from atomic variable
- * @i: integer value to subtract
- * @v: pointer of type atomic_t
- *
- * Atomically subtracts @i from @v and returns the result
- * Note that the guaranteed useful range of an atomic_t is only 24 bits.
- */
-static inline int atomic_sub_return(int i, atomic_t *v)
-{
-       int retval;
-#ifdef CONFIG_SMP
-       int status;
+#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op)
 
-       asm volatile(
-               "1:     mov     %4,(_AAR,%3)    \n"
-               "       mov     (_ADR,%3),%1    \n"
-               "       sub     %5,%1           \n"
-               "       mov     %1,(_ADR,%3)    \n"
-               "       mov     (_ADR,%3),%0    \n"     /* flush */
-               "       mov     (_ASR,%3),%0    \n"
-               "       or      %0,%0           \n"
-               "       bne     1b              \n"
-               : "=&r"(status), "=&r"(retval), "=m"(v->counter)
-               : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i)
-               : "memory", "cc");
+ATOMIC_OPS(add)
+ATOMIC_OPS(sub)
 
-#else
-       unsigned long flags;
-       flags = arch_local_cli_save();
-       retval = v->counter;
-       retval -= i;
-       v->counter = retval;
-       arch_local_irq_restore(flags);
-#endif
-       return retval;
-}
+#undef ATOMIC_OPS
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
 
 static inline int atomic_add_negative(int i, atomic_t *v)
 {
        return atomic_add_return(i, v) < 0;
 }
 
-static inline void atomic_add(int i, atomic_t *v)
-{
-       atomic_add_return(i, v);
-}
-
-static inline void atomic_sub(int i, atomic_t *v)
-{
-       atomic_sub_return(i, v);
-}
-
 static inline void atomic_inc(atomic_t *v)
 {
        atomic_add_return(1, v);