-
Notifications
You must be signed in to change notification settings - Fork 0
/
x86storeload.cpp
56 lines (43 loc) · 1.03 KB
/
x86storeload.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <atomic>
#include <iostream>
#include <thread>
// based on the oft-referenced example from Intel's x86 guide.
// switch this to demonstrate the effect
constexpr bool shouldFence = false;
int x;
int y;
// not registers but w/e
int r1;
int r2;
std::atomic<bool> shouldProceed;
void storeAndLoad(int &storeTo, int &loadFrom, int &dest) {
while(!shouldProceed);
storeTo = 1;
// prevent compile-time reordering by the compiler
asm ("" ::: "memory");
if (shouldFence) {
// also prevent run-time reordering by the processor
asm ("mfence" ::: "memory");
}
dest = loadFrom;
}
int main() {
for (int i = 0; i < 10000; i++) {
x = 0;
y = 0;
r1 = 0;
r2 = 0;
shouldProceed = false;
std::thread left(storeAndLoad, std::ref(x), std::ref(y), std::ref(r1));
std::thread right(storeAndLoad, std::ref(y), std::ref(x), std::ref(r2));
shouldProceed = true;
left.join();
right.join();
std::cout << r1 << r2;
if (r1 == 0 && r2 == 0) {
// store-load reordered
std::cout << "*****";
}
std::cout << std::endl;
}
}