Note that there are some explanatory texts on larger screens.

plurals
  1. POAre there any implementations of concurrent lock-free blocking queues?
    primarykey
    data
    text
    <p>I'm aware of blocking-queues and lock-free queues, a great example of those implementations being provided by <a href="http://www.research.ibm.com/people/m/michael/podc-1996.pdf" rel="nofollow">Scott et al.</a>, but are there any implementations of a lock-free-blocking-queue?</p> <p>In a lock-free-blocking-queue the dequeue will require no locking, but if there are no items in the queue it will block the consumer. Are there any implementations of such a beast? I prefer if they're C# implementations, but any implementation would technically work.</p> <p><strong>Update:</strong> </p> <p>I think I end up with a race condition on line D14.1:</p> <pre><code>initialize(Q: pointer to queue t) node = new node() // Allocate a free node node–&gt;next.ptr = NULL // Make it the only node in the linked list Q–&gt;Head = Q–&gt;Tail = node // Both Head and Tail point to it signal = new ManualResetEvent() // create a manual reset event enqueue(Q: pointer to queue t, value: data type) E1: node = new node() // Allocate a new node from the free list E2: node–&gt;value = value // Copy enqueued value into node E3: node–&gt;next.ptr = NULL // Set next pointer of node to NULL E4: loop // Keep trying until Enqueue is done E5: tail = Q–&gt;Tail // Read Tail.ptr and Tail.count together E6: next = tail.ptr–&gt;next // Read next ptr and count fields together E7: if tail == Q–&gt;Tail // Are tail and next consistent? E8: if next.ptr == NULL // Was Tail pointing to the last node? E9: if CAS(&amp;tail.ptr–&gt;next, next, &lt;node, next.count+1&gt;) // Try to link node at the end of the linked list E10.1: signal.Set() // Signal to the blocking dequeues E10.2: break // Enqueue is done. Exit loop E11: endif E12: else // Tail was not pointing to the last node E13: CAS(&amp;Q–&gt;Tail, tail, &lt;next.ptr, tail.count+1&gt;) // Try to swing Tail to the next node E14: endif E15: endif E16: endloop E17: CAS(&amp;Q–&gt;Tail, tail, &lt;node, tail.count+1&gt;) // Enqueue is done. Try to swing Tail to the inserted node dequeue(Q: pointer to queue t, pvalue: pointer to data type): boolean D1: loop // Keep trying until Dequeue is done D2: head = Q–&gt;Head // Read Head D3: tail = Q–&gt;Tail // Read Tail D4: next = head–&gt;next // Read Head.ptr–&gt;next D5: if head == Q–&gt;Head // Are head, tail, and next consistent? D6: if head.ptr == tail.ptr // Is queue empty or Tail falling behind? D7: if next.ptr == NULL // Is queue empty? D8.1: signal.WaitOne() // Block until an enqueue D8.X: // remove the return --- return FALSE // Queue is empty, couldn’t dequeue D9: endif D10: CAS(&amp;Q–&gt;Tail, tail, &lt;next.ptr, tail.count+1&gt;) // Tail is falling behind. Try to advance it D11: else // No need to deal with Tail // Read value before CAS, otherwise another dequeue might free the next node D12: *pvalue = next.ptr–&gt;value D13: if CAS(&amp;Q–&gt;Head, head, &lt;next.ptr, head.count+1&gt;) // Try to swing Head to the next node D14.1: if(head.ptr == tail.ptr &amp;&amp; next.ptr==NULL) // Is queue empty? &lt;--- POSSIBLE RACE CONDITION??? D14.2: signal.Reset() D14.3: break // Dequeue is done. Exit loop D15: endif D16: endif D17: endif D18: endloop D19: free(head.ptr) // It is safe now to free the old dummy node D20: return TRUE // Queue was not empty, dequeue succeeded </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload