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!
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.
SEV, WFI and WFE are power saving hints for CPU, they have nothing to do with memory synchronization. Also WFE / SEV does not come in a way to couple each other.
From ARM ARM:
A8.8.168: Send Event is a hint instruction. It causes an event to be signaled to all processors in the multiprocessor system.
A8.8.425: The WFI instruction provides a hint that nothing needs to be done until the processor takes an interrupt or similar exception.
A8.8.424: The WFE instruction provides a hint that nothing needs to be done until either an SEV instruction generates an event.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With