test: insanesync: convert to C++
[model-checker.git] / test / insanesync.cc
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <threads.h>
4 #include <atomic>
5
6 #include "librace.h"
7 #include "model-assert.h"
8
9 using namespace std;
10
11 atomic_int x;
12 atomic_int y;
13 atomic_intptr_t z;
14 atomic_intptr_t z2;
15
16 int r1, r2, r3; /* "local" variables */
17
18 /**
19                 This example illustrates a self-satisfying cycle involving
20                 synchronization.  A failed synchronization creates the store that
21                 causes the synchronization to fail.
22
23                 The C++11 memory model nominally allows r1=0, r2=1, r3=5.
24
25                 This example is insane, we don't support that behavior.
26 */
27
28
29 static void a(void *obj)
30 {
31         z.store((intptr_t)&y, memory_order_relaxed);
32         r1 = y.fetch_add(1, memory_order_release);
33         z.store((intptr_t)&x, memory_order_relaxed);
34         r2 = y.fetch_add(1, memory_order_release);
35 }
36
37
38 static void b(void *obj)
39 {
40         r3 = y.fetch_add(1, memory_order_acquire);
41         void *ptr = (void *)z.load(memory_order_relaxed);
42         z2.store((intptr_t)ptr, memory_order_relaxed);
43 }
44
45 static void c(void *obj)
46 {
47         atomic_int *ptr2 = (atomic_int *)z2.load(memory_order_relaxed);
48         (*ptr2).store(5, memory_order_relaxed);
49 }
50
51 int user_main(int argc, char **argv)
52 {
53         thrd_t t1, t2, t3;
54
55         atomic_init(&x, 0);
56         atomic_init(&y, 0);
57         atomic_init(&z, (intptr_t) &x);
58         atomic_init(&z2, (intptr_t) &x);
59
60         thrd_create(&t1, (thrd_start_t)&a, NULL);
61         thrd_create(&t2, (thrd_start_t)&b, NULL);
62         thrd_create(&t3, (thrd_start_t)&c, NULL);
63
64         thrd_join(t1);
65         thrd_join(t2);
66         thrd_join(t3);
67
68         printf("r1=%d, r2=%d, r3=%d\n", r1, r2, r3);
69
70         return 0;
71 }