首页 > 解决方案 > 加载-获取/存储-释放和中断

问题描述

假设我有一个原子加载-修改-存储操作:

1:    ldaxr x8, [x9]
      orr x10, x8, #1
      stlxr w11, x10, [x9]
      cbnz w11, 1b

如果我理解正确,当这段代码在两个内核上执行(访问相同的内存地址)时,线程 A 会使用ldaxr. stlxr在线程 B 中失败并重试操作,直到线程 A 释放锁。

ldaxr但是如果在主线程和中断处理程序尝试访问相同的内存地址之后发生中断会发生什么?它会死锁还是中断处理程序优先,并且stlxr在从中断返回时主线程会失败?

标签: assemblyarm64lock-freearmv8

解决方案


主代码的存储指令成功代码将指示失败。

从广义上讲,跨处理器架构,这些工作方式取决于处理器。然而,我相信有一些实施策略会奏效。处理器可以在中断时取消保留(这意味着它永远不必在上下文切换时保存/恢复保留状态),或者可以等待取消保留直到另一个ldaxr完成,或者可以等到另一个ldaxr同时完成缓存行或相同的地址。使用某些方法,处理器将存储保留的位置/地址,而在其他方法(即可能是单核)中,它不一定必须(除非它想要验证 ld/st 对的正确使用,这应该在地址和访问大小上匹配)。

从此ARM 手册中,第 B-165 页指出:

B.6.5 Load-Exclusive 和 Store-Exclusive 指令约束:

如果在没有中间 LoadExcl 指令的情况下执行了两条 StoreExcl 指令,则第二条 StoreExcl 指令返回状态值 1。

... 更多细节 ...

(1 为失败代码,0 为成功代码。)

因此,通过该文本,如果处理器在中断期间执行这样的存储,这将取消任何获得的保留,从而使主代码的存储失败,而不管所涉及的内存地址如何。

虽然指令集的架构要求通常是相当具体的,但可以实施具有不同权衡的各种替代策略来实现这一点。


推荐阅读