OpenSBI atomic_xchg函数分析

atomic_xchg函数原型

long atomic_xchg(atomic_t *atom, long newval)
{
    /* Atomically set new value and return old value. */
#ifdef __riscv_atomic
    return axchg(&atom->counter, newval);
#else
    return xchg(&atom->counter, newval);
#endif
}

axchg宏定义

#define axchg(ptr, x)                               \
    ({                                  \
        __typeof__(*(ptr)) _x_ = (x);                   \
        (__typeof__(*(ptr))) __axchg((ptr), _x_, sizeof(*(ptr)));   \
    })

__axchg宏定义

这里是linux内核中惯用套路,使用typeof来获取参数的类型,并使用sizeof来获取参数的size,根据size区分使用汇编指令

#define __axchg(ptr, new, size)                         \
    ({                                  \
        __typeof__(ptr) __ptr = (ptr);                  \
        __typeof__(new) __new = (new);                  \
        __typeof__(*(ptr)) __ret;                   \
        switch (size) {                         \
        case 4:                             \
            __asm__ __volatile__ (                  \
                "   amoswap.w.aqrl %0, %2, %1\n"        \
                : "=r" (__ret), "+A" (*__ptr)           \
                : "r" (__new)                   \
                : "memory");                    \
            break;                          \
        case 8:                             \
            __asm__ __volatile__ (                  \
                "   amoswap.d.aqrl %0, %2, %1\n"        \
                : "=r" (__ret), "+A" (*__ptr)           \
                : "r" (__new)                   \
                : "memory");                    \
            break;                          \
        default:                            \
            break;                          \
        }                               \
        __ret;                              \
    })

atomic_t定义

typedef struct {
    volatile long counter;
} atomic_t;

amoswap.d 含义:原子双字交换指令

amoswap.d  rd, rs2, (rs1)

将内存中地址为 x[rs1]中的双字记为 t,把这个双字变为 x[rs2]的值,把 x[rd]设为 t。

aqrl 含义:aq表示acquire,rl表示release

表示在此指令加上了内存屏障,前后的加载存储指令不能越过屏障

amoswap.d.aqrl %0, %2, %1 汇编

%0 :ret

%1 : *__ptr

%2 :_new 

即等同于amoswap.d.aqrl  ret, _new ,*__ptr  <==> amoswap.d.aqrl  ret, new, atom->counter

就是将new赋值给atom->counter,然后将旧值赋值给ret

long atomic_xchg(atomic_t *atom, long newval)

含义: 将newval值赋值给atom->counter, 返回atom->counter的旧值,并且还带有加载获取、存储释放的特性。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byd yes

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值