openGauss源码解析(81)

openGauss源码解析:事务机制源码解析(12)

5.3.5 无锁原子操作

openGauss封装了32、64、128的原子操作,主要用于取代自旋锁,实现简单变量的原子更新操作。

(1) gs_atomic_add_32:32位原子加,并且返回加之后的值。对应的代码如下:

static inline int32 gs_atomic_add_32(volatile int32* ptr, int32 inc)

{

return __sync_fetch_and_add(ptr, inc) + inc;

}

(2) gs_atomic_add_64:64位原子加,并且返回加之后的值。对应的代码如下:

static inline int64 gs_atomic_add_64(int64* ptr, int64 inc)

{

return __sync_fetch_and_add(ptr, inc) + inc;

}

(3) gs_compare_and_swap_32:32位CAS操作,如果dest在更新前没有被更新,则将newval写到dest地址。dest地址的值没有被更新,就返回true;否则返回false。对应的代码如下:

static inline bool gs_compare_and_swap_32(int32* dest, int32 oldval, int32 newval)

{

if (oldval == newval)

return true;

volatile bool res = __sync_bool_compare_and_swap(dest, oldval, newval);

return res;

}

(4) gs_compare_and_swap_64:64位CAS操作,如果dest在更新前没有被更新,则将newval写到dest地址。dest地址的值没有被更新,就返回true;否则返回false。对应的代码如下:

static inline bool gs_compare_and_swap_64(int64* dest, int64 oldval, int64 newval)

{

if (oldval == newval)

return true;

return __sync_bool_compare_and_swap(dest, oldval, newval);

}

(5) arm_compare_and_swap_u128:openGauss提供跨平台的128位CAS操作,在ARM平台下,使用单独的指令集汇编了128位原子操作,用于提升内核测锁并发的性能,详情可以参考下一小结。对应的代码如下:

static inline uint128_u arm_compare_and_swap_u128(volatile uint128_u* ptr, uint128_u oldval, uint128_u newval)

{

#ifdef __ARM_LSE

return __lse_compare_and_swap_u128(ptr, oldval, newval);

#else

return __excl_compare_and_swap_u128(ptr, oldval, newval);

#endif

}

#endif

(6) atomic_compare_and_swap_u128:128位CAS操作,如果dest地址的值在更新前没有被其他线程更新,则将newval写到dest地址。dest地址的值没有被更新,就返回新值;否则返回被别人更新后的值。需要注意必须由上层的调用者保证传入的参数是128位对齐的。对应的代码如下:

static inline uint128_u atomic_compare_and_swap_u128(

volatile uint128_u* ptr,

uint128_u oldval = uint128_u{0},

uint128_u newval = uint128_u{0})

{

#ifdef __aarch64__

return arm_compare_and_swap_u128(ptr, oldval, newval);

#else

uint128_u ret;

ret.u128 = __sync_val_compare_and_swap(&ptr->u128, oldval.u128, newval.u128);

return ret;

#endif

}

posted @ 2024-04-30 10:09  openGauss-bot  阅读(5)  评论(0编辑  收藏  举报