ARM V8 base instruction -- ldrx stxr

本文详细剖析了自旋锁在底层如何通过预取CPU缓存、独占读写操作和循环重试机制来确保线程同步。通过`__ll_sc_atomic_add_return_acquire`和`__ll_sc_atomic_fetch_or_release`两个函数实例,揭示了其核心原理和关键技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自旋锁的底层实现。    

static inline int
    __ll_sc_atomic_add_return_acquire(int i, atomic_t *v)
    {
        unsigned long tmp;
        int result;
     
        asm volatile(
    "       // 将v->counter预取到CPU缓存\n"                                   \
    "    prfm    pstl1strm, %2\n"                    \
    "       // 将v->counter独占的读入result中\n"                              \
    "1:    ldaxr    %w0, %2\n"                            \
    "       // result = result + i\n"                                       \
    "    add    %w0, %w0, %w3\n"                                \
    "       // 将result的值独占的存入v->counter中\n"                           \
    "       // 如果存入时独占标记被清除则将tmp置1\n"                             \
    "    stxr    %w1, %w0, %2\n"                            \
    "       // 如果tmp被置1则从头再次执行一遍\n"                                \
    "    cbnz    %w1, 1b\n"                        \
            )                                \
        : "=&r" (result), "=&r" (tmp), "+Q" (v->counter)        \
        : __stringify(I) "r" (i)                        \
        : "memory");                                    \
                                        \
        return result;                            \
    }

    static inline int                            \
    __ll_sc_atomic_fetch_or_release(int i, atomic_t *v)            \
    {                                    \
        unsigned long tmp;                        \
        int val, result;                        \
                                        \
        asm volatile(                                            \
    "       // 将v->counter预取到CPU缓存\n"                                   \
    "    prfm    pstl1strm, %3\n"                    \
    "       // 将v->counter独占的读入result中\n"                              \
    "1:    ldxr    %w0, %3\n"                            \
    "       // val = result | i\n"                                          \
    "    orr    %w1, %w0, %w4\n"                        \
    "       // 将val的值独占的存入v->counter中\n"                              \
    "       // 如果存入时独占标记被清除则将tmp置1\n"                             \
    "    stlxr    %w2, %w1, %3\n"                            \
    "       // 如果tmp被置1则从头再次执行一遍\n"                                \
    "    cbnz    %w2, 1b\n"                        \
        : "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)    \
        : __stringify(K) "r" (i)                        \
        : "memory");                            \
                                        \
        return result;                            \
    }

A组:基本指令 ADD、SUB、AND、OR、XOR、CMP、TEST、MVRR、DEC、INC、SHL、SHR、 JR、JRC、JRNC、JRZ、JRNZ 扩展指令 ADC、SBB、RCL、RCR、ASR、NOT、CLC、STC、EI、CI、JRS、 JRNS、JMPR B组:基本指令 JMPA、LDRR、STRR、PUSH、POP、PSHF、POPF、MVRD、IN、OUT、RET C组:扩展指令 CALR、LDRA、STRA、LDRX、STRX D组:基本指令 CALA 扩展指令 IRET 这种分类办法,是为了突出指令执行步骤的划分结果,有利于讲解控制器设计技术。 A组指令完成的是通用寄存器之间的数据运算或传送,或其它几项特殊的操作,在取指之后可一步完成。 B组指令完成的是一次内存或I/O读、写操作,在取指之后可两步完成,第一步把要使用的地址传送到地址寄存器AR中,第二步执行内存或I/O读、写操作。 C组指令在取指之后可三步完成,其中CALR指令在用两步完成一次写内存之后,第三步执行寄存器之间的数据传送;而其它指令在第一步置地址寄存器AR,第二步读内存(即取得一个内存单元的地址)并传送到地址寄存器AR,第三步执行另外一次读、写内存的操作。 D组指令完成的是两次读、写内存操作,在取指之后可四步完成。 十六位的教学机系统,实现了上面4组中的29条基本指令,用于支持教学机的监控程序和简单的汇编语言程序设计。保留了其余19条扩展指令,供学生在教学实验中进行扩展,即完成对这些指令的设计与调试,当然,还可以扩展另外一些指令。 为了支持汇编语言程序设计,每一条指令分配了一个汇编语句名,其命名规则是: 用一个英文单词或其缩写形式(2~4个字母)给出一个汇编语句名,例如ADD、SUB、MVRR、MVRD、JR、JMPA、STRX等; 其中的1~2个字母可能涉及到操作数寻址方式,具体规定如下: 用R代表寄存器寻址,例如ADD R0,R1 语句表示 R0←R0+R1;MVRR R0,R1语句表示把寄存器R1的内容传送到寄存器R0;在R字母两侧加上方括号,代表寄存器间接寻址,例如STRR [R8],R9 语句表示把R9的内容传送到以寄存器R8的内容为地址的内存单元之中; 用D表示立即数寻址,例如MVRD R3,1234 语句表示 R0←立即数1234; 用X表示变址寻址,例如 LDRX R1,12[R2] 语句表示把变址寄存器R2的内容与变址偏移量12相加作为内存地址,进行读操作,读出的数据传送的寄存器R1; 用A表示直接地址寻址,例如 JMPA 2008 语句表示转移到2008单元之处, STRA [2000], R2 语句表示把R2的内容写入到地址为2000的内存单元之中。 §1.2.1 基本指令汇总表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值