diff options
| author | Nick Piggin <npiggin@suse.de> | 2006-03-23 06:01:02 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-23 10:38:17 -0500 |
| commit | 0b2fcfdb8b4e7e379192f24ea2203163ddf5df1d (patch) | |
| tree | 1f3995e41ab12ff76e737389e0b59a40c0c73668 /include/asm-x86_64 | |
| parent | 713729e8b993cb880225e2ced50a3f5ac05c2b3f (diff) | |
[PATCH] atomic: add_unless cmpxchg optimise
Without branch hints, the very unlikely chance of the loop repeating due to
cmpxchg failure is unrolled with gcc-4 that I have tested.
Improve this for architectures with a native cas/cmpxchg. llsc archs
should try to implement this natively.
Signed-off-by: Nick Piggin <npiggin@suse.de>
Cc: Andi Kleen <ak@muc.de>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/asm-x86_64')
| -rw-r--r-- | include/asm-x86_64/atomic.h | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h index 4b5cd553e772..cecbf7baa6aa 100644 --- a/include/asm-x86_64/atomic.h +++ b/include/asm-x86_64/atomic.h | |||
| @@ -405,8 +405,14 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *v) | |||
| 405 | ({ \ | 405 | ({ \ |
| 406 | int c, old; \ | 406 | int c, old; \ |
| 407 | c = atomic_read(v); \ | 407 | c = atomic_read(v); \ |
| 408 | while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ | 408 | for (;;) { \ |
| 409 | if (unlikely(c == (u))) \ | ||
| 410 | break; \ | ||
| 411 | old = atomic_cmpxchg((v), c, c + (a)); \ | ||
| 412 | if (likely(old == c)) \ | ||
| 413 | break; \ | ||
| 409 | c = old; \ | 414 | c = old; \ |
| 415 | } \ | ||
| 410 | c != (u); \ | 416 | c != (u); \ |
| 411 | }) | 417 | }) |
| 412 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 418 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
