wow... i think this version is correct...
[model-checker-benchmarks.git] / ms-queue / my_queue.c
index efab2377d310efdf63723f6b2e188af4023c86e8..dfdf819574e49bf4914f0b5b819390bf3236c1eb 100644 (file)
@@ -61,6 +61,7 @@ void enqueue(queue_t *q, unsigned int val)
        pointer next;
        pointer tmp;
 
+       /* Get a fresh node, set its value field, then set it's next reference to null */
        node = new_node();
        store_32(&q->nodes[node].value, val);
        tmp = atomic_load_explicit(&q->nodes[node].next, relaxed);
@@ -68,29 +69,30 @@ void enqueue(queue_t *q, unsigned int val)
        atomic_store_explicit(&q->nodes[node].next, tmp, relaxed);
 
        while (!success) {
-               tail = atomic_load_explicit(&q->tail, acquire);
-               next = atomic_load_explicit(&q->nodes[get_ptr(tail)].next, acquire);
-               if (tail == atomic_load_explicit(&q->tail, acquire)) {
+               //tail isn't actually synchronization point
+               tail = atomic_load_explicit(&q->tail, relaxed);
+               //acquire reference...
+               next = atomic_load_explicit(&q->nodes[get_ptr(tail)].next, memory_order_seq_cst);
+               if (tail == atomic_load_explicit(&q->tail, memory_order_seq_cst)) {
                        if (get_ptr(next) == 0) { // == NULL
                                pointer value = MAKE_POINTER(node, get_count(next) + 1);
                                success = atomic_compare_exchange_strong_explicit(&q->nodes[get_ptr(tail)].next,
-                                               &next, value, memory_order_acq_rel, memory_order_acq_rel);
+                                               &next, value, memory_order_seq_cst, memory_order_seq_cst);
                        }
                        if (!success) {
-                               unsigned int ptr = get_ptr(atomic_load_explicit(&q->nodes[get_ptr(tail)].next, memory_order_seq_cst));
+                               unsigned int ptr = get_ptr(atomic_load_explicit(&q->nodes[get_ptr(tail)].next, memory_order_relaxed));
                                pointer value = MAKE_POINTER(ptr,
                                                get_count(tail) + 1);
                                atomic_compare_exchange_strong_explicit(&q->tail,
                                                &tail, value,
-                                               memory_order_acq_rel, memory_order_acq_rel);
-                               thrd_yield();
+                                               memory_order_seq_cst, memory_order_seq_cst);
                        }
                }
        }
        atomic_compare_exchange_strong_explicit(&q->tail,
                        &tail,
                        MAKE_POINTER(node, get_count(tail) + 1),
-                       memory_order_acq_rel, memory_order_acq_rel);
+                       memory_order_seq_cst, memory_order_seq_cst);
 }
 
 unsigned int dequeue(queue_t *q)
@@ -102,10 +104,10 @@ unsigned int dequeue(queue_t *q)
        pointer next;
 
        while (!success) {
-               head = atomic_load_explicit(&q->head, acquire);
-               tail = atomic_load_explicit(&q->tail, acquire);
-               next = atomic_load_explicit(&q->nodes[get_ptr(head)].next, acquire);
-               if (atomic_load_explicit(&q->head, acquire) == head) {
+               head = atomic_load_explicit(&q->head, memory_order_seq_cst);
+               tail = atomic_load_explicit(&q->tail, memory_order_seq_cst);
+               next = atomic_load_explicit(&q->nodes[get_ptr(head)].next, memory_order_seq_cst);
+               if (atomic_load_explicit(&q->head, memory_order_seq_cst) == head) {
                        if (get_ptr(head) == get_ptr(tail)) {
                                if (get_ptr(next) == 0) { // NULL
                                        return 0; // NULL
@@ -113,16 +115,13 @@ unsigned int dequeue(queue_t *q)
                                atomic_compare_exchange_strong_explicit(&q->tail,
                                                &tail,
                                                MAKE_POINTER(get_ptr(next), get_count(tail) + 1),
-                                               memory_order_acq_rel, memory_order_acq_rel);
-                               thrd_yield();
+                                               memory_order_seq_cst, memory_order_seq_cst);
                        } else {
                                value = load_32(&q->nodes[get_ptr(next)].value);
                                success = atomic_compare_exchange_strong_explicit(&q->head,
                                                &head,
                                                MAKE_POINTER(get_ptr(next), get_count(head) + 1),
-                                               memory_order_acq_rel, memory_order_acq_rel);
-                               if (!success)
-                                       thrd_yield();
+                                               memory_order_seq_cst, memory_order_seq_cst);
                        }
                }
        }