Load-Acquire/Store-Release 和中断

Load-Acquire/Store-Release and interrupts

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

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

如果我没理解错的话,当这段代码在两个内核上执行时(访问相同的内存地址),那么线程A就用ldaxr锁定了资源。 stlxr 线程 B 失败并重试操作,直到线程 A 释放锁。

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

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

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

据此 ARM manual,pg B-165 指出:

B.6.5 Load-Exclusive and Store-Exclusive instruction constraints:

If two StoreExcl instructions are executed without an intervening LoadExcl instruction the second StoreExcl instruction returns a status value of 1.

... more details ...

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

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

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

主线程中的stlxr会失败
ldaxrstlxrLoad-link/Store-conditional指令,它们是无锁的,用户必须准备重复LL/SC。

Whenever an address is read using a Load Exclusive instruction, it is marked as being for an exclusive access. If an address marked as exclusive is written to using a Store Exclusive instruction, it clears the exclusive status. An attempt to write to an address not marked as exclusive using a Store Exclusive instruction will not succeed. This enables software to detect if the contents of that address have been changed since the last time it was read.