I can't find the implementation of AtomicCmpExchange
(seems to be hidden), so I don't know what it does.
Is AtomicCmpExchange
reliable on all platforms? How is it implemented internally? Does it use something like a critical section?
I have this scenario :
MainThread:
Target := 1;
Thread1:
x := AtomicCmpExchange(Target, 0, 0);
Thread2:
Target := 2;
Thread3:
Target := 3;
Will x
always be an integer 1, 2 or 3, or could it be something else? I mean, even if the AtomicCmpExchange(Target, 0, 0)
failed to exchange the value, does it return a "valid" integer (I mean, not a half-read integer, for exemple if another thread has already started to half write of the value)?
I want to avoid using a critical section, I need maximum speed.
AtomicCmpExchange
is what is known as an intrinsic routine, or a standard function. It is intrinsically known to the compiler and may or may not have a visible implementation. For example, Writeln
is a standard function, but you won't find a single implementation for it. The compiler breaks it up into multiple calls to lower-level functions in System.pas. Some standard functions, such as Inc()
and Dec()
don't have any implementation in System.pas. The compiler will generate machine instructions which amount to simple INC
or DEC
instructions.
Like Inc()
or Dec()
, AtomicCmpExchange()
is implemented using whatever code is needed for a given platform. It will generate inline instructions. For x86/x64 it will generate a CMPXCHG
instruction (along with whatever setup is necessary to get variables/values into the registers). For ARM it will generate a few more instructions around the LDREX
and STREX
instructions.
So the direct answer to your question is that even calling into assembly code, you cannot get much more efficient than using that standard function along with others such as AtomicIncrement
, AtomicDecrement
, and AtomicExchange
.
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