edits
[model-checker-benchmarks.git] / spsc-example / spsc-queue.cc
1 #include <threads.h>
2 #include <atomic>
3
4 //#include "wildcard.h" 
5 using namespace std;
6
7 #define acquire memory_order_acquire
8 #define release memory_order_release
9 #define relaxed memory_order_relaxed
10
11 struct node {
12         node(int idx) {
13                 index.store(idx, relaxed);
14                 next.store(NULL, relaxed);
15         }
16         atomic<node*> next;/*@ \label{line:spscNodeNext} @*/
17         atomic<int> index;/*@ \label{line:spscNodeIndex} @*/
18 };/*@ \label{line:spscNodeEnd} @*/
19
20 class spsc_queue {/*@ \label{line:spscBegin} @*/
21         node *head, *tail;
22         public:
23         spsc_queue() {
24                 head = tail = new node(-1);
25         }
26         void enqueue(int idx) {
27                 node* n = new node(idx);
28                 tail->next.store(n, relaxed); // Should be release/*@ \label{line:spscRelease} @*/
29                 tail = n;
30         }
31         bool dequeue(int *idx) {
32                 node *tmp = head;
33                 node *n = tmp->next.load(relaxed); // Should be acquire/*@ \label{line:spscAcquire} @*/
34                 if (NULL == n) return false;
35                 head = n;
36                 *idx = n->index.load(relaxed);
37                 delete (tmp);
38                 return true;
39         }
40 };/*@ \label{line:spscEnd} @*/
41
42 spsc_queue *q;/*@ \label{line:testcaseBegin} @*/
43 atomic_int arr[2];
44 void thrd1() { // Thread 1/*@ \label{line:thrd1} @*/
45         arr[1].store(47, relaxed);/*@ \label{line:spscRelaxedStore} @*/
46         q->enqueue(1);
47 }
48 void thrd2() { // Thread 2/*@ \label{line:thrd2} @*/
49         int idx;
50         if (q->dequeue(&idx))
51                 arr[idx].load(relaxed);/*@ \label{line:spscRelaxedLoad} @*/
52 }/*@ \label{line:testcaseEnd} @*/
53
54 int user_main(int argc, char **argv)
55 {
56         thrd_t A, B;
57         q = new spsc_queue;
58         thrd_create(&A, (thrd_start_t)&thrd1, NULL);
59         thrd_create(&B, (thrd_start_t)&thrd2, NULL);
60         thrd_join(A);
61         thrd_join(B);
62
63         //delete q;
64
65         return 0;
66 }