prune mod order
[c11tester.git] / pthread_test / mo-satcycle.cc
1 /**
2  * @file mo-satcycle.cc
3  * @brief MO satisfaction cycle test
4  *
5  * This program has a peculiar behavior which is technically legal under the
6  * current C++ memory model but which is a result of a type of satisfaction
7  * cycle. We use this as justification for part of our modifications to the
8  * memory model when proving our model-checker's correctness.
9  */
10
11 #include <atomic>
12 #include <pthread.h>
13 #include <stdio.h>
14
15 #include "model-assert.h"
16
17 using namespace std;
18
19 atomic_int x, y;
20 int r0, r1, r2, r3; /* "local" variables */
21
22 static void *a(void *obj)
23 {
24         y.store(10, memory_order_relaxed);
25         x.store(1, memory_order_release);
26         return NULL;
27 }
28
29 static void *b(void *obj)
30 {
31         r0 = x.load(memory_order_relaxed);
32         r1 = x.load(memory_order_acquire);
33         y.store(11, memory_order_relaxed);
34         return NULL;
35 }
36
37 static void *c(void *obj)
38 {
39         r2 = y.load(memory_order_relaxed);
40         r3 = y.load(memory_order_relaxed);
41         if (r2 == 11 && r3 == 10)
42                 x.store(0, memory_order_relaxed);
43         return NULL;
44 }
45
46 int user_main(int argc, char **argv)
47 {
48         pthread_t t1, t2, t3;
49
50         atomic_init(&x, 0);
51         atomic_init(&y, 0);
52
53         printf("Main thread: creating 3 threads\n");
54         pthread_create(&t1,NULL, &a, NULL);
55         pthread_create(&t2,NULL, &b, NULL);
56         pthread_create(&t3,NULL, &c, NULL);
57
58         pthread_join(t1,NULL);
59         pthread_join(t2,NULL);
60         pthread_join(t3,NULL);
61         printf("Main thread is finished\n");
62
63         /*
64          * This condition should not be hit because it only occurs under a
65          * satisfaction cycle
66          */
67         bool cycle = (r0 == 1 && r1 == 0 && r2 == 11 && r3 == 10);
68         MODEL_ASSERT(!cycle);
69
70         return 0;
71 }