add another testcase for dekker-fences
[model-checker-benchmarks.git] / ms-queue / queue_wildcard.c
index 43a2de2cf743fbe0d6b85530ae648866b3e3548f..802e6f622bf889313d9252aecc137b9fc0df6e87 100644 (file)
@@ -32,6 +32,12 @@ static unsigned int new_node()
        return 0;
 }
 
+/* Simulate the fact that when a node got recycled, it will get assigned to the
+ * same queue or for other usage */
+void simulateRecycledNodeUpdate(queue_t *q, unsigned int node) {
+       atomic_store_explicit(&q->nodes[node].next, -1, memory_order_release);
+}
+
 /* Place this node index back on this thread's free list */
 static void reclaim(unsigned int node)
 {
@@ -77,7 +83,7 @@ void init_queue(queue_t *q, int num_threads)
        atomic_init(&q->nodes[1].next, MAKE_POINTER(0, 0));
 }
 
-void enqueue(queue_t *q, unsigned int val)
+void enqueue(queue_t *q, unsigned int val, bool yield)
 {
        int success = 0;
        unsigned int node;
@@ -94,7 +100,9 @@ void enqueue(queue_t *q, unsigned int val)
 
        while (!success) {
                tail = atomic_load_explicit(&q->tail, wildcard(3)); // acquire
-               // FIXME: SCFence makes this relaxed 
+               // FIXME: SCFence makes this relaxed
+               if (yield)
+                       thrd_yield();
                next = atomic_load_explicit(&q->nodes[get_ptr(tail)].next, wildcard(4)); //acquire
                if (tail == atomic_load_explicit(&q->tail, wildcard(5))) { // relaxed
 
@@ -108,7 +116,7 @@ void enqueue(queue_t *q, unsigned int val)
                        }
                        if (!success) {
                                unsigned int ptr =
-                               get_ptr(atomic_load_explicit(&q->nodes[get_ptr(tail)].next, wildcard(8))); // acquire
+                                       get_ptr(atomic_load_explicit(&q->nodes[get_ptr(tail)].next, wildcard(8))); // acquire
                                pointer value = MAKE_POINTER(ptr,
                                                get_count(tail) + 1);
                                atomic_compare_exchange_strong_explicit(&q->tail,
@@ -124,7 +132,7 @@ void enqueue(queue_t *q, unsigned int val)
                        wildcard(11), wildcard(12)); // release & relaxed
 }
 
-bool dequeue(queue_t *q, unsigned int *retVal)
+bool dequeue(queue_t *q, unsigned int *retVal, unsigned int *reclaimNode)
 {
        unsigned int value;
        int success = 0;
@@ -154,7 +162,6 @@ bool dequeue(queue_t *q, unsigned int *retVal)
                        } else {
                                //value = load_32(&q->nodes[get_ptr(next)].value);
                                value = q->nodes[get_ptr(next)].value;
-                               // FIXME: SCFence makes this relaxed 
                                success = atomic_compare_exchange_strong_explicit(&q->head,
                                                &head, MAKE_POINTER(get_ptr(next), get_count(head) + 1),
                                                wildcard(19), wildcard(20)); // release & relaxed
@@ -163,6 +170,8 @@ bool dequeue(queue_t *q, unsigned int *retVal)
                        }
                }
        }
+
+       reclaimNode = get_ptr(head);
        reclaim(get_ptr(head));
        *retVal = value;
        return true;