3

我需要__sync_fetch_and_sub自己用汇编语言编写原子操作的实现,它基于没有内置函数的 GCC 3.4 __sync_fetch_and_sub。但我对组装知之甚少。

谁能帮我?任何帮助将不胜感激!!

这里是实现__sync_fetch_and_add

inline unsigned int __sync_fetch_and_add(volatile unsigned int* p, unsigned int incr)
{

    unsigned int result;
    __asm__ _volatile_ ("lock; xadd %0, %1" :
            "=r"(result), "=m"(*p):
            "0"(incr), "m"(*p) :
            "memory");
    return result;
}

__sync_fetch_and_add(int *ptr, int a_count)就是将 a_count 原子地添加到 ptr 指向的变量中。返回之前在内存中的值。

__sync_fetch_and_sub(int *ptr, int a_count)就是从ptr指向的变量中原子地减去a_count。返回之前在内存中的值。

4

1 回答 1

5

此代码段使用原子版本的xadd: exchange 和 add:它以原子方式将右操作数添加到左侧(此处为内存),并在右操作数中返回内存中的初始值。前面的lock语句保证了操作的原子性。

但是,gcc 使用 AT&T 表示法,所以这个解释(取自 intel 手册)中的左右参数是相反的。

由于没有xsub关于英特尔架构的说明,因此最简单的模拟方法是首先取与您要减去的数字相反的数字,然后自动添加/交换它:

inline unsigned int __sync_fetch_and_sub(volatile unsigned int* p,
    unsigned int decr)
{
    unsigned int result;

    __asm__ __volatile__ ("lock; xadd %0, %1"
            :"=r"(result), "=m"(*p)
            :"0"(-decr), "m"(*p)
            :"memory");
    return result;
}

我还删除了这些unsigned属性,我发现它们在这种情况下不相关。

于 2013-01-10T05:44:18.690 回答