diff options
| author | Mathieu Desnoyers <compudj@krystal.dyndns.org> | 2007-05-08 03:34:38 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:20 -0400 |
| commit | 2856f5e31c1413bf6e4f1371e07e17078a5fee5e (patch) | |
| tree | 587dfe584f0913813d0cf2414a9378618143db15 /include | |
| parent | 79d365a306c3af53d8a732fec79b76c0b285d816 (diff) | |
atomic.h: atomic_add_unless as inline. Remove system.h atomic.h circular dependency
atomic_add_unless as inline. Remove system.h atomic.h circular dependency.
I agree (with Andi Kleen) this typeof is not needed and more error
prone. All the original atomic.h code that uses cmpxchg (which includes
the atomic_add_unless) uses defines instead of inline functions,
probably to circumvent a circular dependency between system.h and
atomic.h on powerpc (which my patch addresses). Therefore, it makes
sense to use inline functions that will provide type checking.
atomic_add_unless as inline. Remove system.h atomic.h circular dependency.
Digging into the FRV architecture shows me that it is also affected by
such a circular dependency. Here is the diff applying this against the
rest of my atomic.h patches.
It applies over the atomic.h standardization patches.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-alpha/atomic.h | 59 | ||||
| -rw-r--r-- | include/asm-arm/atomic.h | 1 | ||||
| -rw-r--r-- | include/asm-arm26/atomic.h | 1 | ||||
| -rw-r--r-- | include/asm-frv/atomic.h | 91 | ||||
| -rw-r--r-- | include/asm-frv/system.h | 70 | ||||
| -rw-r--r-- | include/asm-generic/atomic.h | 17 | ||||
| -rw-r--r-- | include/asm-i386/atomic.h | 29 | ||||
| -rw-r--r-- | include/asm-ia64/atomic.h | 59 | ||||
| -rw-r--r-- | include/asm-m32r/atomic.h | 23 | ||||
| -rw-r--r-- | include/asm-m68k/atomic.h | 31 | ||||
| -rw-r--r-- | include/asm-m68knommu/atomic.h | 25 | ||||
| -rw-r--r-- | include/asm-mips/atomic.h | 46 | ||||
| -rw-r--r-- | include/asm-parisc/atomic.h | 47 | ||||
| -rw-r--r-- | include/asm-powerpc/atomic.h | 1 | ||||
| -rw-r--r-- | include/asm-ppc/system.h | 1 | ||||
| -rw-r--r-- | include/asm-sparc64/atomic.h | 59 | ||||
| -rw-r--r-- | include/asm-x86_64/atomic.h | 59 | ||||
| -rw-r--r-- | include/asm-xtensa/atomic.h | 23 |
18 files changed, 360 insertions, 282 deletions
diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h index 7b4fba88cb..f5cb7b878a 100644 --- a/include/asm-alpha/atomic.h +++ b/include/asm-alpha/atomic.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #define _ALPHA_ATOMIC_H | 2 | #define _ALPHA_ATOMIC_H |
| 3 | 3 | ||
| 4 | #include <asm/barrier.h> | 4 | #include <asm/barrier.h> |
| 5 | #include <asm/system.h> | ||
| 5 | 6 | ||
| 6 | /* | 7 | /* |
| 7 | * Atomic operations that C can't guarantee us. Useful for | 8 | * Atomic operations that C can't guarantee us. Useful for |
| @@ -190,20 +191,21 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) | |||
| 190 | * Atomically adds @a to @v, so long as it was not @u. | 191 | * Atomically adds @a to @v, so long as it was not @u. |
| 191 | * Returns non-zero if @v was not @u, and zero otherwise. | 192 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 192 | */ | 193 | */ |
| 193 | #define atomic_add_unless(v, a, u) \ | 194 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 194 | ({ \ | 195 | { |
| 195 | __typeof__((v)->counter) c, old; \ | 196 | int c, old; |
| 196 | c = atomic_read(v); \ | 197 | c = atomic_read(v); |
| 197 | for (;;) { \ | 198 | for (;;) { |
| 198 | if (unlikely(c == (u))) \ | 199 | if (unlikely(c == (u))) |
| 199 | break; \ | 200 | break; |
| 200 | old = atomic_cmpxchg((v), c, c + (a)); \ | 201 | old = atomic_cmpxchg((v), c, c + (a)); |
| 201 | if (likely(old == c)) \ | 202 | if (likely(old == c)) |
| 202 | break; \ | 203 | break; |
| 203 | c = old; \ | 204 | c = old; |
| 204 | } \ | 205 | } |
| 205 | c != (u); \ | 206 | return c != (u); |
| 206 | }) | 207 | } |
| 208 | |||
| 207 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 209 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 208 | 210 | ||
| 209 | /** | 211 | /** |
| @@ -215,20 +217,21 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) | |||
| 215 | * Atomically adds @a to @v, so long as it was not @u. | 217 | * Atomically adds @a to @v, so long as it was not @u. |
| 216 | * Returns non-zero if @v was not @u, and zero otherwise. | 218 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 217 | */ | 219 | */ |
| 218 | #define atomic64_add_unless(v, a, u) \ | 220 | static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) |
| 219 | ({ \ | 221 | { |
| 220 | __typeof__((v)->counter) c, old; \ | 222 | long c, old; |
| 221 | c = atomic64_read(v); \ | 223 | c = atomic64_read(v); |
| 222 | for (;;) { \ | 224 | for (;;) { |
| 223 | if (unlikely(c == (u))) \ | 225 | if (unlikely(c == (u))) |
| 224 | break; \ | 226 | break; |
| 225 | old = atomic64_cmpxchg((v), c, c + (a)); \ | 227 | old = atomic64_cmpxchg((v), c, c + (a)); |
| 226 | if (likely(old == c)) \ | 228 | if (likely(old == c)) |
| 227 | break; \ | 229 | break; |
| 228 | c = old; \ | 230 | c = old; |
| 229 | } \ | 231 | } |
| 230 | c != (u); \ | 232 | return c != (u); |
| 231 | }) | 233 | } |
| 234 | |||
| 232 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 235 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
| 233 | 236 | ||
| 234 | #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) | 237 | #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) |
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h index f266c27951..3b59f94b5a 100644 --- a/include/asm-arm/atomic.h +++ b/include/asm-arm/atomic.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #define __ASM_ARM_ATOMIC_H | 12 | #define __ASM_ARM_ATOMIC_H |
| 13 | 13 | ||
| 14 | #include <linux/compiler.h> | 14 | #include <linux/compiler.h> |
| 15 | #include <asm/system.h> | ||
| 15 | 16 | ||
| 16 | typedef struct { volatile int counter; } atomic_t; | 17 | typedef struct { volatile int counter; } atomic_t; |
| 17 | 18 | ||
diff --git a/include/asm-arm26/atomic.h b/include/asm-arm26/atomic.h index 97e944fe1c..d6dd42374c 100644 --- a/include/asm-arm26/atomic.h +++ b/include/asm-arm26/atomic.h | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #ifndef __ASM_ARM_ATOMIC_H | 20 | #ifndef __ASM_ARM_ATOMIC_H |
| 21 | #define __ASM_ARM_ATOMIC_H | 21 | #define __ASM_ARM_ATOMIC_H |
| 22 | 22 | ||
| 23 | |||
| 24 | #ifdef CONFIG_SMP | 23 | #ifdef CONFIG_SMP |
| 25 | #error SMP is NOT supported | 24 | #error SMP is NOT supported |
| 26 | #endif | 25 | #endif |
diff --git a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h index 066386ac23..d425d8d0ad 100644 --- a/include/asm-frv/atomic.h +++ b/include/asm-frv/atomic.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 18 | #include <asm/spr-regs.h> | 18 | #include <asm/spr-regs.h> |
| 19 | #include <asm/system.h> | ||
| 19 | 20 | ||
| 20 | #ifdef CONFIG_SMP | 21 | #ifdef CONFIG_SMP |
| 21 | #error not SMP safe | 22 | #error not SMP safe |
| @@ -258,85 +259,23 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v); | |||
| 258 | 259 | ||
| 259 | #define tas(ptr) (xchg((ptr), 1)) | 260 | #define tas(ptr) (xchg((ptr), 1)) |
| 260 | 261 | ||
| 261 | /*****************************************************************************/ | ||
| 262 | /* | ||
| 263 | * compare and conditionally exchange value with memory | ||
| 264 | * - if (*ptr == test) then orig = *ptr; *ptr = test; | ||
| 265 | * - if (*ptr != test) then orig = *ptr; | ||
| 266 | */ | ||
| 267 | #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS | ||
| 268 | |||
| 269 | #define cmpxchg(ptr, test, new) \ | ||
| 270 | ({ \ | ||
| 271 | __typeof__(ptr) __xg_ptr = (ptr); \ | ||
| 272 | __typeof__(*(ptr)) __xg_orig, __xg_tmp; \ | ||
| 273 | __typeof__(*(ptr)) __xg_test = (test); \ | ||
| 274 | __typeof__(*(ptr)) __xg_new = (new); \ | ||
| 275 | \ | ||
| 276 | switch (sizeof(__xg_orig)) { \ | ||
| 277 | case 4: \ | ||
| 278 | asm volatile( \ | ||
| 279 | "0: \n" \ | ||
| 280 | " orcc gr0,gr0,gr0,icc3 \n" \ | ||
| 281 | " ckeq icc3,cc7 \n" \ | ||
| 282 | " ld.p %M0,%1 \n" \ | ||
| 283 | " orcr cc7,cc7,cc3 \n" \ | ||
| 284 | " sub%I4cc %1,%4,%2,icc0 \n" \ | ||
| 285 | " bne icc0,#0,1f \n" \ | ||
| 286 | " cst.p %3,%M0 ,cc3,#1 \n" \ | ||
| 287 | " corcc gr29,gr29,gr0 ,cc3,#1 \n" \ | ||
| 288 | " beq icc3,#0,0b \n" \ | ||
| 289 | "1: \n" \ | ||
| 290 | : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \ | ||
| 291 | : "r"(__xg_new), "NPr"(__xg_test) \ | ||
| 292 | : "memory", "cc7", "cc3", "icc3", "icc0" \ | ||
| 293 | ); \ | ||
| 294 | break; \ | ||
| 295 | \ | ||
| 296 | default: \ | ||
| 297 | __xg_orig = 0; \ | ||
| 298 | asm volatile("break"); \ | ||
| 299 | break; \ | ||
| 300 | } \ | ||
| 301 | \ | ||
| 302 | __xg_orig; \ | ||
| 303 | }) | ||
| 304 | |||
| 305 | #else | ||
| 306 | |||
| 307 | extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new); | ||
| 308 | |||
| 309 | #define cmpxchg(ptr, test, new) \ | ||
| 310 | ({ \ | ||
| 311 | __typeof__(ptr) __xg_ptr = (ptr); \ | ||
| 312 | __typeof__(*(ptr)) __xg_orig; \ | ||
| 313 | __typeof__(*(ptr)) __xg_test = (test); \ | ||
| 314 | __typeof__(*(ptr)) __xg_new = (new); \ | ||
| 315 | \ | ||
| 316 | switch (sizeof(__xg_orig)) { \ | ||
| 317 | case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break; \ | ||
| 318 | default: \ | ||
| 319 | __xg_orig = 0; \ | ||
| 320 | asm volatile("break"); \ | ||
| 321 | break; \ | ||
| 322 | } \ | ||
| 323 | \ | ||
| 324 | __xg_orig; \ | ||
| 325 | }) | ||
| 326 | |||
| 327 | #endif | ||
| 328 | |||
| 329 | #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) | 262 | #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) |
| 330 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | 263 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) |
| 331 | 264 | ||
| 332 | #define atomic_add_unless(v, a, u) \ | 265 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 333 | ({ \ | 266 | { |
| 334 | int c, old; \ | 267 | int c, old; |
| 335 | c = atomic_read(v); \ | 268 | c = atomic_read(v); |
| 336 | while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ | 269 | for (;;) { |
| 337 | c = old; \ | 270 | if (unlikely(c == (u))) |
| 338 | c != (u); \ | 271 | break; |
| 339 | }) | 272 | old = atomic_cmpxchg((v), c, c + (a)); |
| 273 | if (likely(old == c)) | ||
| 274 | break; | ||
| 275 | c = old; | ||
| 276 | } | ||
| 277 | return c != (u); | ||
| 278 | } | ||
| 340 | 279 | ||
| 341 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 280 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 342 | 281 | ||
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h index 1166899317..be303b3eef 100644 --- a/include/asm-frv/system.h +++ b/include/asm-frv/system.h | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #define _ASM_SYSTEM_H | 13 | #define _ASM_SYSTEM_H |
| 14 | 14 | ||
| 15 | #include <linux/linkage.h> | 15 | #include <linux/linkage.h> |
| 16 | #include <asm/atomic.h> | ||
| 17 | 16 | ||
| 18 | struct thread_struct; | 17 | struct thread_struct; |
| 19 | 18 | ||
| @@ -197,4 +196,73 @@ extern void free_initmem(void); | |||
| 197 | 196 | ||
| 198 | #define arch_align_stack(x) (x) | 197 | #define arch_align_stack(x) (x) |
| 199 | 198 | ||
| 199 | /*****************************************************************************/ | ||
| 200 | /* | ||
| 201 | * compare and conditionally exchange value with memory | ||
| 202 | * - if (*ptr == test) then orig = *ptr; *ptr = test; | ||
| 203 | * - if (*ptr != test) then orig = *ptr; | ||
| 204 | */ | ||
| 205 | #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS | ||
| 206 | |||
| 207 | #define cmpxchg(ptr, test, new) \ | ||
| 208 | ({ \ | ||
| 209 | __typeof__(ptr) __xg_ptr = (ptr); \ | ||
| 210 | __typeof__(*(ptr)) __xg_orig, __xg_tmp; \ | ||
| 211 | __typeof__(*(ptr)) __xg_test = (test); \ | ||
| 212 | __typeof__(*(ptr)) __xg_new = (new); \ | ||
| 213 | \ | ||
| 214 | switch (sizeof(__xg_orig)) { \ | ||
| 215 | case 4: \ | ||
| 216 | asm volatile( \ | ||
| 217 | "0: \n" \ | ||
| 218 | " orcc gr0,gr0,gr0,icc3 \n" \ | ||
| 219 | " ckeq icc3,cc7 \n" \ | ||
| 220 | " ld.p %M0,%1 \n" \ | ||
| 221 | " orcr cc7,cc7,cc3 \n" \ | ||
| 222 | " sub%I4cc %1,%4,%2,icc0 \n" \ | ||
| 223 | " bne icc0,#0,1f \n" \ | ||
| 224 | " cst.p %3,%M0 ,cc3,#1 \n" \ | ||
| 225 | " corcc gr29,gr29,gr0 ,cc3,#1 \n" \ | ||
| 226 | " beq icc3,#0,0b \n" \ | ||
| 227 | "1: \n" \ | ||
| 228 | : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \ | ||
| 229 | : "r"(__xg_new), "NPr"(__xg_test) \ | ||
| 230 | : "memory", "cc7", "cc3", "icc3", "icc0" \ | ||
| 231 | ); \ | ||
| 232 | break; \ | ||
| 233 | \ | ||
| 234 | default: \ | ||
| 235 | __xg_orig = 0; \ | ||
| 236 | asm volatile("break"); \ | ||
| 237 | break; \ | ||
| 238 | } \ | ||
| 239 | \ | ||
| 240 | __xg_orig; \ | ||
| 241 | }) | ||
| 242 | |||
| 243 | #else | ||
| 244 | |||
| 245 | extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new); | ||
| 246 | |||
| 247 | #define cmpxchg(ptr, test, new) \ | ||
| 248 | ({ \ | ||
| 249 | __typeof__(ptr) __xg_ptr = (ptr); \ | ||
| 250 | __typeof__(*(ptr)) __xg_orig; \ | ||
| 251 | __typeof__(*(ptr)) __xg_test = (test); \ | ||
| 252 | __typeof__(*(ptr)) __xg_new = (new); \ | ||
| 253 | \ | ||
| 254 | switch (sizeof(__xg_orig)) { \ | ||
| 255 | case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break; \ | ||
| 256 | default: \ | ||
| 257 | __xg_orig = 0; \ | ||
| 258 | asm volatile("break"); \ | ||
| 259 | break; \ | ||
| 260 | } \ | ||
| 261 | \ | ||
| 262 | __xg_orig; \ | ||
| 263 | }) | ||
| 264 | |||
| 265 | #endif | ||
| 266 | |||
| 267 | |||
| 200 | #endif /* _ASM_SYSTEM_H */ | 268 | #endif /* _ASM_SYSTEM_H */ |
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h index 5ae6dce1cb..85fd0aa27a 100644 --- a/include/asm-generic/atomic.h +++ b/include/asm-generic/atomic.h | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <asm/types.h> | 11 | #include <asm/types.h> |
| 12 | #include <asm/system.h> | ||
| 13 | 12 | ||
| 14 | /* | 13 | /* |
| 15 | * Suppport for atomic_long_t | 14 | * Suppport for atomic_long_t |
| @@ -123,8 +122,12 @@ static inline long atomic_long_dec_return(atomic_long_t *l) | |||
| 123 | return (long)atomic64_dec_return(v); | 122 | return (long)atomic64_dec_return(v); |
| 124 | } | 123 | } |
| 125 | 124 | ||
| 126 | #define atomic_long_add_unless(l, a, u) \ | 125 | static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u) |
| 127 | atomic64_add_unless((atomic64_t *)(l), (a), (u)) | 126 | { |
| 127 | atomic64_t *v = (atomic64_t *)l; | ||
| 128 | |||
| 129 | return (long)atomic64_add_unless(v, a, u); | ||
| 130 | } | ||
| 128 | 131 | ||
| 129 | #define atomic_long_inc_not_zero(l) atomic64_inc_not_zero((atomic64_t *)(l)) | 132 | #define atomic_long_inc_not_zero(l) atomic64_inc_not_zero((atomic64_t *)(l)) |
| 130 | 133 | ||
| @@ -236,8 +239,12 @@ static inline long atomic_long_dec_return(atomic_long_t *l) | |||
| 236 | return (long)atomic_dec_return(v); | 239 | return (long)atomic_dec_return(v); |
| 237 | } | 240 | } |
| 238 | 241 | ||
| 239 | #define atomic_long_add_unless(l, a, u) \ | 242 | static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u) |
| 240 | atomic_add_unless((atomic_t *)(l), (a), (u)) | 243 | { |
| 244 | atomic_t *v = (atomic_t *)l; | ||
| 245 | |||
| 246 | return (long)atomic_add_unless(v, a, u); | ||
| 247 | } | ||
| 241 | 248 | ||
| 242 | #define atomic_long_inc_not_zero(l) atomic_inc_not_zero((atomic_t *)(l)) | 249 | #define atomic_long_inc_not_zero(l) atomic_inc_not_zero((atomic_t *)(l)) |
| 243 | 250 | ||
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h index 0893511320..ff90c6e3fc 100644 --- a/include/asm-i386/atomic.h +++ b/include/asm-i386/atomic.h | |||
| @@ -219,20 +219,21 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v) | |||
| 219 | * Atomically adds @a to @v, so long as @v was not already @u. | 219 | * Atomically adds @a to @v, so long as @v was not already @u. |
| 220 | * Returns non-zero if @v was not @u, and zero otherwise. | 220 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 221 | */ | 221 | */ |
| 222 | #define atomic_add_unless(v, a, u) \ | 222 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 223 | ({ \ | 223 | { |
| 224 | __typeof__((v)->counter) c, old; \ | 224 | int c, old; |
| 225 | c = atomic_read(v); \ | 225 | c = atomic_read(v); |
| 226 | for (;;) { \ | 226 | for (;;) { |
| 227 | if (unlikely(c == (u))) \ | 227 | if (unlikely(c == (u))) |
| 228 | break; \ | 228 | break; |
| 229 | old = atomic_cmpxchg((v), c, c + (a)); \ | 229 | old = atomic_cmpxchg((v), c, c + (a)); |
| 230 | if (likely(old == c)) \ | 230 | if (likely(old == c)) |
| 231 | break; \ | 231 | break; |
| 232 | c = old; \ | 232 | c = old; |
| 233 | } \ | 233 | } |
| 234 | c != (u); \ | 234 | return c != (u); |
| 235 | }) | 235 | } |
| 236 | |||
| 236 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 237 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 237 | 238 | ||
| 238 | #define atomic_inc_return(v) (atomic_add_return(1,v)) | 239 | #define atomic_inc_return(v) (atomic_add_return(1,v)) |
diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h index b16ad235c7..1fc3b83325 100644 --- a/include/asm-ia64/atomic.h +++ b/include/asm-ia64/atomic.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 16 | 16 | ||
| 17 | #include <asm/intrinsics.h> | 17 | #include <asm/intrinsics.h> |
| 18 | #include <asm/system.h> | ||
| 18 | 19 | ||
| 19 | /* | 20 | /* |
| 20 | * On IA-64, counter must always be volatile to ensure that that the | 21 | * On IA-64, counter must always be volatile to ensure that that the |
| @@ -95,36 +96,38 @@ ia64_atomic64_sub (__s64 i, atomic64_t *v) | |||
| 95 | (cmpxchg(&((v)->counter), old, new)) | 96 | (cmpxchg(&((v)->counter), old, new)) |
| 96 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | 97 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) |
| 97 | 98 | ||
| 98 | #define atomic_add_unless(v, a, u) \ | 99 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 99 | ({ \ | 100 | { |
| 100 | __typeof__(v->counter) c, old; \ | 101 | int c, old; |
| 101 | c = atomic_read(v); \ | 102 | c = atomic_read(v); |
| 102 | for (;;) { \ | 103 | for (;;) { |
| 103 | if (unlikely(c == (u))) \ | 104 | if (unlikely(c == (u))) |
| 104 | break; \ | 105 | break; |
| 105 | old = atomic_cmpxchg((v), c, c + (a)); \ | 106 | old = atomic_cmpxchg((v), c, c + (a)); |
| 106 | if (likely(old == c)) \ | 107 | if (likely(old == c)) |
| 107 | break; \ | 108 | break; |
| 108 | c = old; \ | 109 | c = old; |
| 109 | } \ | 110 | } |
| 110 | c != (u); \ | 111 | return c != (u); |
| 111 | }) | 112 | } |
| 113 | |||
| 112 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 114 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 113 | 115 | ||
| 114 | #define atomic64_add_unless(v, a, u) \ | 116 | static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) |
| 115 | ({ \ | 117 | { |
| 116 | __typeof__(v->counter) c, old; \ | 118 | long c, old; |
| 117 | c = atomic64_read(v); \ | 119 | c = atomic64_read(v); |
| 118 | for (;;) { \ | 120 | for (;;) { |
| 119 | if (unlikely(c == (u))) \ | 121 | if (unlikely(c == (u))) |
| 120 | break; \ | 122 | break; |
| 121 | old = atomic64_cmpxchg((v), c, c + (a)); \ | 123 | old = atomic64_cmpxchg((v), c, c + (a)); |
| 122 | if (likely(old == c)) \ | 124 | if (likely(old == c)) |
| 123 | break; \ | 125 | break; |
| 124 | c = old; \ | 126 | c = old; |
| 125 | } \ | 127 | } |
| 126 | c != (u); \ | 128 | return c != (u); |
| 127 | }) | 129 | } |
| 130 | |||
| 128 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 131 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
| 129 | 132 | ||
| 130 | #define atomic_add_return(i,v) \ | 133 | #define atomic_add_return(i,v) \ |
diff --git a/include/asm-m32r/atomic.h b/include/asm-m32r/atomic.h index f5a7d7301c..3a38ffe4a4 100644 --- a/include/asm-m32r/atomic.h +++ b/include/asm-m32r/atomic.h | |||
| @@ -253,14 +253,21 @@ static __inline__ int atomic_dec_return(atomic_t *v) | |||
| 253 | * Atomically adds @a to @v, so long as it was not @u. | 253 | * Atomically adds @a to @v, so long as it was not @u. |
| 254 | * Returns non-zero if @v was not @u, and zero otherwise. | 254 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 255 | */ | 255 | */ |
| 256 | #define atomic_add_unless(v, a, u) \ | 256 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 257 | ({ \ | 257 | { |
| 258 | int c, old; \ | 258 | int c, old; |
| 259 | c = atomic_read(v); \ | 259 | c = atomic_read(v); |
| 260 | while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ | 260 | for (;;) { |
| 261 | c = old; \ | 261 | if (unlikely(c == (u))) |
| 262 | c != (u); \ | 262 | break; |
| 263 | }) | 263 | old = atomic_cmpxchg((v), c, c + (a)); |
| 264 | if (likely(old == c)) | ||
| 265 | break; | ||
| 266 | c = old; | ||
| 267 | } | ||
| 268 | return c != (u); | ||
| 269 | } | ||
| 270 | |||
| 264 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 271 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 265 | 272 | ||
| 266 | static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t *addr) | 273 | static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t *addr) |
diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h index d5eed64cb8..4915294fea 100644 --- a/include/asm-m68k/atomic.h +++ b/include/asm-m68k/atomic.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | #define __ARCH_M68K_ATOMIC__ | 2 | #define __ARCH_M68K_ATOMIC__ |
| 3 | 3 | ||
| 4 | 4 | ||
| 5 | #include <asm/system.h> /* local_irq_XXX() */ | 5 | #include <asm/system.h> |
| 6 | 6 | ||
| 7 | /* | 7 | /* |
| 8 | * Atomic operations that C can't guarantee us. Useful for | 8 | * Atomic operations that C can't guarantee us. Useful for |
| @@ -170,20 +170,21 @@ static inline void atomic_set_mask(unsigned long mask, unsigned long *v) | |||
| 170 | __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask)); | 170 | __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask)); |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | #define atomic_add_unless(v, a, u) \ | 173 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 174 | ({ \ | 174 | { |
| 175 | int c, old; \ | 175 | int c, old; |
| 176 | c = atomic_read(v); \ | 176 | c = atomic_read(v); |
| 177 | for (;;) { \ | 177 | for (;;) { |
| 178 | if (unlikely(c == (u))) \ | 178 | if (unlikely(c == (u))) |
| 179 | break; \ | 179 | break; |
| 180 | old = atomic_cmpxchg((v), c, c + (a)); \ | 180 | old = atomic_cmpxchg((v), c, c + (a)); |
| 181 | if (likely(old == c)) \ | 181 | if (likely(old == c)) |
| 182 | break; \ | 182 | break; |
| 183 | c = old; \ | 183 | c = old; |
| 184 | } \ | 184 | } |
| 185 | c != (u); \ | 185 | return c != (u); |
| 186 | }) | 186 | } |
| 187 | |||
| 187 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 188 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 188 | 189 | ||
| 189 | /* Atomic operations are already serializing */ | 190 | /* Atomic operations are already serializing */ |
diff --git a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h index 6c4e4b63e4..d5632a305d 100644 --- a/include/asm-m68knommu/atomic.h +++ b/include/asm-m68knommu/atomic.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #ifndef __ARCH_M68KNOMMU_ATOMIC__ | 1 | #ifndef __ARCH_M68KNOMMU_ATOMIC__ |
| 2 | #define __ARCH_M68KNOMMU_ATOMIC__ | 2 | #define __ARCH_M68KNOMMU_ATOMIC__ |
| 3 | 3 | ||
| 4 | #include <asm/system.h> /* local_irq_XXX() */ | 4 | #include <asm/system.h> |
| 5 | 5 | ||
| 6 | /* | 6 | /* |
| 7 | * Atomic operations that C can't guarantee us. Useful for | 7 | * Atomic operations that C can't guarantee us. Useful for |
| @@ -131,14 +131,21 @@ static inline int atomic_sub_return(int i, atomic_t * v) | |||
| 131 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) | 131 | #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) |
| 132 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | 132 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) |
| 133 | 133 | ||
| 134 | #define atomic_add_unless(v, a, u) \ | 134 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 135 | ({ \ | 135 | { |
| 136 | int c, old; \ | 136 | int c, old; |
| 137 | c = atomic_read(v); \ | 137 | c = atomic_read(v); |
| 138 | while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ | 138 | for (;;) { |
| 139 | c = old; \ | 139 | if (unlikely(c == (u))) |
| 140 | c != (u); \ | 140 | break; |
| 141 | }) | 141 | old = atomic_cmpxchg((v), c, c + (a)); |
| 142 | if (likely(old == c)) | ||
| 143 | break; | ||
| 144 | c = old; | ||
| 145 | } | ||
| 146 | return c != (u); | ||
| 147 | } | ||
| 148 | |||
| 142 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 149 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 143 | 150 | ||
| 144 | #define atomic_dec_return(v) atomic_sub_return(1,(v)) | 151 | #define atomic_dec_return(v) atomic_sub_return(1,(v)) |
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h index 6423ffa195..62daa746a9 100644 --- a/include/asm-mips/atomic.h +++ b/include/asm-mips/atomic.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <asm/barrier.h> | 18 | #include <asm/barrier.h> |
| 19 | #include <asm/cpu-features.h> | 19 | #include <asm/cpu-features.h> |
| 20 | #include <asm/war.h> | 20 | #include <asm/war.h> |
| 21 | #include <asm/system.h> | ||
| 21 | 22 | ||
| 22 | typedef struct { volatile int counter; } atomic_t; | 23 | typedef struct { volatile int counter; } atomic_t; |
| 23 | 24 | ||
| @@ -318,14 +319,20 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) | |||
| 318 | * Atomically adds @a to @v, so long as it was not @u. | 319 | * Atomically adds @a to @v, so long as it was not @u. |
| 319 | * Returns non-zero if @v was not @u, and zero otherwise. | 320 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 320 | */ | 321 | */ |
| 321 | #define atomic_add_unless(v, a, u) \ | 322 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 322 | ({ \ | 323 | { |
| 323 | __typeof__((v)->counter) c, old; \ | 324 | int c, old; |
| 324 | c = atomic_read(v); \ | 325 | c = atomic_read(v); |
| 325 | while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ | 326 | for (;;) { |
| 326 | c = old; \ | 327 | if (unlikely(c == (u))) |
| 327 | c != (u); \ | 328 | break; |
| 328 | }) | 329 | old = atomic_cmpxchg((v), c, c + (a)); |
| 330 | if (likely(old == c)) | ||
| 331 | break; | ||
| 332 | c = old; | ||
| 333 | } | ||
| 334 | return c != (u); | ||
| 335 | } | ||
| 329 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 336 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 330 | 337 | ||
| 331 | #define atomic_dec_return(v) atomic_sub_return(1,(v)) | 338 | #define atomic_dec_return(v) atomic_sub_return(1,(v)) |
| @@ -694,14 +701,21 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) | |||
| 694 | * Atomically adds @a to @v, so long as it was not @u. | 701 | * Atomically adds @a to @v, so long as it was not @u. |
| 695 | * Returns non-zero if @v was not @u, and zero otherwise. | 702 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 696 | */ | 703 | */ |
| 697 | #define atomic64_add_unless(v, a, u) \ | 704 | static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) |
| 698 | ({ \ | 705 | { |
| 699 | __typeof__((v)->counter) c, old; \ | 706 | long c, old; |
| 700 | c = atomic_read(v); \ | 707 | c = atomic64_read(v); |
| 701 | while (c != (u) && (old = atomic64_cmpxchg((v), c, c + (a))) != c) \ | 708 | for (;;) { |
| 702 | c = old; \ | 709 | if (unlikely(c == (u))) |
| 703 | c != (u); \ | 710 | break; |
| 704 | }) | 711 | old = atomic64_cmpxchg((v), c, c + (a)); |
| 712 | if (likely(old == c)) | ||
| 713 | break; | ||
| 714 | c = old; | ||
| 715 | } | ||
| 716 | return c != (u); | ||
| 717 | } | ||
| 718 | |||
| 705 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 719 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
| 706 | 720 | ||
| 707 | #define atomic64_dec_return(v) atomic64_sub_return(1,(v)) | 721 | #define atomic64_dec_return(v) atomic64_sub_return(1,(v)) |
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h index 66a0edbb51..e894ee3507 100644 --- a/include/asm-parisc/atomic.h +++ b/include/asm-parisc/atomic.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #define _ASM_PARISC_ATOMIC_H_ | 6 | #define _ASM_PARISC_ATOMIC_H_ |
| 7 | 7 | ||
| 8 | #include <linux/types.h> | 8 | #include <linux/types.h> |
| 9 | #include <asm/system.h> | ||
| 9 | 10 | ||
| 10 | /* | 11 | /* |
| 11 | * Atomic operations that C can't guarantee us. Useful for | 12 | * Atomic operations that C can't guarantee us. Useful for |
| @@ -174,14 +175,21 @@ static __inline__ int atomic_read(const atomic_t *v) | |||
| 174 | * Atomically adds @a to @v, so long as it was not @u. | 175 | * Atomically adds @a to @v, so long as it was not @u. |
| 175 | * Returns non-zero if @v was not @u, and zero otherwise. | 176 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 176 | */ | 177 | */ |
| 177 | #define atomic_add_unless(v, a, u) \ | 178 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 178 | ({ \ | 179 | { |
| 179 | __typeof__((v)->counter) c, old; \ | 180 | int c, old; |
| 180 | c = atomic_read(v); \ | 181 | c = atomic_read(v); |
| 181 | while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ | 182 | for (;;) { |
| 182 | c = old; \ | 183 | if (unlikely(c == (u))) |
| 183 | c != (u); \ | 184 | break; |
| 184 | }) | 185 | old = atomic_cmpxchg((v), c, c + (a)); |
| 186 | if (likely(old == c)) | ||
| 187 | break; | ||
| 188 | c = old; | ||
| 189 | } | ||
| 190 | return c != (u); | ||
| 191 | } | ||
| 192 | |||
| 185 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 193 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 186 | 194 | ||
| 187 | #define atomic_add(i,v) ((void)(__atomic_add_return( ((int)i),(v)))) | 195 | #define atomic_add(i,v) ((void)(__atomic_add_return( ((int)i),(v)))) |
| @@ -283,14 +291,21 @@ atomic64_read(const atomic64_t *v) | |||
| 283 | * Atomically adds @a to @v, so long as it was not @u. | 291 | * Atomically adds @a to @v, so long as it was not @u. |
| 284 | * Returns non-zero if @v was not @u, and zero otherwise. | 292 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 285 | */ | 293 | */ |
| 286 | #define atomic64_add_unless(v, a, u) \ | 294 | static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) |
| 287 | ({ \ | 295 | { |
| 288 | __typeof__((v)->counter) c, old; \ | 296 | long c, old; |
| 289 | c = atomic64_read(v); \ | 297 | c = atomic64_read(v); |
| 290 | while (c != (u) && (old = atomic64_cmpxchg((v), c, c + (a))) != c) \ | 298 | for (;;) { |
| 291 | c = old; \ | 299 | if (unlikely(c == (u))) |
| 292 | c != (u); \ | 300 | break; |
| 293 | }) | 301 | old = atomic64_cmpxchg((v), c, c + (a)); |
| 302 | if (likely(old == c)) | ||
| 303 | break; | ||
| 304 | c = old; | ||
| 305 | } | ||
| 306 | return c != (u); | ||
| 307 | } | ||
| 308 | |||
| 294 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 309 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
| 295 | 310 | ||
| 296 | #endif /* CONFIG_64BIT */ | 311 | #endif /* CONFIG_64BIT */ |
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h index 438a7fcfba..c44810b9d3 100644 --- a/include/asm-powerpc/atomic.h +++ b/include/asm-powerpc/atomic.h | |||
| @@ -11,6 +11,7 @@ typedef struct { volatile int counter; } atomic_t; | |||
| 11 | #include <linux/compiler.h> | 11 | #include <linux/compiler.h> |
| 12 | #include <asm/synch.h> | 12 | #include <asm/synch.h> |
| 13 | #include <asm/asm-compat.h> | 13 | #include <asm/asm-compat.h> |
| 14 | #include <asm/system.h> | ||
| 14 | 15 | ||
| 15 | #define ATOMIC_INIT(i) { (i) } | 16 | #define ATOMIC_INIT(i) { (i) } |
| 16 | 17 | ||
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index 738943584c..56abe5e9e1 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | 6 | ||
| 7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
| 8 | 8 | ||
| 9 | #include <asm/atomic.h> | ||
| 10 | #include <asm/hw_irq.h> | 9 | #include <asm/hw_irq.h> |
| 11 | 10 | ||
| 12 | /* | 11 | /* |
diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h index c3feb3af2c..3fb4e1f7f1 100644 --- a/include/asm-sparc64/atomic.h +++ b/include/asm-sparc64/atomic.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #define __ARCH_SPARC64_ATOMIC__ | 9 | #define __ARCH_SPARC64_ATOMIC__ |
| 10 | 10 | ||
| 11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
| 12 | #include <asm/system.h> | ||
| 12 | 13 | ||
| 13 | typedef struct { volatile int counter; } atomic_t; | 14 | typedef struct { volatile int counter; } atomic_t; |
| 14 | typedef struct { volatile __s64 counter; } atomic64_t; | 15 | typedef struct { volatile __s64 counter; } atomic64_t; |
| @@ -73,40 +74,42 @@ extern int atomic64_sub_ret(int, atomic64_t *); | |||
| 73 | #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) | 74 | #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) |
| 74 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | 75 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) |
| 75 | 76 | ||
| 76 | #define atomic_add_unless(v, a, u) \ | 77 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 77 | ({ \ | 78 | { |
| 78 | __typeof__((v)->counter) c, old; \ | 79 | int c, old; |
| 79 | c = atomic_read(v); \ | 80 | c = atomic_read(v); |
| 80 | for (;;) { \ | 81 | for (;;) { |
| 81 | if (unlikely(c == (u))) \ | 82 | if (unlikely(c == (u))) |
| 82 | break; \ | 83 | break; |
| 83 | old = atomic_cmpxchg((v), c, c + (a)); \ | 84 | old = atomic_cmpxchg((v), c, c + (a)); |
| 84 | if (likely(old == c)) \ | 85 | if (likely(old == c)) |
| 85 | break; \ | 86 | break; |
| 86 | c = old; \ | 87 | c = old; |
| 87 | } \ | 88 | } |
| 88 | likely(c != (u)); \ | 89 | return c != (u); |
| 89 | }) | 90 | } |
| 91 | |||
| 90 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 92 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 91 | 93 | ||
| 92 | #define atomic64_cmpxchg(v, o, n) \ | 94 | #define atomic64_cmpxchg(v, o, n) \ |
| 93 | ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) | 95 | ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) |
| 94 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | 96 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) |
| 95 | 97 | ||
| 96 | #define atomic64_add_unless(v, a, u) \ | 98 | static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) |
| 97 | ({ \ | 99 | { |
| 98 | __typeof__((v)->counter) c, old; \ | 100 | long c, old; |
| 99 | c = atomic64_read(v); \ | 101 | c = atomic64_read(v); |
| 100 | for (;;) { \ | 102 | for (;;) { |
| 101 | if (unlikely(c == (u))) \ | 103 | if (unlikely(c == (u))) |
| 102 | break; \ | 104 | break; |
| 103 | old = atomic64_cmpxchg((v), c, c + (a)); \ | 105 | old = atomic64_cmpxchg((v), c, c + (a)); |
| 104 | if (likely(old == c)) \ | 106 | if (likely(old == c)) |
| 105 | break; \ | 107 | break; |
| 106 | c = old; \ | 108 | c = old; |
| 107 | } \ | 109 | } |
| 108 | likely(c != (u)); \ | 110 | return c != (u); |
| 109 | }) | 111 | } |
| 112 | |||
| 110 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 113 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
| 111 | 114 | ||
| 112 | /* Atomic operations are already serializing */ | 115 | /* Atomic operations are already serializing */ |
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h index 80e4fdbe22..19e0c607b5 100644 --- a/include/asm-x86_64/atomic.h +++ b/include/asm-x86_64/atomic.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #define __ARCH_X86_64_ATOMIC__ | 2 | #define __ARCH_X86_64_ATOMIC__ |
| 3 | 3 | ||
| 4 | #include <asm/alternative.h> | 4 | #include <asm/alternative.h> |
| 5 | #include <asm/system.h> | ||
| 5 | 6 | ||
| 6 | /* atomic_t should be 32 bit signed type */ | 7 | /* atomic_t should be 32 bit signed type */ |
| 7 | 8 | ||
| @@ -403,20 +404,21 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *v) | |||
| 403 | * Atomically adds @a to @v, so long as it was not @u. | 404 | * Atomically adds @a to @v, so long as it was not @u. |
| 404 | * Returns non-zero if @v was not @u, and zero otherwise. | 405 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 405 | */ | 406 | */ |
| 406 | #define atomic_add_unless(v, a, u) \ | 407 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 407 | ({ \ | 408 | { |
| 408 | __typeof__((v)->counter) c, old; \ | 409 | int c, old; |
| 409 | c = atomic_read(v); \ | 410 | c = atomic_read(v); |
| 410 | for (;;) { \ | 411 | for (;;) { |
| 411 | if (unlikely(c == (u))) \ | 412 | if (unlikely(c == (u))) |
| 412 | break; \ | 413 | break; |
| 413 | old = atomic_cmpxchg((v), c, c + (a)); \ | 414 | old = atomic_cmpxchg((v), c, c + (a)); |
| 414 | if (likely(old == c)) \ | 415 | if (likely(old == c)) |
| 415 | break; \ | 416 | break; |
| 416 | c = old; \ | 417 | c = old; |
| 417 | } \ | 418 | } |
| 418 | c != (u); \ | 419 | return c != (u); |
| 419 | }) | 420 | } |
| 421 | |||
| 420 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 422 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 421 | 423 | ||
| 422 | /** | 424 | /** |
| @@ -428,20 +430,21 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *v) | |||
| 428 | * Atomically adds @a to @v, so long as it was not @u. | 430 | * Atomically adds @a to @v, so long as it was not @u. |
| 429 | * Returns non-zero if @v was not @u, and zero otherwise. | 431 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 430 | */ | 432 | */ |
| 431 | #define atomic64_add_unless(v, a, u) \ | 433 | static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) |
| 432 | ({ \ | 434 | { |
| 433 | __typeof__((v)->counter) c, old; \ | 435 | long c, old; |
| 434 | c = atomic64_read(v); \ | 436 | c = atomic64_read(v); |
| 435 | for (;;) { \ | 437 | for (;;) { |
| 436 | if (unlikely(c == (u))) \ | 438 | if (unlikely(c == (u))) |
| 437 | break; \ | 439 | break; |
| 438 | old = atomic64_cmpxchg((v), c, c + (a)); \ | 440 | old = atomic64_cmpxchg((v), c, c + (a)); |
| 439 | if (likely(old == c)) \ | 441 | if (likely(old == c)) |
| 440 | break; \ | 442 | break; |
| 441 | c = old; \ | 443 | c = old; |
| 442 | } \ | 444 | } |
| 443 | c != (u); \ | 445 | return c != (u); |
| 444 | }) | 446 | } |
| 447 | |||
| 445 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 448 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
| 446 | 449 | ||
| 447 | /* These are x86-specific, used by some header files */ | 450 | /* These are x86-specific, used by some header files */ |
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h index 5c26720210..b3b23540f1 100644 --- a/include/asm-xtensa/atomic.h +++ b/include/asm-xtensa/atomic.h | |||
| @@ -234,14 +234,21 @@ static inline int atomic_sub_return(int i, atomic_t * v) | |||
| 234 | * Atomically adds @a to @v, so long as it was not @u. | 234 | * Atomically adds @a to @v, so long as it was not @u. |
| 235 | * Returns non-zero if @v was not @u, and zero otherwise. | 235 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 236 | */ | 236 | */ |
| 237 | #define atomic_add_unless(v, a, u) \ | 237 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
| 238 | ({ \ | 238 | { |
| 239 | int c, old; \ | 239 | int c, old; |
| 240 | c = atomic_read(v); \ | 240 | c = atomic_read(v); |
| 241 | while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ | 241 | for (;;) { |
| 242 | c = old; \ | 242 | if (unlikely(c == (u))) |
| 243 | c != (u); \ | 243 | break; |
| 244 | }) | 244 | old = atomic_cmpxchg((v), c, c + (a)); |
| 245 | if (likely(old == c)) | ||
| 246 | break; | ||
| 247 | c = old; | ||
| 248 | } | ||
| 249 | return c != (u); | ||
| 250 | } | ||
| 251 | |||
| 245 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 252 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
| 246 | 253 | ||
| 247 | static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) | 254 | static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) |
