最近将一个项目从 GCC 4 downgrade 到 GCC 3,其中有部分代码用到 GCC 4.1.2 开始提供的 __sync__ 系列原子操作函数:

type __sync_fetch_and_add (type *ptr, type value, ...)
type __sync_fetch_and_sub (type *ptr, type value, ...)
type __sync_fetch_and_or (type *ptr, type value, ...)
type __sync_fetch_and_and (type *ptr, type value, ...)
type __sync_fetch_and_xor (type *ptr, type value, ...)
type __sync_fetch_and_nand (type *ptr, type value, ...)


type __sync_add_and_fetch (type *ptr, type value, ...)
type __sync_sub_and_fetch (type *ptr, type value, ...)
type __sync_or_and_fetch (type *ptr, type value, ...)
type __sync_and_and_fetch (type *ptr, type value, ...)
type __sync_xor_and_fetch (type *ptr, type value, ...)
type __sync_nand_and_fetch (type *ptr, type value, ...)

这些函数在 GCC3 中没有,需要改写,一时找不到替代,于是开始思考,原子操作无非是指令级别的有序不可被中断的执行,那么汇编肯定是可以做到这些的,于是寻找 GCC 联合汇编相关的材料,再进行一些实验,改写是可行的,如下提供三种原子操作的混编实现(自增,自减,以及 cas, centos 6 & 7下测试可行,64位系统,32位系统指令+l):

compare_and_swap:

static inline bool compare_and_set (unsigned long *thevalue, unsigned long oldvalue, unsigned long newvalue)
{
    unsigned long prev;
    asm volatile(
        "lock; cmpxchg %1, %2;"
        : "=a"(prev)
        : "q"(newvalue), "m"(*thevalue), "a"(oldvalue)
        : "memory"
    );
    return prev == oldvalue;
}

fetch_and_add:

int a = 1;
__asm__ __volatile__ ("lock; incl %0\n\t" : "+m" (a) :: "memory");

fetch_and_sub:

int a = 1;
__asm__ __volatile__ ("lock; decl %0\n\t" : "+m" (a) :: "memory");

GCC 内联汇编,可参考简介:Linux中x86的内联汇编,更深入的资料可自行搜索