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

atomic.h: add atomic64 cmpxchg, xchg and add_unless to x86_64

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Mathieu Desnoyers and committed by
Linus Torvalds
79d365a3 2549c858

+32 -4
+32 -4
include/asm-x86_64/atomic.h
··· 375 375 long __i = i; 376 376 __asm__ __volatile__( 377 377 LOCK_PREFIX "xaddq %0, %1;" 378 - :"=r"(i) 379 - :"m"(v->counter), "0"(i)); 378 + :"+r" (i), "+m" (v->counter) 379 + : : "memory"); 380 380 return i + __i; 381 381 } 382 382 ··· 388 388 #define atomic64_inc_return(v) (atomic64_add_return(1,v)) 389 389 #define atomic64_dec_return(v) (atomic64_sub_return(1,v)) 390 390 391 - #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) 391 + #define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) 392 + #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) 393 + 394 + #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) 392 395 #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) 393 396 394 397 /** ··· 405 402 */ 406 403 #define atomic_add_unless(v, a, u) \ 407 404 ({ \ 408 - int c, old; \ 405 + __typeof__((v)->counter) c, old; \ 409 406 c = atomic_read(v); \ 410 407 for (;;) { \ 411 408 if (unlikely(c == (u))) \ ··· 418 415 c != (u); \ 419 416 }) 420 417 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) 418 + 419 + /** 420 + * atomic64_add_unless - add unless the number is a given value 421 + * @v: pointer of type atomic64_t 422 + * @a: the amount to add to v... 423 + * @u: ...unless v is equal to u. 424 + * 425 + * Atomically adds @a to @v, so long as it was not @u. 426 + * Returns non-zero if @v was not @u, and zero otherwise. 427 + */ 428 + #define atomic64_add_unless(v, a, u) \ 429 + ({ \ 430 + __typeof__((v)->counter) c, old; \ 431 + c = atomic64_read(v); \ 432 + for (;;) { \ 433 + if (unlikely(c == (u))) \ 434 + break; \ 435 + old = atomic64_cmpxchg((v), c, c + (a)); \ 436 + if (likely(old == c)) \ 437 + break; \ 438 + c = old; \ 439 + } \ 440 + c != (u); \ 441 + }) 442 + #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) 421 443 422 444 /* These are x86-specific, used by some header files */ 423 445 #define atomic_clear_mask(mask, addr) \