I have MMU disabled while doing some tests on atomics. Here's what I have:
Case 1:
static VAR: AtomicBool = AtomicBool::new(false);
VAR.compare_and_swap(false, true, Ordering::AcqRel);
It assembles into
58: 52800028 mov w8, #0x1 // #1
5c: 90000009 adrp x9, 0x0
60: 91098129 add x9, x9, #0x260
64: 085ffd2a ldaxrb w10, [x9]
68: 350000ca cbnz w10, 0x80
6c: 080afd28 stlxrb w10, w8, [x9]
70: 35ffffaa cbnz w10, 0x64
. . .
80: d5033f5f clrex
. . .
Case 2:
static VAR: AtomicBool = AtomicBool::new(false);
VAR.swap(true, Ordering::AcqRel);
It assembles into
58: 52800028 mov w8, #0x1 // #1
5c: 90000009 adrp x9, 0x0
60: 91094129 add x9, x9, #0x260
64: 085ffd3f ldaxrb wzr, [x9]
68: 080afd28 stlxrb w10, w8, [x9]
6c: 35ffffca cbnz w10, 0x64
. . .
What I expected is both cases will not work when MMU is not enabled. However, only swap()
doesn't work and generates exception. Code after compare_and_swap()
runs fine: I see my LED turns on. Moreover, I thought maybe write operation just fails, or gets skipped, or whatever... but consecutive load()
acquires true
from the variable.
Also, I do not completely understand compare_and_swap()
description:
Notice that even when using
AcqRel
, the operation might fail and hence just perform anAcquire
load, but not haveRelease
semantics.
It can fail and stay in acquired state? Will it freeze in some infinite loop waiting for release then or what will happen in this case? Could anyone please explain me what is happening and why?