9 #include "libinterface.h"
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);
15 void init_queue(queue_t *q, int num_threads) {
17 struct node *newnode=malloc(sizeof (struct node));
18 store_32(&newnode->value, 0);
20 store_64(&newnode->next, (uintptr_t) MAKE_POINTER(NULL, 0LL));
21 /* initialize queue */
22 store_64(&q->head, (uintptr_t) MAKE_POINTER(newnode, 0LL));
24 store_64(&q->tail, (uintptr_t) MAKE_POINTER(newnode, 0LL));
27 void enqueue(queue_t *q, unsigned int val) {
29 struct node * node_ptr = malloc(sizeof(struct node));
30 store_32(&node_ptr->value, val);
32 store_64(&node_ptr->next, (uintptr_t) MAKE_POINTER(NULL, GET_COUNT(1)));
35 tail = (struct node *) load_64(&q->tail);
36 struct node ** tail_ptr_next= & GET_PTR(tail)->next;
38 struct node * next = (struct node *) load_64(tail_ptr_next);
40 struct node * qtail = (struct node *) load_64(&q->tail);
41 int tqt = (tail == qtail);
43 struct node *next_ptr=GET_PTR(next);
45 int npn = (next_ptr == NULL);
47 struct node * new_node = MAKE_POINTER(node_ptr, GET_COUNT(next) +1);
48 struct node * valread = (struct node *) rmw_64(CAS, tail_ptr_next, (uintptr_t) next, (uintptr_t) new_node);
49 int vn = (valread == next);
58 struct node * new_tailptr = GET_PTR(load_64( tail_ptr_next));
59 struct node * newtail = MAKE_POINTER(new_tailptr, GET_COUNT(tail) + 1);
60 rmw_64(CAS, &q->tail, (uintptr_t) tail, (uintptr_t) newtail);
66 rmw_64(CAS, &q->tail, (uintptr_t) tail, (uintptr_t)MAKE_POINTER(node_ptr, GET_COUNT(tail) + 1));
69 bool dequeue(queue_t *q, unsigned int *retVal) {
71 struct node * head = (struct node *) load_64(&q->head);
72 struct node * tail = (struct node *) load_64(&q->tail);
73 struct node * next = (struct node *) load_64(&(GET_PTR(head)->next));
75 int t = ((struct node *) load_64(&q->head)) == head;
77 if (GET_PTR(head) == GET_PTR(tail)) {
79 if (GET_PTR(next) == NULL) {
84 rmw_64(CAS, &q->tail, (uintptr_t) tail, (uintptr_t) MAKE_POINTER(GET_PTR(next), GET_COUNT(tail) + 1));
87 int nv = load_32(&GET_PTR(next)->value);
89 struct node * nh = MAKE_POINTER(GET_PTR(next), GET_COUNT(head)+1);
90 struct node *old_head = (struct node *) rmw_64(CAS, &q->head,
93 if (old_head == head) {
104 static queue_t queue;
107 static void e(void *p) {
113 static void d(void *p) {
117 dequeue(&queue, &val);
120 int user_main(int argc, char **argv)
122 init_queue(&queue, 2);
125 thrd_create(&t1, e, NULL);
126 thrd_create(&t2, d, NULL);