2 * Dekker's critical section algorithm, implemented with fences.
3 * Translated to C by Patrick Lam <prof.lam@gmail.com>
6 * http://www.justsoftwaresolutions.co.uk/threading/
11 #include "libinterface.h"
13 /* atomic */ int flag0, flag1;
14 /* atomic */ int turn;
20 /* uint32_t */ int var = 0;
23 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
24 store_32(&flag0, true);
25 // std::atomic_thread_fence(std::memory_order_seq_cst);
31 _mf1=MC2_nextOpLoad(MCID_NODEP), f1 = load_32(&flag1);
35 MCID _cond0_m = MC2_function_id(1, 1, sizeof(_cond0), _cond0, _mf1);
37 _br0 = MC2_branchUsesID(_cond0_m, 1, 2, true);
40 else { _br0 = MC2_branchUsesID(_cond0_m, 0, 2, true); MC2_merge(_br0);
43 MCID _m_cond1_m=MC2_nextOpLoad(MCID_NODEP);
44 int _cond1 = load_32(&turn);
45 MCID _cond1_m = MC2_function_id(2, 1, sizeof(_cond1), _cond1, _m_cond1_m);
47 _br1 = MC2_branchUsesID(_cond1_m, 1, 2, true);
48 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
49 store_32(&flag0, false);
53 MCID _m_cond2_m=MC2_nextOpLoad(MCID_NODEP);
54 int _cond2 = !load_32(&turn);
55 MCID _cond2_m = MC2_function_id(3, 1, sizeof(_cond2), _cond2, _m_cond2_m);
57 _br2 = MC2_branchUsesID(_cond2_m, 1, 2, true);
60 else { _br2 = MC2_branchUsesID(_cond2_m, 0, 2, true); MC2_merge(_br2);
67 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
68 store_32(&flag0, true);
71 _br1 = MC2_branchUsesID(_cond1_m, 0, 2, true);
79 // std::atomic_thread_fence(std::memory_order_acquire);
82 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
85 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
87 // std::atomic_thread_fence(std::memory_order_release);
88 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
89 store_32(&flag0, false);
93 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
94 store_32(&flag1, true);
95 // std::atomic_thread_fence(std::memory_order_seq_cst);
100 MCID _mf0; _mf0=MC2_nextOpLoad(MCID_NODEP); int f0 = load_32(&flag0);
104 MCID _cond3_m = MC2_function_id(4, 1, sizeof(_cond3), _cond3, _mf0);
106 _br3 = MC2_branchUsesID(_cond3_m, 1, 2, true);
109 else { _br3 = MC2_branchUsesID(_cond3_m, 0, 2, true); MC2_merge(_br3);
112 MCID _m_cond4_m=MC2_nextOpLoad(MCID_NODEP);
113 int _cond4 = !load_32(&turn);
114 MCID _cond4_m = MC2_function_id(5, 1, sizeof(_cond4), _cond4, _m_cond4_m);
116 _br4 = MC2_branchUsesID(_cond4_m, 1, 2, true);
117 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
118 store_32(&flag1, false);
122 MCID _m_cond5_m=MC2_nextOpLoad(MCID_NODEP);
123 int _cond5 = load_32(&turn);
124 MCID _cond5_m = MC2_function_id(6, 1, sizeof(_cond5), _cond5, _m_cond5_m);
126 {_br5 = MC2_branchUsesID(_cond5_m, 1, 2, true);
128 else { _br5 = MC2_branchUsesID(_cond5_m, 0, 2, true); MC2_merge(_br5);
134 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
135 store_32(&flag1, true);
136 // std::atomic_thread_fence(std::memory_order_seq_cst);
139 else { _br4 = MC2_branchUsesID(_cond4_m, 0, 2, true);
146 // std::atomic_thread_fence(std::memory_order_acquire);
149 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
152 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
154 // std::atomic_thread_fence(std::memory_order_release);
155 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
156 store_32(&flag1, false);
162 for(i=0;i<PROBLEMSIZE;i++) {
173 for(i=0;i<PROBLEMSIZE;i++) {
181 int user_main(int argc, char **argv)
185 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
186 store_32(&flag0, false);
188 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
189 store_32(&flag1, false);
191 MC2_nextOpStore(MCID_NODEP, MCID_NODEP);
194 thrd_create(&a, p0l, NULL);
195 thrd_create(&b, p1l, NULL);