Source
Edit
Intrusive multi-producer, single-consumer linked list courtesy of D.Vyukov:
https://groups.google.com/g/lock-free/c/Vd9xuHrLggE/m/B9-URa3B37MJ
https://github.com/grivet/mpsc-queue/blob/main/mpsc-queue.h is a modernised version thereof upon which this implementation is based.
MpscNode {.inheritable, pure.} = object
next*: Atomic[ptr MpscNode]
-
Base node type. All node types used with MpscQueue should embed or inherit from this, or at minimum have an Atomic[ptr MpscNode] field named next.
Source
Edit
MpscQueue[T] = object
-
Lock-free Michael & Scott MPSC queue parameterized by node type T.
T must have an Atomic[ptr T] field called next (which is naturally the case if T embeds MpscNode or declares its own next field of the right type).
Source
Edit
proc init[T](q: var MpscQueue[T]) {....raises: [], gcsafe.}
-
Initialize the queue - must be called before any other ops
Source
Edit
proc pop[T](q: var MpscQueue[T]): ptr T {....raises: [], gcsafe.}
-
Try to pop the next node. Returns true if an item was popped, and nil otherwise.
Only a single consumer may call this function concurrently.
Source
Edit
proc push[T](q: var MpscQueue[T]; node: ptr T) {....raises: [], gcsafe.}
-
Push a node into the queue - may be called concurrently by multiple producers.
Source
Edit