edits
[model-checker-benchmarks.git] / spsc-queue-scfence / queue.h
1 #include <unrelacy.h>
2 #include <atomic>
3
4 #include "eventcount.h"
5 #include "wildcard.h"
6
7 class spsc_queue
8 {
9 public:
10         spsc_queue()
11         {
12                 node* n = new node (-1);
13                 head = n;
14                 tail = n;
15         }
16
17         ~spsc_queue()
18         {
19                 RL_ASSERT(head == tail);
20                 delete ((node*)head($));
21         }
22
23         void enqueue(int data)
24         {
25                 node* n = new node (data);
26                 head($)->next.store(n, wildcard(6));
27                 head = n;
28                 ec.signal_relaxed();
29         }
30
31         int dequeue()
32         {
33                 int data = try_dequeue();
34                 while (0 == data)
35                 {
36                         int cmp = ec.get();
37                         data = try_dequeue();
38                         if (data)
39                                 break;
40                         ec.wait(cmp);
41                         thrd_yield();
42                         data = try_dequeue();
43                         if (data)
44                                 break;
45                 }
46                 return data;
47         }
48
49 private:
50         struct node
51         {
52                 std::atomic<node*> next;
53                 std::atomic<int> data;
54
55                 node(int d)
56                 {
57                         data.store(d, memory_order_normal);
58                         next = 0;
59                 }
60         };
61
62         rl::var<node*> head;
63         rl::var<node*> tail;
64
65         eventcount ec;
66
67         int try_dequeue()
68         {
69                 node* t = tail($);
70                 node* n = t->next.load(wildcard(7));
71                 if (0 == n)
72                         return 0;
73                 int data = n->data.load(memory_order_normal);
74                 delete (t);
75                 tail = n;
76                 return data;
77         }
78 };