diff options
Diffstat (limited to 'include/asm-xtensa')
-rw-r--r-- | include/asm-xtensa/atomic.h | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h index 5c2672021068..b3b23540f14d 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) |