以下是ARM手册中的自旋锁实现示例。请点击此处:http://infocenter.arm.com/help/topic/com.arm.doc.genc007826/Barrier_Litmus_Tests_and_Cookbook_A08.pdf。关于“使用等待事件(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 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将确保我们等待活动?那么不需要STREX EQ 吗?
提前致谢!
答案 0 :(得分:6)
不,WFE没有您认为的保证。 ARM手册描述了一系列必须使您从WFE中退出的事件,但由于其他原因允许核心唤醒。例如,允许核心在其WFE实现上实现超时。这些事件与WFI的事件相同,添加了一些执行SEV指令的处理器。但是,它没有任何要求保持睡眠的要求。实际上,NOP是一种体系结构有效的,虽然是强大的WFE实现。假设你因为看到SEV而醒来,你永远不会安全。例如,可能存在中断,处理器处理中断并将控制权返回给线程。然后线程执行系列中的下一条指令STREX。
答案 1 :(得分:1)
SEV,WFI和WFE是CPU的省电提示,它们与内存同步无关。 WFE / SEV也没有相互结合的方式。
来自ARM ARM:
A8.8.168: 发送事件是一条提示指令。它会将事件发送到多处理器系统中的所有处理器。
A8.8.425: WFI 指令提示在处理器发生中断或类似异常之前不需要做任何事情。
A8.8.424: WFE 指令提示在SEV指令生成事件之前不需要执行任何操作。