Commit state of repository at time of OOPSLA 2015 submission.
[satcheck.git] / clang / test / ms-queue-simple_unannotated.c
1 #include <threads.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #define true 1
5 #define false 0
6 #define bool int
7
8 #include "ms-queue-simple.h"
9 #include "libinterface.h"
10
11 void init_queue(queue_t *q, int num_threads);
12 void enqueue(queue_t *q, unsigned int val);
13 bool dequeue(queue_t *q, unsigned int *retVal);
14
15 queue_t queue;
16
17 void init_queue(queue_t *q, int num_threads) {
18         struct node *newnode=malloc(sizeof (struct node));
19         store_32(&newnode->value, 0);
20
21         store_64(&newnode->next, (uintptr_t) NULL);
22                 /* initialize queue */
23         store_64(&q->head, (uintptr_t) newnode);
24         
25         store_64(&q->tail, (uintptr_t) newnode);
26 }
27
28 void enqueue(queue_t *q, unsigned int val) {
29         struct node *tail;
30         struct node * node_ptr = malloc(sizeof(struct node));
31         store_32(&node_ptr->value, val);
32         
33         store_64(&node_ptr->next, (uintptr_t) NULL);
34                         
35         while (true) {
36                 tail = (struct node *) load_64(&q->tail);
37                 struct node ** tail_ptr_next= & tail->next;
38
39                 struct node * next = (struct node *) load_64(tail_ptr_next);
40                 
41                 struct node * qtail = (struct node *) load_64(&q->tail);
42                 int tqt = (tail == qtail);
43                 if (tqt) {
44                         
45                         if (next) {
46                                 MC2_yield();
47                         } else {
48                                 struct node * valread = (struct node *) rmw_64(CAS, tail_ptr_next, (uintptr_t) next, (uintptr_t) node_ptr);
49                                 int vn = (valread == next);
50                                 if (vn) {
51                                         break;
52                                 } else {
53                                         MC2_yield();
54                                 }
55                         }
56                         struct node * new_tailptr = (struct node *)load_64( tail_ptr_next);
57                         rmw_64(CAS, &q->tail, (uintptr_t) tail, (uintptr_t) new_tailptr);
58                         MC2_yield();
59                 } else {
60                         MC2_yield();
61                 }
62         }
63         rmw_64(CAS, &q->tail, (uintptr_t) tail, (uintptr_t) node_ptr);
64 }
65
66 bool dequeue(queue_t *q, unsigned int *retVal) {
67         while (true) {
68                 struct node * head = (struct node *) load_64(&q->head);
69                 struct node * tail = (struct node *) load_64(&q->tail);
70                 struct node * next = (struct node *) load_64(&head->next);
71                 
72                 int t = ((struct node *) load_64(&q->head)) == head;
73                 if (t) {
74                         int ht = (head == tail);
75                         if (ht) {
76
77                                 if (next) {
78                                         MC2_yield();
79                                 } else {
80                                         return false; // NULL
81                                 }
82                                 rmw_64(CAS, &q->tail, (uintptr_t) tail, (uintptr_t) next);
83                                 MC2_yield();
84                         } else {
85                                 int nv = load_32(&next->value);
86                                 store_32(retVal, nv);
87                                 struct node *old_head = (struct node *) rmw_64(CAS, &q->head,
88                                                                                                                                                                                                                          (uintptr_t) head, 
89                                                                                                                                                                                                                          (uintptr_t) next);
90                                 int ohh = (old_head == head);
91                                 if (ohh) {
92                                         return true;
93                                 } else {
94                                         MC2_yield();
95                                 }
96                         }
97                 } else {
98                         MC2_yield();
99                 }
100         }
101 }
102
103 /* ms-queue-main */
104 bool succ1, succ2;
105
106 static void e(void *p) {
107         int i;
108         for(i=0;i<2;i++)
109         enqueue(&queue, 1);
110 }
111
112 static void d(void *p) {
113         unsigned int val;
114         int i;
115         for(i=0;i<2;i++)
116                 dequeue(&queue, &val);
117 }
118
119 int user_main(int argc, char **argv)
120 {
121         init_queue(&queue, 2);
122
123         thrd_t t1,t2;
124         thrd_create(&t1, e, NULL);
125         thrd_create(&t2, d, NULL);
126
127         thrd_join(t1);
128         thrd_join(t2);
129
130         return 0;
131 }