]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
locking/local, arch: Rewrite local_add_unless() as a static inline function
authorUros Bizjak <ubizjak@gmail.com>
Mon, 31 Jul 2023 08:42:23 +0000 (10:42 +0200)
committerIngo Molnar <mingo@kernel.org>
Wed, 4 Oct 2023 09:38:11 +0000 (11:38 +0200)
Rewrite local_add_unless() as a static inline function with boolean
return value, similar to the arch_atomic_add_unless() arch fallbacks.

The function is currently unused.

Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20230731084458.28096-1-ubizjak@gmail.com
arch/alpha/include/asm/local.h
arch/loongarch/include/asm/local.h
arch/mips/include/asm/local.h
arch/powerpc/include/asm/local.h
arch/x86/include/asm/local.h

index 0fcaad642cc3ea7c943a5b72732bd0874fc51c0b..88eb398947a5beb9218a50ada710700836f9e300 100644 (file)
@@ -65,28 +65,27 @@ static __inline__ bool local_try_cmpxchg(local_t *l, long *old, long new)
 #define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
 
 /**
- * local_add_unless - add unless the number is a given value
+ * local_add_unless - add unless the number is already a given value
  * @l: pointer of type local_t
  * @a: the amount to add to l...
  * @u: ...unless l is equal to u.
  *
- * Atomically adds @a to @l, so long as it was not @u.
- * Returns non-zero if @l was not @u, and zero otherwise.
+ * Atomically adds @a to @l, if @v was not already @u.
+ * Returns true if the addition was done.
  */
-#define local_add_unless(l, a, u)                              \
-({                                                             \
-       long c, old;                                            \
-       c = local_read(l);                                      \
-       for (;;) {                                              \
-               if (unlikely(c == (u)))                         \
-                       break;                                  \
-               old = local_cmpxchg((l), c, c + (a));   \
-               if (likely(old == c))                           \
-                       break;                                  \
-               c = old;                                        \
-       }                                                       \
-       c != (u);                                               \
-})
+static __inline__ bool
+local_add_unless(local_t *l, long a, long u)
+{
+       long c = local_read(l);
+
+       do {
+               if (unlikely(c == u))
+                       return false;
+       } while (!local_try_cmpxchg(l, &c, c + a));
+
+       return true;
+}
+
 #define local_inc_not_zero(l) local_add_unless((l), 1, 0)
 
 #define local_add_negative(a, l) (local_add_return((a), (l)) < 0)
index c49675852bdcd5b84a4ef34b0538edc331f51287..f53ea653af76d7f708d6becbf8e5eaf58d700391 100644 (file)
@@ -70,22 +70,27 @@ static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
 #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
 
 /**
- * local_add_unless - add unless the number is a given value
+ * local_add_unless - add unless the number is already a given value
  * @l: pointer of type local_t
  * @a: the amount to add to l...
  * @u: ...unless l is equal to u.
  *
- * Atomically adds @a to @l, so long as it was not @u.
- * Returns non-zero if @l was not @u, and zero otherwise.
+ * Atomically adds @a to @l, if @v was not already @u.
+ * Returns true if the addition was done.
  */
-#define local_add_unless(l, a, u)                              \
-({                                                             \
-       long c, old;                                            \
-       c = local_read(l);                                      \
-       while (c != (u) && (old = local_cmpxchg((l), c, c + (a))) != c) \
-               c = old;                                        \
-       c != (u);                                               \
-})
+static inline bool
+local_add_unless(local_t *l, long a, long u)
+{
+       long c = local_read(l);
+
+       do {
+               if (unlikely(c == u))
+                       return false;
+       } while (!local_try_cmpxchg(l, &c, c + a));
+
+       return true;
+}
+
 #define local_inc_not_zero(l) local_add_unless((l), 1, 0)
 
 #define local_dec_return(l) local_sub_return(1, (l))
index e6ae3df0349d23233dcf7b2cbefdf5cba5092428..86fc2402224258874cacbd41de9b3d6d4ce9450d 100644 (file)
@@ -108,22 +108,27 @@ static __inline__ bool local_try_cmpxchg(local_t *l, long *old, long new)
 #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
 
 /**
- * local_add_unless - add unless the number is a given value
+ * local_add_unless - add unless the number is already a given value
  * @l: pointer of type local_t
  * @a: the amount to add to l...
  * @u: ...unless l is equal to u.
  *
- * Atomically adds @a to @l, so long as it was not @u.
- * Returns non-zero if @l was not @u, and zero otherwise.
+ * Atomically adds @a to @l, if @v was not already @u.
+ * Returns true if the addition was done.
  */
-#define local_add_unless(l, a, u)                              \
-({                                                             \
-       long c, old;                                            \
-       c = local_read(l);                                      \
-       while (c != (u) && (old = local_cmpxchg((l), c, c + (a))) != c) \
-               c = old;                                        \
-       c != (u);                                               \
-})
+static __inline__ bool
+local_add_unless(local_t *l, long a, long u)
+{
+       long c = local_read(l);
+
+       do {
+               if (unlikely(c == u))
+                       return false;
+       } while (!local_try_cmpxchg(l, &c, c + a));
+
+       return true;
+}
+
 #define local_inc_not_zero(l) local_add_unless((l), 1, 0)
 
 #define local_dec_return(l) local_sub_return(1, (l))
index 45492fb5bf223cbd1870b202bd21dc5cdc98a708..ec6ced6d7cedfeba47397785e8dacb0d519b3565 100644 (file)
@@ -115,23 +115,23 @@ static __inline__ long local_xchg(local_t *l, long n)
 }
 
 /**
- * local_add_unless - add unless the number is a given value
+ * local_add_unless - add unless the number is already a given value
  * @l: pointer of type local_t
  * @a: the amount to add to v...
  * @u: ...unless v is equal to u.
  *
- * Atomically adds @a to @l, so long as it was not @u.
- * Returns non-zero if @l was not @u, and zero otherwise.
+ * Atomically adds @a to @l, if @v was not already @u.
+ * Returns true if the addition was done.
  */
-static __inline__ int local_add_unless(local_t *l, long a, long u)
+static __inline__ bool local_add_unless(local_t *l, long a, long u)
 {
        unsigned long flags;
-       int ret = 0;
+       bool ret = false;
 
        powerpc_local_irq_pmu_save(flags);
        if (l->v != u) {
                l->v += a;
-               ret = 1;
+               ret = true;
        }
        powerpc_local_irq_pmu_restore(flags);
 
index 635132a127782d3262fc1e2f82c07d8db3885b9e..73dba8b9444308d603e5e5db6b76d412aea6b3b5 100644 (file)
@@ -135,28 +135,27 @@ static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
 #define local_xchg(l, n) (xchg(&((l)->a.counter), (n)))
 
 /**
- * local_add_unless - add unless the number is a given value
+ * local_add_unless - add unless the number is already a given value
  * @l: pointer of type local_t
  * @a: the amount to add to l...
  * @u: ...unless l is equal to u.
  *
- * Atomically adds @a to @l, so long as it was not @u.
- * Returns non-zero if @l was not @u, and zero otherwise.
+ * Atomically adds @a to @l, if @v was not already @u.
+ * Returns true if the addition was done.
  */
-#define local_add_unless(l, a, u)                              \
-({                                                             \
-       long c, old;                                            \
-       c = local_read((l));                                    \
-       for (;;) {                                              \
-               if (unlikely(c == (u)))                         \
-                       break;                                  \
-               old = local_cmpxchg((l), c, c + (a));           \
-               if (likely(old == c))                           \
-                       break;                                  \
-               c = old;                                        \
-       }                                                       \
-       c != (u);                                               \
-})
+static __always_inline bool
+local_add_unless(local_t *l, long a, long u)
+{
+       long c = local_read(l);
+
+       do {
+               if (unlikely(c == u))
+                       return false;
+       } while (!local_try_cmpxchg(l, &c, c + a));
+
+       return true;
+}
+
 #define local_inc_not_zero(l) local_add_unless((l), 1, 0)
 
 /* On x86_32, these are no better than the atomic variants.