chronos/internal/mpsc

Search:
Group by:
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.

Types

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  

Procs

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