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