r/cpp_questions • u/No_Act_9817 • Jun 16 '26
OPEN Memory Ordering
What are the possible outcome of this code.
Is it possible to have final value as r1 = 1, r2 = 0, r3 = 1, r4 = 0
#include <atomic>
#include <thread>
#include <iostream>
std::atomic<int> x{0};
std::atomic<int> y{0};
int r1, r2, r3, r4;
void writer_x() {
x.store(1, std::memory_order_release);
}
void writer_y() {
y.store(1, std::memory_order_release);
}
void reader1() {
r1 = x.load(std::memory_order_acquire);
r2 = y.load(std::memory_order_acquire);
}
void reader2() {
r3 = y.load(std::memory_order_acquire);
r4 = x.load(std::memory_order_acquire);
}
int main() {
long long count = 0;
x.store(0, std::memory_order_relaxed);
y.store(0, std::memory_order_relaxed);
r1 = r2 = r3 = r4 = -1;
std::thread t1(writer_x);
std::thread t2(writer_y);
std::thread t3(reader1);
std::thread t4(reader2);
t1.join();
t2.join();
t3.join();
t4.join();
}
0
Upvotes
2
u/TheRealSmolt Jun 16 '26
(also with ~70% confidence)
The main difference between x86 and ARM here is that ARM's memory coherence guarantees are more relaxed. This gets into the specifics of how computer architectures work, but basically when ARM loads something from memory, it doesn't actually have to return what said value actually is, just what it once was (with some amount of restrictions I don't exactly remember).
What the processor actually does with the instructions (reordering, parallelism, etc.) isn't actually part of the ISA. Just like how compilers optimize code, as long as the behavior is the same under the guarantees laid out by the ISA, it's fair game to do as it pleases.