My understanding was that:
For V6 and above: You should use LDREX/STREX, because LDREX "locks"
the memory word to this CPU only.
For V5 and below: You can use SWP, or whatever else, but you have to
disable the interrupts to guarantee safety of your memory contents.
However, for V5, disabling interrupts will not be enough in case of
SMP. There seems to be thinking that it's a bad idea to do so anyway,
but I'm not sure whether any other synchronization method will be more
effective, at least to the thread that's executing now. (Probably,
doing other synchronization will work slowly for the current thread,
but have more impact on other system events).
Also, for V6, I can't find anything that says the memory access is
guaranteed to be exclusive to multiple threads. The ARM doc says that
the LDREX "...marks the physical address as exclusive access for the
executing processor in a shared monitor...", but I don't see how a a
code executed in a context switch, or any other external interrupt on
the SAME CPU, won't be able to modify that memory word.... (Which
would mean that the interrupts need to be as disabled even if
LDREX/STREX is used).
Also, I am concerned about the logic diagrams in ARM doc, as it seems that the
LDREX will lock the memory if the condition is true, but STREX will
not unlock the memory
if the condition is false. I would see the most common ways to use
LDREX/STREX is:
LDREXAL R0 ; [R0] -> R0, always load
CMP R0, R1 ; do we need to swap ? (wathever is the instruction for comparing)
STREXNE R2, R1, R0 ; R1 -> [R0], status in R2, only store if weren't equal
I can make the LDREX condition on the same comparison before the load, but
even then there is guarantee I would have to do the store. And it doesn't make
sense to unlock the memory (anyway, I don't know how) using another instruction
than STREX...
Thanks,
Pawel.
--
With best of best regards
Pawel S. Veselov