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)
{
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;
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
}
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,
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;
while (!success) {
head = atomic_load_explicit(&q->head, wildcard(13)); // acquire
- // FIXME: SCFence makes this acquire
+ // SCFence makes this acquire, and we actually need an acquire here!!!
tail = atomic_load_explicit(&q->tail, wildcard(14)); // relaxed
next = atomic_load_explicit(&q->nodes[get_ptr(head)].next, wildcard(15)); // acquire
if (atomic_load_explicit(&q->head, wildcard(16)) == head) { // relaxed
} 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
}
}
}
+
+ reclaimNode = get_ptr(head);
reclaim(get_ptr(head));
*retVal = value;
return true;