Fix apparent bug...
[satcheck.git] / test / dekker-fences.c
1 /*
2  * Dekker's critical section algorithm, implemented with fences.
3  * Translated to C by Patrick Lam <prof.lam@gmail.com>
4  *
5  * URL:
6  *   http://www.justsoftwaresolutions.co.uk/threading/
7  */
8
9 #include <threads.h>
10 #include <stdbool.h>
11 #include "libinterface.h"
12
13 /* atomic */ int flag0, flag1;
14 /* atomic */ int turn;
15
16 #define true 1
17 #define false 0
18 #define NULL 0
19
20 /* uint32_t */ int var = 0;
21
22 void p0(void *arg)
23 {
24         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
25         store_32(&flag0, true);
26         // std::atomic_thread_fence(std::memory_order_seq_cst);
27
28         MCID _mt; MCID _fn0; int f1, t;
29         MC2_enterLoop();
30         while (true)
31         {
32                 _fn0=MC2_nextOpLoad(MCID_NODEP), f1 = load_32(&flag1);
33                 _fn0 = MC2_function(1, sizeof (f1), f1, _fn0); 
34                 MCID _br0;
35                 if (!f1) {
36                         _br0 = MC2_branchUsesID(_fn0, 1, 2, true);
37                         break;
38                 } else {
39                         _br0 = MC2_branchUsesID(_fn0, 0, 2, true);
40                         ;
41                         MC2_merge(_br0);
42                 }
43
44                 if ((_mt=MC2_nextOpLoad(MCID_NODEP), t = load_32(&turn)) != 0)
45                 {
46                         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
47                         store_32(&flag0, false);
48                         MC2_enterLoop();
49                         while ((_mt=MC2_nextOpLoad(MCID_NODEP), t = load_32(&turn)) != 0)
50                         {
51                                 // thrd_yield();
52                                 ;
53                         }
54 MC2_exitLoop();
55
56                         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
57                         store_32(&flag0, true);
58                         // std::atomic_thread_fence(std::memory_order_seq_cst);
59                 } else {
60                         ;
61                         // thrd_yield();
62                 }
63         }
64 MC2_exitLoop();
65
66         // std::atomic_thread_fence(std::memory_order_acquire);
67
68         // critical section
69         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
70         store_32(&var, 1);
71
72         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
73         store_32(&turn, 1);
74         // std::atomic_thread_fence(std::memory_order_release);
75         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
76         store_32(&flag0, false);
77 }
78
79 void p1(void *arg)
80 {
81         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
82         store_32(&flag1, true);
83         // std::atomic_thread_fence(std::memory_order_seq_cst);
84
85         MCID _mt; int f0, t;
86         MC2_enterLoop();
87         while (true)
88         {
89                 MCID _mf0; _mf0=MC2_nextOpLoad(MCID_NODEP); int f0 = load_32(&flag0);
90                 MCID _br1;
91                 if (f0) {
92                         _br1 = MC2_branchUsesID(_mf0, 1, 2, true);
93                         ;
94                         MC2_merge(_br1);
95                 } else {
96                         _br1 = MC2_branchUsesID(_mf0, 0, 2, true);
97                         break;
98                 }
99                 if ((_mt=MC2_nextOpLoad(MCID_NODEP), t = load_32(&turn)) != 1)
100                 {
101                         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
102                         store_32(&flag1, false);
103                         MC2_enterLoop();
104                         while ((_mt=MC2_nextOpLoad(MCID_NODEP), t = load_32(&turn)) != 1)
105                         {
106                                 thrd_yield();
107                         }
108 MC2_exitLoop();
109
110                         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
111                         store_32(&flag1, true);
112                         // std::atomic_thread_fence(std::memory_order_seq_cst);
113                 } else {
114                         ;
115                         thrd_yield();
116                 }
117         }
118 MC2_exitLoop();
119
120         // std::atomic_thread_fence(std::memory_order_acquire);
121
122         // critical section
123         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
124         store_32(&var, 2);
125
126         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
127         store_32(&turn, 0);
128         // std::atomic_thread_fence(std::memory_order_release);
129         MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
130         store_32(&flag1, false);
131 }
132
133 int user_main(int argc, char **argv)
134 {
135         thrd_t a, b;
136
137         flag0 = false;
138         flag1 = false;
139         turn = 0;
140
141         thrd_create(&a, p0, NULL);
142         thrd_create(&b, p1, NULL);
143
144         thrd_join(a);
145         thrd_join(b);
146
147         return 0;
148 }