在ARM中使用STREXEQ而不是STREX来实现自旋锁

时间:2013-05-02 01:48:43

标签: assembly kernel arm inline-assembly spinlock

以下是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 吗?

提前致谢!

2 个答案:

答案 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指令生成事件之前不需要执行任何操作。