baron · 3月31日 · 四川

ARMv8/ARMv9的Exclusive机制深度解读

快速连接

👉👉👉【精选】ARMv8/ARMv9架构入门到精通-目录 👈👈👈


 title=

说明:本文虽然以spinlock函数为例,但并不会深度解读spinlock函数。本文重点解读exclusive机制。

基础知识

  • 每一个core都有一个Internal exclusive monitor,它有open和exclusive两个状态,管理着:Load-Exclusive accesses 、Store-Exclusive accesses、Clear-Exclusive(CLREX) instructions
  • Load-Exclusive instruction和Store-Exclusive instruction是LDX, LDAX, STX, STLX
  • 可以使用这些指令去构造semaphores、spinlock,以确保在同一个core之间的不同线程的同步操作。在不同的core之间也是可以使用同一个的coherent memory locations来确保同步。
  • Load-Exclusive instruction标记一个block用于独占访问的内存, CTR_EL0定义了这个block的大小。

LDXR Wt, [base{,#0}]
(1)、从base地址处读取一个数字,存放到Wt寄存器中;
(2)、将Monitor的状态变成exclusive

STXR Ws, Wt, [base{,#0}]
(1)、将Wt中的数据写入到base地址处,如果成功Ws返回0,否则返回1;
(2)、将Monitor从exclusive状态切换成open, 如果切换成功,则说明写入成功,Ws返回0; 如果切换失败,则数据不会写入到内存,Ws返回1

剖析:如果想用独占指令去store一个数,那么必需先要ldx/ldax指令,让Monitor置为exclusive状态,此时它才能继续进行store操作,store完成之后,Monitor将会从exclusive切回open状态。
继续白话剖析:我想独占方式往一个地址写数,那么我必需独占monitor,然后我才能往相关地址写数据。

示例1:同一个core上访问不同的锁

如下一个spinlock的实现,在同一个核上,当有两个线程都要执行这一段代码时。

FUNC cpu_spin_lock , :
    mov    w2, #SPINLOCK_LOCK
    sevl
l1:    wfe
l2:    ldaxr    w1, [x0]
    cbnz    w1, l1
    stxr    w1, w2, [x0]
    cbnz    w1, l2
    ret
END_FUNC __cpu_spin_lock
  • 1、thread1先调用cpu_spin_lock[&lock1]执行到ldaxr时,此时Internal Exclusive Monitor将标记为exclusive状态。换句话说,core已经是 Exclusive Access state,马上就要准备写操作了。
  • 2、接着thread2也调用cpu_spin_lock*[&lock2]执行了到ldaxr,此时Internal Exclusive Monitor已经是exclusive状态了,无需重新设置。换句话说,core依然是 Exclusive Access state,马上就要准备写操作了。
  • 3、接着thread1先调用了stxr操作,窝槽牛逼啊,直接就成功了,成功将w2写入到[X0]地址处,w1并返回0表示操作成功。此时Internal Exclusive Monitor将会从exclusive切换成open状态。。
  • 4、接着thread2也调用了stxr操作,因为此时Internal Exclusive Monitor已经是open状态了,所以此时的写入操作将会失败。即w2不会被写入到[X0],且w1返回1,反馈给程序一个结果,告诉他:嗨,这步执行没有通过哦。
  • 5、按照上述程序的逻辑,thread2在执行stxr失败后,w1返回1, 此时将程序跳回l2处,重新来一遍...
    在这里插入图片描述

示例2:不同的core上访问不同的锁

依然是上述的例子,如果是不同的CPU在获取同一把锁会怎样呢?
由于[X0]标记exclusive访问,将会被缓存到Coherent memory中,此memory遵循MESI协议,故此时

  • 1、thread1先调用cpu_spin_lock[&lock1]执行到ldaxr时,此时core1的Internal Exclusive Monitor将标记为exclusive状态。换句话说,core1已经是 Exclusive Access state,马上就要准备写操作了。
  • 2、接着thread2也调用cpu_spin_lock*[&lock2]执行了到ldaxr,此时core2的Internal Exclusive Monitor将标记exclusive状态,换句话说,core依然是 Exclusive Access state,马上就要准备写操作了。
  • 3、接着thread1先调用了stxr操作,窝槽牛逼啊,直接就成功了,成功将w2写入到[X0]地址处,w1并返回0表示操作成功。此时Internal Exclusive Monitor将会从exclusive切换成open状态。。
  • 4、接着thread2也调用了stxr操作,因为此时core2的Internal Exclusive Monitor依然经是exclusive状态了,所以此时的写入操作会成功。

在这里插入图片描述

示例3:不同的core上,访问相同的锁。

依然是上述的例子,如果是不同的CPU在获取同一把锁会怎样呢?
由于[X0]标记exclusive访问,将会被缓存到Coherent memory中,此memory遵循MESI协议,故此时

  • 1、thread1先调用cpu_spin_lock[&lock1]执行到ldaxr时,此时core1的Internal Exclusive Monitor将标记为exclusive状态。换句话说,core1已经是 Exclusive Access state,马上就要准备写操作了。
  • 2、接着thread2也调用cpu_spin_lock*[&lock1]执行了到ldaxr,此时core2的Internal Exclusive Monitor将标记exclusive状态,由于[X0]标记exclusive访问,将会被缓存到Coherent memory中,此memory遵循MESI协议,故此时该地址数据也会被同步到Global Monitor的cache和Core2的Internal Monior的cache中,也就是说,此时Global Exclusive Monitor也换成了该地址数据,并且也是exclusive状态了。
  • 3、接着thread1先调用了stxr操作,窝槽牛逼啊,直接就成功了,成功将w2写入到[X0]地址处,w1并返回0表示操作成功。此时core1的Internal Exclusive Monitor将会从exclusive切换成open状态。 Global Monitor也会从exclusive切换成open状态
  • 4、接着thread2也调用了stxr操作,根据MESI协议,core2在执行store操作时,必先去snoop core1的cache,此时该地址数据将同步到Global Monitor的cache和core2的Internal Monitore的cache中,此时Global exclusive Monitor将会被置为open状态。因为Global exclusive Monitor缓存了该地址数据,并且为open状态,故stxr操作将失败;
  • 5、如果此时core2再次执行一次ldaxr,然后再去执行stxr则能成功。
  • 6、按照上述程序的逻辑,core2在执行stxr失败后,w1返回1, 此时将程序跳回l2处,重新来一遍...

    关注"Arm精选"公众号,备注进ARM交流讨论区。
    图片1.png

推荐阅读
关注数
9467
内容数
212
以易懂、渐进、有序的方式,深入探讨ARMv8/ARMv9架构的核心概念。我们将从基础知识开始,逐步深入,覆盖最新的架构,不再纠缠于过时技术。本系列内容包含但不限于ARM基础、SOC芯片基础、Trustzone、gic、异常和中断、AMBA、Cache、MMU等内容,并将持续更新。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息