If someone wants to use xchg(), cmpxchg() and their variants, linux/atomic.h should be included rather than asm/cmpxchg.h, unless the code is in arch/* and can take care of itself.
"compare and swap" atomically:
1) Compares "old" with the value currently at "mem".
2) If they are equal, "new" is written to "mem".
3) Regardless, the current value at "mem" is returned.
include/asm-generic/atomic.h
#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v)))
#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
相同的是两者都是返回 ->counter 的原值
不同的是 atomic_xchg 直接用 v 覆盖原值,不考虑任何条件;
而 atomic_cmpxchg 只有在 old == &((v)->counter) 的时候才用 new 覆盖原值