Use of STREXEQ instead of STREX for spinlock implementation in ARM
arm, assembly, inline-assembly, kernel, spinlock
Solution
No, WFE does not have the guarantees you're thinking it does. The ARM manual describes a large set of events that must cause you to come out from WFE but the core is allowed to wake up for other reasons. For example a core is allowed to implement a timeout on its WFE implementation. These events are the same as the events for WFI with the addition of some processor executing an SEV instruction. It does not however have any requirement to stay asleep. In fact, NOP is an architecturally valid albeit power hungry implementation of WFE. It is never safe for you to assume that you woke up because you saw an SEV. For example, there may have been an interrupt, the processor processed the interrupt and returned control to the thread. The thread then executed the next instruction in the series, the STREX.
Problem
The following is a sample spin-lock implementation in the ARM manual. Please check here: http://infocenter.arm.com/help/topic/com.arm.doc.genc007826/Barrier_Litmus_Tests_and_Cookbook_A08.pdf . Section on "Use of Wait For Event (WFE) and Send Event (SEV) with Locks". Locking code: ``` 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 ``` Lock release code: ``` 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 ``` Question: Why is STREXEQ used? What if STREX is used instead? As I understand it strexeq will execute only if EQ flag is set. But anyway, if EQ is not set, then WFENE will ensure that we are waiting for the event? So isn't STREX EQ unnecessary? Thanks in advance!