I do not understand anything reading the source code of this method
I think the load method executes only once to load the current value of the data. Then it compares with the new one, if it matches the given current one, then the success case is executed, otherwise the failure case.
Interesting, neither the type nor the module level docs actually explicitly state the defining feature of atomics, that is, every operation on them is "atomic" in the sense that it happens all at once ("atom" meaning indivisible - the Greeks not having particle accelerators and all)
In the case of compare_exchange, it's not reading the current value then comparing, then writing - it does all three at once with a single CPU instruction, eg on x86 it's CMPXCHG.
The language around Relaxed, etc is referring to the memory model, which determines how the compiler and CPU is permitted to reorder other instructions relative to the atomic instruction, for example you don't want it to move operations on the content of a mutex either before the lock, so you use Acquire for that, nor after the unlock, so you use Release.
The hint may be in compare_exchange_weak() — it can fail, so I presume compare_exchange() reserves the right to be implemented as a retry loop over compare_exchange_weak().
Technically, compare_exchange can not be implemented in terms of compare_exchange_weak, since the latter does not provide a way to distinguish between regular and spurious failures (e.g. such emulation can be problematic if current is equal to new). But the compiler indeed can generate retry loops on architectures with LR/SC instructions like RISC-V:
Obligatory mention of Mara Bos' Rust Atomics and Locks. It's a great resource for learning this stuff, especially if you are new to doing concurrency things.
For your case with compare_exchange, see Chapter 2.3.
Continuing on the example @simonbuchan mentioned, on the x86 architecture the CMPXCHG instruction, based on the Intel 64 and IA-32 Developers Manual (Page 804 in the PDF), there should only be one load in either the success or failure scenarios
If the two values are equal, the second operand (source operand) is loaded into the destination operand. Otherwise, the destination operand is loaded into the AL, AX, EAX or RAX register. RAX register is available only in 64-bit mode.
Strictly speaking, based on the pseudo code (replica of the same Intel Manual for ease of hyperlinking) for a potential implementation of CMPXCHG, there can be multiple "loads" in the sense of loading data from memory addresses into registers (e.g. TEMP := DEST and DEST := SRC are both memory loads), but the developer's manual quoted refers to a single memory load which serves as the synchronization point for memory ordering. As the manual mentions, the CMPXCHG instruction can be prefixed with LOCK which makes the operation atomic.
Thanks. It is a good book. I have been reading this book for a few weeks. While reading chapter three of the book I stumbled upon this question. The book gave a simple overview of the compare_exchange method which is really excellent.