我需要在汇编语言中自己编写__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。返回之前在内存中的值。
答案 0 :(得分:4)
此代码段使用xadd
的原子版:交换并添加:它以原子方式将右操作数添加到左侧(此处为内存),并在右操作数中返回内存中的初始值。之前的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
属性,在这种情况下我发现它们不相关。