Assembly 在ARM中使用STREXEQ代替STREX实现自旋锁
以下是ARM手册中的自旋锁实现示例。请检查这里:。“使用带锁的等待事件(WFE)和发送事件(SEV)”部分 锁定代码:Assembly 在ARM中使用STREXEQ代替STREX实现自旋锁,assembly,kernel,arm,inline-assembly,spinlock,Assembly,Kernel,Arm,Inline Assembly,Spinlock,以下是ARM手册中的自旋锁实现示例。请检查这里:。“使用带锁的等待事件(WFE)和发送事件(SEV)”部分 锁定代码: Loop: LDREX R5, [R1] ; read lock CMP R5, #0 ; check if 0 WFENE ; sleep if the lock is held STREXEQ R5, R0, [R1] ; attempt to store new valu
Loop:
LDREX R5, [R1] ; read lock
CMP R5, #0 ; check if 0
WFENE ; sleep if the lock is held
STREXEQ R5, R0, [R1] ; attempt to store new value
CMPEQ R5, #0 ; test if store suceeded
BNE Loop ; retry if not
DMB ; ensures that all subsequent accesses are observed after the
; gaining of the lock is observed
; loads and stores in the critical region can now be performed
锁释放代码:
MOV R0, #0
DMB ; ensure all previous accesses are observed before the lock is cleared
STR R0, [R1] ; clear the lock.
DSB ; ensure completion of the store that cleared the lock before sending the event
SEV
问题:为什么使用STREXEQ?如果改用STREX呢?据我所知,只有设置了EQ标志,strexeq才会执行。但无论如何,如果没有设置EQ,那么WFENE将确保我们正在等待事件?那么STREXEQ不是没有必要吗
提前谢谢 不,WFE没有您认为的保证。ARM手册描述了一大组事件,这些事件必须导致您从WFE中出来,但内核由于其他原因被允许唤醒。例如,允许内核在其WFE实现上实现超时。这些事件与WFI的事件相同,只是增加了一些执行SEV指令的处理器。然而,它没有任何保持睡眠的要求。事实上,NOP是WFE的一个架构上有效的、但耗电量很大的实现。假设你醒来是因为看到了一个SEV,这对你来说永远都不安全。例如,可能有一个中断,处理器处理该中断并将控制返回给线程。然后线程执行系列中的下一条指令STREX。SEV、WFI和WFE是CPU的节能提示,它们与内存同步无关。此外,WFE/SEV不会以某种方式相互耦合 发件人: A8.8.168:发送事件是一条提示指令。它使事件通过信号发送给多处理器系统中的所有处理器 A8.8.425:WFI指令提供提示,在处理器发生中断或类似异常之前,无需执行任何操作 A8.8.424:WFE指令提示在SEV指令生成事件之前无需执行任何操作
非常感谢。这是有道理的。我应该更加注意wfene指令。