假设我有一个原子加载-修改-存储操作:
1: ldaxr x8, [x9]
orr x10, x8, #1
stlxr w11, x10, [x9]
cbnz w11, 1b
如果我理解正确,当这段代码在两个内核上执行(访问相同的内存地址(时,线程 A 会用ldaxr
锁定资源。 线程 B 中的stlxr
失败,操作将重试,直到线程 A 释放锁。
但是,如果在主线程和中断处理程序中的ldaxr
尝试访问相同的内存地址后发生中断,会发生什么情况?它是否会死锁或中断处理程序优先,并且主线程中的stlxr
在从中断返回时会失败?
主线程中的stlxr
将失败。ldaxr
和stlxr
是加载链接/存储条件指令,它们是无锁的,用户必须准备好重复LL/SC。
每当使用"加载独占"指令读取地址时,都会将其标记为 独占访问权限。如果使用商店独占指令写入标记为专用地址, 它清除了独占状态。尝试使用 商店独占说明不会成功。这使软件能够检测其内容是否 自上次读取以来,地址已更改。
主代码的存储指令成功代码将指示失败。
从广义上讲,跨处理器架构,这些工作方式取决于处理器。 但是,我认为有许多实施策略是可行的。 处理器可以在中断时取消保留(这意味着它永远不必在上下文切换时保存/恢复保留状态(,或者可以等到另一个ldaxr
完成时取消保留, 或者可以等到在同一缓存行或相同地址上完成另一ldaxr
。 对于某些方法,处理器将存储保留的位置/地址,而在其他方法(即可能是单核(中,它不一定必须(除非它想验证ld/st对的正确用法, 应该在地址和访问大小上匹配(。
从这本 ARM 手册中,第 B-165 页指出:
B.6.5 独占加载和存储独占指令约束:
如果在没有干预 LoadExcl 指令的情况下执行了两个 StoreExcl 指令,则第二个 StoreExcl 指令返回状态值 1。
。更多详情 ...
(1 是失败代码,0 是成功代码。
因此,通过该文本,如果处理器在中断期间执行这样的存储,这将取消任何获取的保留,从而使主代码的存储失败,无论如何,可能涉及的内存地址。
虽然指令集的架构要求通常是相当具体的,但可以实现具有不同权衡的各种替代策略来实现这一点。