The ldrex
and strex
take a different tactic for implementing atomic instructions. The traditional compare and swap (CAS for short) has limitations in lock-free programming. The load link/store conditional (LL/SC for short) is a more advanced form of atomic instruction that allows atomic linked lists; compare them and think about how they might be implemented in silicon.
For the traditional ARM, the swp
and swpb
instructions provided an atomic mechanism. This seems obvious as the instruction stands by itself. The complication is in multi-cpu designs. The CPU running the swp
must lock the bus so that other CPUs can not read or write the memory as the update is being performed. Typically, this would be the whole BUS and not just a single location. The whole BUS mechanism means that Adhmal's law applies.
As per Masta79, Atomic does not mean "in one cycle", is a distinguishing feature of the ARM ldrex
/strex
atomic support. A particular reserve granule is locked on the ARM bus for the duration of the ldrex
/strex
pair. This allows for many different complex lock free primitives; many valid instructions are permitted between the ldrex
/strex
pairs. However, it come with the additional complication that the strex
supports a retry status via the condition code being set. This is a definite shift in mind-set from traditional atomic operations. With specific reservations, it is possible for each CPU to make progress, if they are not trying to lock the same reserve granual (a specific chunk of memory) at the same time. This should help in avoiding the Adhmal road block (aka memory bandwidth with bus locking).
how can it be called as atomic when it can be preempted?
An important feature of the code is prefetchw(&v->counter);
, which brings the value into the cache. The cache is treated as a temporary buffer and a successful strex
will commit it. Only the cached value is modified until the strex
; if the strex
finds it is dirty (another committed it), then the value is thrown away. An interrupt on the same CPU will do a clrex
, which also invalidates the data and makes the strex
retry.