简体   繁体   English

如何基于Linux GCC以汇编语言实现__sync_fetch_and_sub原子操作

[英]How to implement the __sync_fetch_and_sub atomic operation in assembly language based on Linux GCC

I need to write the implementation of __sync_fetch_and_sub atomic operation myself in assembly language based on GCC 3.4 which doesn't have __sync_fetch_and_sub builtins. 我需要使用基于GCC 3.4的汇编语言编写自己的__sync_fetch_and_sub原子操作的实现, __sync_fetch_and_sub语言没有内置__sync_fetch_and_sub But I know little about assembly. 但是我对组装一无所知。

Can anyone help me? 谁能帮我? Any help would be greatly appreciated!! 任何帮助将不胜感激!!

here is the implementation of __sync_fetch_and_add 这是__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) is to atomically add a_count to the variable pointed by ptr. __sync_fetch_and_add(int *ptr, int a_count)是将a_count自动添加到ptr指向的变量中。 return the value that had previously in memory. 返回以前在内存中的值。

__sync_fetch_and_sub(int *ptr, int a_count) is to atomically subtract a_count from the variable pointed by ptr. __sync_fetch_and_sub(int *ptr, int a_count)是从ptr指向的变量中自动减去a_count。 return the value that had previously in memory. 返回以前在内存中的值。

This snippet uses the atomic version of xadd : exchange and add: it atomically add the right operand to the left (here to memory) and returns the initial value in memory in the right operand. 此代码段使用xadd的原子版本:exchange和add:将原子的右边操作数原子地添加到左边(这里是内存),并在右边的操作数中返回内存中的初始值。 The lock statement before ensure the atomicity of the operation. 之前的lock语句可确保操作的原子性。

However, gcc uses the AT&T notation, so the left and right arguments in this explanation (taken from the intel manual) are reversed. 但是,gcc使用AT&T表示法,因此该解释中的左右参数(取自intel手册)是相反的。

As there is no xsub instruction on intel architecture, the easiest way to emulate this is first to take the opposite of the number you want to substract and then add/exchange it atomically: 由于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;
}

I also remove the unsigned properties, I don't find they are relevant in this case. 我还删除了 unsigned属性,在这种情况下我发现它们不相关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM