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

locking/local, arch: Rewrite local_add_unless() as a static inline function

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

authored by

Uros Bizjak and committed by
Ingo Molnar
5e0eb679 8788c6c2

+70 -62
+16 -17
arch/alpha/include/asm/local.h
··· 65 65 #define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n))) 66 66 67 67 /** 68 - * local_add_unless - add unless the number is a given value 68 + * local_add_unless - add unless the number is already a given value 69 69 * @l: pointer of type local_t 70 70 * @a: the amount to add to l... 71 71 * @u: ...unless l is equal to u. 72 72 * 73 - * Atomically adds @a to @l, so long as it was not @u. 74 - * Returns non-zero if @l was not @u, and zero otherwise. 73 + * Atomically adds @a to @l, if @v was not already @u. 74 + * Returns true if the addition was done. 75 75 */ 76 - #define local_add_unless(l, a, u) \ 77 - ({ \ 78 - long c, old; \ 79 - c = local_read(l); \ 80 - for (;;) { \ 81 - if (unlikely(c == (u))) \ 82 - break; \ 83 - old = local_cmpxchg((l), c, c + (a)); \ 84 - if (likely(old == c)) \ 85 - break; \ 86 - c = old; \ 87 - } \ 88 - c != (u); \ 89 - }) 76 + static __inline__ bool 77 + local_add_unless(local_t *l, long a, long u) 78 + { 79 + long c = local_read(l); 80 + 81 + do { 82 + if (unlikely(c == u)) 83 + return false; 84 + } while (!local_try_cmpxchg(l, &c, c + a)); 85 + 86 + return true; 87 + } 88 + 90 89 #define local_inc_not_zero(l) local_add_unless((l), 1, 0) 91 90 92 91 #define local_add_negative(a, l) (local_add_return((a), (l)) < 0)
+16 -11
arch/loongarch/include/asm/local.h
··· 70 70 #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n))) 71 71 72 72 /** 73 - * local_add_unless - add unless the number is a given value 73 + * local_add_unless - add unless the number is already a given value 74 74 * @l: pointer of type local_t 75 75 * @a: the amount to add to l... 76 76 * @u: ...unless l is equal to u. 77 77 * 78 - * Atomically adds @a to @l, so long as it was not @u. 79 - * Returns non-zero if @l was not @u, and zero otherwise. 78 + * Atomically adds @a to @l, if @v was not already @u. 79 + * Returns true if the addition was done. 80 80 */ 81 - #define local_add_unless(l, a, u) \ 82 - ({ \ 83 - long c, old; \ 84 - c = local_read(l); \ 85 - while (c != (u) && (old = local_cmpxchg((l), c, c + (a))) != c) \ 86 - c = old; \ 87 - c != (u); \ 88 - }) 81 + static inline bool 82 + local_add_unless(local_t *l, long a, long u) 83 + { 84 + long c = local_read(l); 85 + 86 + do { 87 + if (unlikely(c == u)) 88 + return false; 89 + } while (!local_try_cmpxchg(l, &c, c + a)); 90 + 91 + return true; 92 + } 93 + 89 94 #define local_inc_not_zero(l) local_add_unless((l), 1, 0) 90 95 91 96 #define local_dec_return(l) local_sub_return(1, (l))
+16 -11
arch/mips/include/asm/local.h
··· 108 108 #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n))) 109 109 110 110 /** 111 - * local_add_unless - add unless the number is a given value 111 + * local_add_unless - add unless the number is already a given value 112 112 * @l: pointer of type local_t 113 113 * @a: the amount to add to l... 114 114 * @u: ...unless l is equal to u. 115 115 * 116 - * Atomically adds @a to @l, so long as it was not @u. 117 - * Returns non-zero if @l was not @u, and zero otherwise. 116 + * Atomically adds @a to @l, if @v was not already @u. 117 + * Returns true if the addition was done. 118 118 */ 119 - #define local_add_unless(l, a, u) \ 120 - ({ \ 121 - long c, old; \ 122 - c = local_read(l); \ 123 - while (c != (u) && (old = local_cmpxchg((l), c, c + (a))) != c) \ 124 - c = old; \ 125 - c != (u); \ 126 - }) 119 + static __inline__ bool 120 + local_add_unless(local_t *l, long a, long u) 121 + { 122 + long c = local_read(l); 123 + 124 + do { 125 + if (unlikely(c == u)) 126 + return false; 127 + } while (!local_try_cmpxchg(l, &c, c + a)); 128 + 129 + return true; 130 + } 131 + 127 132 #define local_inc_not_zero(l) local_add_unless((l), 1, 0) 128 133 129 134 #define local_dec_return(l) local_sub_return(1, (l))
+6 -6
arch/powerpc/include/asm/local.h
··· 115 115 } 116 116 117 117 /** 118 - * local_add_unless - add unless the number is a given value 118 + * local_add_unless - add unless the number is already a given value 119 119 * @l: pointer of type local_t 120 120 * @a: the amount to add to v... 121 121 * @u: ...unless v is equal to u. 122 122 * 123 - * Atomically adds @a to @l, so long as it was not @u. 124 - * Returns non-zero if @l was not @u, and zero otherwise. 123 + * Atomically adds @a to @l, if @v was not already @u. 124 + * Returns true if the addition was done. 125 125 */ 126 - static __inline__ int local_add_unless(local_t *l, long a, long u) 126 + static __inline__ bool local_add_unless(local_t *l, long a, long u) 127 127 { 128 128 unsigned long flags; 129 - int ret = 0; 129 + bool ret = false; 130 130 131 131 powerpc_local_irq_pmu_save(flags); 132 132 if (l->v != u) { 133 133 l->v += a; 134 - ret = 1; 134 + ret = true; 135 135 } 136 136 powerpc_local_irq_pmu_restore(flags); 137 137
+16 -17
arch/x86/include/asm/local.h
··· 135 135 #define local_xchg(l, n) (xchg(&((l)->a.counter), (n))) 136 136 137 137 /** 138 - * local_add_unless - add unless the number is a given value 138 + * local_add_unless - add unless the number is already a given value 139 139 * @l: pointer of type local_t 140 140 * @a: the amount to add to l... 141 141 * @u: ...unless l is equal to u. 142 142 * 143 - * Atomically adds @a to @l, so long as it was not @u. 144 - * Returns non-zero if @l was not @u, and zero otherwise. 143 + * Atomically adds @a to @l, if @v was not already @u. 144 + * Returns true if the addition was done. 145 145 */ 146 - #define local_add_unless(l, a, u) \ 147 - ({ \ 148 - long c, old; \ 149 - c = local_read((l)); \ 150 - for (;;) { \ 151 - if (unlikely(c == (u))) \ 152 - break; \ 153 - old = local_cmpxchg((l), c, c + (a)); \ 154 - if (likely(old == c)) \ 155 - break; \ 156 - c = old; \ 157 - } \ 158 - c != (u); \ 159 - }) 146 + static __always_inline bool 147 + local_add_unless(local_t *l, long a, long u) 148 + { 149 + long c = local_read(l); 150 + 151 + do { 152 + if (unlikely(c == u)) 153 + return false; 154 + } while (!local_try_cmpxchg(l, &c, c + a)); 155 + 156 + return true; 157 + } 158 + 160 159 #define local_inc_not_zero(l) local_add_unless((l), 1, 0) 161 160 162 161 /* On x86_32, these are no better than the atomic variants.