type __sync_xor_and_fetch (type *ptr, type value);
type __sync_nand_and_fetch (type *ptr, type value);
2.dpdk提供的原子操作
static inline int rte_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp, uint16_t src);
static inline uint16_t rte_atomic16_exchange(volatile uint16_t *dst, uint16_t val);
static inline void rte_atomic16_init(rte_atomic16_t *v)
static inline int16_t rte_atomic16_read(const rte_atomic16_t *v)
static inline void rte_atomic16_set(rte_atomic16_t *v, int16_t new_value)
static inline void rte_atomic16_add(rte_atomic16_t *v, int16_t inc)
static inline void rte_atomic16_sub(rte_atomic16_t *v, int16_t dec)
static inline void rte_atomic16_inc(rte_atomic16_t *v);
static inline void rte_atomic16_dec(rte_atomic16_t *v);
static inline int16_t rte_atomic16_add_return(rte_atomic16_t *v, int16_t inc)
static inline int16_t rte_atomic16_sub_return(rte_atomic16_t *v, int16_t dec)
static inline int rte_atomic16_inc_and_test(rte_atomic16_t *v);
static inline int rte_atomic16_dec_and_test(rte_atomic16_t *v);
static inline int rte_atomic16_test_and_set(rte_atomic16_t *v);
static inline void rte_atomic16_clear(rte_atomic16_t *v)
dpdk提供了16、 32和64位的原子操作API,主要实现原理是使用了**LOCK指令+CMPXCHG指令**。
对于LOCK指令前缀的总线锁,早期CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前
缀“LOCK”(这个前缀表示锁总线),经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指
令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。
随着处理器的发展,对LOCK前缀的实现也在不断进行着性能改善。最近几代处理器中已经支持新的锁技术,若当前访问的内存已经被处理器缓存,LOCK#不会被触发,会用锁缓存的方式代替。这样处理原子操作的开销就在这些特定场景下进一步降低。
CMPXCHG这条指令,它的语义是比较并交换操作数(CAS,Compare And Set)。而用XCHG类的指令做内存操作,处理器会自动地遵循LOCK的语义,可见该指令是一条原子的CAS单指令操作。
源码如下
static inline int
rte_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp, uint64_t src)
{
uint8_t res;
asm volatile(
MPLOCKED
"cmpxchgq %[src], %[dst];"
"sete %[res];"
: [res] "=a" (res), /* output */
[dst] "=m" (*dst)
: [src] "r" (src), /* input */
"a" (exp),
"m" (*dst)
: "memory"); /* no-clobber list */
return res;
}
本人从dpdk移植了锁实现到自己的github里面 有兴趣的可以参考.
3.linux kernel
内核的原子锁实现主要在x86结构里面,使用的是lock指令+内存屏障原理
提供的api基本一致,都是分为16、32、64位三种api。