Commit state of repository at time of OOPSLA 2015 submission.
[satcheck.git] / benchmarks / satcheck / dekker / dekker-fences_unannotated.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() {
23         store_32(&flag0, true);
24         // std::atomic_thread_fence(std::memory_order_seq_cst);
25
26         int f1;
27         while (true)
28         {
29                 f1 = load_32(&flag1);
30                 if (!f1) {
31                         break;
32                 }
33
34                 if (load_32(&turn)) {
35                         store_32(&flag0, false);
36                         while(1) {
37                                 if (!load_32(&turn)) {
38                                         break;
39                                 }
40                                 
41                                 MC2_yield();
42                         }
43
44                         store_32(&flag0, true);
45                 } else {
46                         MC2_yield();
47                 }
48         }
49
50         // std::atomic_thread_fence(std::memory_order_acquire);
51
52         // critical section
53         store_32(&var, 1);
54
55         store_32(&turn, 1);
56         // std::atomic_thread_fence(std::memory_order_release);
57         store_32(&flag0, false);
58 }
59
60 void p1() {
61         store_32(&flag1, true);
62         // std::atomic_thread_fence(std::memory_order_seq_cst);
63         
64         int f0;
65         while (true) {
66                 int f0 = load_32(&flag0);
67                 if (!f0) {
68                         break;
69                 }
70                 
71                 if (!load_32(&turn)) {
72                         store_32(&flag1, false);
73                         while (1) {
74                                 if (load_32(&turn))
75                                         break;
76                                 MC2_yield();
77                         }
78                         
79                         store_32(&flag1, true);
80                         // std::atomic_thread_fence(std::memory_order_seq_cst);
81                 }
82         }
83
84         // std::atomic_thread_fence(std::memory_order_acquire);
85
86         // critical section
87         store_32(&var, 2);
88
89         store_32(&turn, 0);
90         // std::atomic_thread_fence(std::memory_order_release);
91         store_32(&flag1, false);
92 }
93
94 void p0l(void *a) {
95         int i;
96         for(i=0;i<PROBLEMSIZE;i++) {
97                 p0();
98         }
99 }
100
101
102 void p1l(void *a) {
103         int i;
104         for(i=0;i<PROBLEMSIZE;i++) {
105                 p1();
106         }
107 }
108
109
110 int user_main(int argc, char **argv)
111 {
112         thrd_t a, b;
113
114         store_32(&flag0, false);
115
116         store_32(&flag1, false);
117
118         store_32(&turn, 0);
119
120         thrd_create(&a, p0l, NULL);
121         thrd_create(&b, p1l, NULL);
122
123         thrd_join(a);
124         thrd_join(b);
125
126         return 0;
127 }