ms-queue: begin relaxing
[model-checker-benchmarks.git] / dekker-fences / dekker-fences.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
13 std::atomic<bool> flag0, flag1;
14 std::atomic<int> turn;
15
16 uint32_t var = 0;
17
18 void p0(void *arg)
19 {
20         flag0.store(true,std::memory_order_relaxed);
21         std::atomic_thread_fence(std::memory_order_seq_cst);
22
23         while (flag1.load(std::memory_order_relaxed))
24         {
25                 if (turn.load(std::memory_order_relaxed) != 0)
26                 {
27                         flag0.store(false,std::memory_order_relaxed);
28                         while (turn.load(std::memory_order_relaxed) != 0)
29                         {
30                         }
31                         flag0.store(true,std::memory_order_relaxed);
32                         std::atomic_thread_fence(std::memory_order_seq_cst);
33                 }
34         }
35         std::atomic_thread_fence(std::memory_order_acquire);
36
37         // critical section
38         store_32(&var, 1);
39
40         turn.store(1,std::memory_order_relaxed);
41         std::atomic_thread_fence(std::memory_order_release);
42         flag0.store(false,std::memory_order_relaxed);
43 }
44
45 void p1(void *arg)
46 {
47         flag1.store(true,std::memory_order_relaxed);
48         std::atomic_thread_fence(std::memory_order_seq_cst);
49
50         while (flag0.load(std::memory_order_relaxed))
51         {
52                 if (turn.load(std::memory_order_relaxed) != 1)
53                 {
54                         flag1.store(false,std::memory_order_relaxed);
55                         while (turn.load(std::memory_order_relaxed) != 1)
56                         {
57                         }
58                         flag1.store(true,std::memory_order_relaxed);
59                         std::atomic_thread_fence(std::memory_order_seq_cst);
60                 }
61         }
62         std::atomic_thread_fence(std::memory_order_acquire);
63
64         // critical section
65         store_32(&var, 2);
66
67         turn.store(0,std::memory_order_relaxed);
68         std::atomic_thread_fence(std::memory_order_release);
69         flag1.store(false,std::memory_order_relaxed);
70 }
71
72 int user_main(int argc, char **argv)
73 {
74         thrd_t a, b;
75
76         flag0 = false;
77         flag1 = false;
78         turn = 0;
79
80         thrd_create(&a, p0, NULL);
81         thrd_create(&b, p1, NULL);
82
83         thrd_join(a);
84         thrd_join(b);
85
86         return 0;
87 }