edits
[model-checker-benchmarks.git] / dekker-fences / dekker-fences-wildcard.cc
1 /*
2  * Dekker's critical section algorithm, implemented with fences.
3  *
4  * URL:
5  *   http://www.justsoftwaresolutions.co.uk/threading/
6  */
7
8 #include <atomic>
9 #include <threads.h>
10
11 #include "librace.h"
12 #include "wildcard.h"
13
14 std::atomic<bool> flag0, flag1;
15 std::atomic<int> turn;
16
17 //uint32_t var = 0;
18 std::atomic_int var1;
19 std::atomic_int var2;
20
21 void p0(void *argv)
22 {
23         int val = *((int*)argv);
24         int myTurn = val;
25         int otherTurn = 1 - val;
26         std::atomic<bool> *myFlag = val == 0 ? &flag0 : &flag1;
27         std::atomic<bool> *otherFlag = val == 0 ? &flag1 : &flag0;
28         myFlag->store(true, wildcard(1));
29         std::atomic_thread_fence(wildcard(2)); // seq_cst
30
31         while (otherFlag->load(wildcard(3)))
32         {
33                 if (turn.load(wildcard(4)) != myTurn)
34                 {
35                         myFlag->store(false, wildcard(5));
36                         while (turn.load(wildcard(6)) != myTurn)
37                         {
38                                 thrd_yield();
39                         }
40                         myFlag->store(true, wildcard(7));
41                         std::atomic_thread_fence(wildcard(8)); // seq_cst
42                 } else
43                         thrd_yield();
44         }
45         std::atomic_thread_fence(wildcard(9)); // acquire
46
47         // critical section
48         //store_32(&var, 1);
49         if (val) {
50                 var1.store(1, std::memory_order_relaxed);
51                 var2.load(std::memory_order_relaxed);
52         } else {
53                 var2.store(2, std::memory_order_relaxed);
54                 var1.load(std::memory_order_relaxed);
55         }
56
57         turn.store(otherTurn, wildcard(10));
58         std::atomic_thread_fence(wildcard(11)); // release
59         myFlag->store(false, wildcard(12));
60 }
61
62 void p1(void *arg)
63 {
64         p0(arg);
65         p0(arg);
66 }
67
68 int user_main(int argc, char **argv)
69 {
70         thrd_t a, b;
71
72         flag0 = false;
73         flag1 = false;
74         turn = 1;
75         atomic_init(&var1, 0);
76         atomic_init(&var2, 0);
77
78         int thrd1 = 0, thrd2 = 1;
79         thrd_create(&a, p0, &thrd1);
80         thrd_create(&b, p1, &thrd2);
81
82         thrd_join(a);
83         thrd_join(b);
84
85         return 0;
86 }