SylixOS armv8 原子操作

在SylixOS 中 armv8 原子操作分为32位和64位。

首先介绍32位

#define ATOMIC_OP_RETURN(op, c_op, asm_op)                                  \
static LW_INLINE INT  archAtomic##op (INT  i, atomic_t  *v)                 \
{                                                                           \
    ULONG   ulTemp;                                                         \
    INT     iResult;                                                        \
                                                                            \
    ARM_PREFETCH_W(&v->counter);                                            \
                                                                            \
    __asm__ __volatile__(                                                   \
        "1: ldxr            %w0, %2         \n"                             \
        "   " #asm_op "     %w0, %w0, %w3   \n"                             \
        "   stlxr           %w1, %w0, %2    \n"                             \
        "   cbnz            %w1, 1b         \n"                             \
        "   dmb ish"                                                        \
            : "=&r" (iResult), "=&r" (ulTemp), "+Q" (v->counter)            \
            : "Ir" (i)                                                      \
            : "memory");                                                    \
                                                                            \
    return  (iResult);                                                      \
}

ATOMIC_OP_RETURN(Add,  +=,  add)
ATOMIC_OP_RETURN(Sub,  -=,  sub)
ATOMIC_OP_RETURN(And,  &=,  and)
ATOMIC_OP_RETURN(Or,   |=,  orr)
ATOMIC_OP_RETURN(Xor,  ^=,  eor)

原子操作和自旋锁增加代码基本一致,不同的是自旋锁只用到了add。 首先是ldxr命令,此命令是加载内存值到寄存器。这里说是32位数加减,和64位主要区别在于%w0 在armv8中规定x 代表寄存器64位,w代表32位寄存器。看armasm用户知道手册

对ldxr的介绍 如下图

ldxr命令保证对加载时候是原子操作。根据代码的含义是将v->counter中的值加载到iResult中。“asm_op” 根据原子操作的不同可能是add,sub,and,orr等。最后是执行stlxr命令,此命令是将数据写入到内存中。看armasm 用户指导手册对其介绍如下:

该命令也是支持32位和64位,在原子操作32位时使用的W1 ,W0

。根据代码的还难以stlxr首先将iResult写入到v->counter中。stlxr会把写入失败或者成功标志位写入到w1(ulTemp)中。cbnz命令就是判断这个标志位(ulTmep)来判断是否写入成功,如果写入失败返回到1:处重新开始执行代码。

在最后保证操作全部完成加入了 dmb ish 这个命令,dmb是arm中内存屏障的,前面的写入操作全部完成。

原子操作64位和32位完全一样,不同的是没用使用W

#define ATOMIC64_OP_RETURN(op, c_op, asm_op)                                \
static LW_INLINE INT64  archAtomic64##op (INT64  i, atomic64_t  *v)         \
{                                                                           \
    ULONG   ulTemp;                                                         \
    INT64   i64Result;                                                      \
                                                                            \
    ARM_PREFETCH_W(&v->counter);                                            \
                                                                            \
    __asm__ __volatile__(                                                   \
        "1: ldxr            %0, %2          \n"                             \
        "   " #asm_op "     %0, %0, %3      \n"                             \
        "   stlxr           %w1, %0, %2     \n"                             \
        "   cbnz            %w1, 1b         \n"                             \
        "   dmb ish"                                                        \
            : "=&r" (i64Result), "=&r" (ulTemp), "+Q" (v->counter)          \
            : "Ir" (i)                                                      \
            : "memory");                                                    \
                                                                            \
    return  (i64Result);                                                    \
}

ATOMIC64_OP_RETURN(Add,  +=,  add)
ATOMIC64_OP_RETURN(Sub,  -=,  sub)
ATOMIC64_OP_RETURN(And,  &=,  and)
ATOMIC64_OP_RETURN(Or,   |=,  orr)
ATOMIC64_OP_RETURN(Xor,  ^=,  eor)

参考文档《DUI0801C_armasm_user_guide.pdf》

参考代码:http://www.sylixos.com/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值