6 static unsigned int *node_nums;
8 static unsigned int new_node()
10 return node_nums[get_thread_num()];
13 static void reclaim(unsigned int node)
15 node_nums[get_thread_num()] = node;
18 void init_queue(queue_t *q, int num_threads)
25 node_nums = malloc(num_threads * sizeof(*node_nums));
26 for (i = 0; i < num_threads; i++)
29 /* initialize queue */
30 head = MAKE_POINTER(1, 0);
31 tail = MAKE_POINTER(1, 0);
32 next = MAKE_POINTER(0, 0); // (NULL, 0)
34 atomic_store(&q->head, head);
35 atomic_store(&q->tail, tail);
36 atomic_store(&q->nodes[1].next, next);
38 /* initialize avail list */
39 for (i = 2; i < MAX_NODES; i++) {
40 next = MAKE_POINTER(i + 1, 0);
41 atomic_store(&q->nodes[i].next, next);
44 next = MAKE_POINTER(0, 0); // (NULL, 0)
45 atomic_store(&q->nodes[MAX_NODES].next, next);
48 void enqueue(queue_t *q, unsigned int val)
57 q->nodes[node].value = val;
58 tmp = atomic_load(&q->nodes[node].next);
59 set_ptr(&tmp, 0); // NULL
60 atomic_store(&q->nodes[node].next, tmp);
63 tail = atomic_load(&q->tail);
64 next = atomic_load(&q->nodes[get_ptr(tail)].next);
65 if (tail == atomic_load(&q->tail)) {
66 if (get_ptr(next) == 0) { // == NULL
67 pointer value = MAKE_POINTER(node, get_count(next) + 1);
68 success = atomic_compare_exchange_weak(&q->nodes[get_ptr(tail)].next,
72 unsigned int ptr = get_ptr(atomic_load(&q->nodes[get_ptr(tail)].next));
73 pointer value = MAKE_POINTER(ptr,
75 atomic_compare_exchange_strong(&q->tail,
81 atomic_compare_exchange_strong(&q->tail,
83 MAKE_POINTER(node, get_count(tail) + 1));
86 unsigned int dequeue(queue_t *q)
95 head = atomic_load(&q->head);
96 tail = atomic_load(&q->tail);
97 next = atomic_load(&q->nodes[get_ptr(head)].next);
98 if (atomic_load(&q->head) == head) {
99 if (get_ptr(head) == get_ptr(tail)) {
100 if (get_ptr(next) == 0) { // NULL
103 atomic_compare_exchange_strong(&q->tail,
105 MAKE_POINTER(get_ptr(next), get_count(tail) + 1));
108 value = q->nodes[get_ptr(next)].value;
109 success = atomic_compare_exchange_weak(&q->head,
111 MAKE_POINTER(get_ptr(next), get_count(head) + 1));
117 reclaim(get_ptr(head));