bench.sh: only print git information when we're in git
[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                                 thrd_yield();
31                         }
32                         flag0.store(true,std::memory_order_relaxed);
33                         std::atomic_thread_fence(std::memory_order_seq_cst);
34                 } else
35                         thrd_yield();
36         }
37         std::atomic_thread_fence(std::memory_order_acquire);
38
39         // critical section
40         store_32(&var, 1);
41
42         turn.store(1,std::memory_order_relaxed);
43         std::atomic_thread_fence(std::memory_order_release);
44         flag0.store(false,std::memory_order_relaxed);
45 }
46
47 void p1(void *arg)
48 {
49         flag1.store(true,std::memory_order_relaxed);
50         std::atomic_thread_fence(std::memory_order_seq_cst);
51
52         while (flag0.load(std::memory_order_relaxed))
53         {
54                 if (turn.load(std::memory_order_relaxed) != 1)
55                 {
56                         flag1.store(false,std::memory_order_relaxed);
57                         while (turn.load(std::memory_order_relaxed) != 1)
58                         {
59                                 thrd_yield();
60                         }
61                         flag1.store(true,std::memory_order_relaxed);
62                         std::atomic_thread_fence(std::memory_order_seq_cst);
63                 } else
64                         thrd_yield();
65         }
66         std::atomic_thread_fence(std::memory_order_acquire);
67
68         // critical section
69         store_32(&var, 2);
70
71         turn.store(0,std::memory_order_relaxed);
72         std::atomic_thread_fence(std::memory_order_release);
73         flag1.store(false,std::memory_order_relaxed);
74 }
75
76 int user_main(int argc, char **argv)
77 {
78         thrd_t a, b;
79
80         flag0 = false;
81         flag1 = false;
82         turn = 0;
83
84         thrd_create(&a, p0, NULL);
85         thrd_create(&b, p1, NULL);
86
87         thrd_join(a);
88         thrd_join(b);
89
90         return 0;
91 }