src/lockfreequeues/sipsic

  Source   Edit

A single-producer, single-consumer bounded queue implemented as a ring buffer.

Types

Sipsic[N; T] = object of RootObj
  head* {.align: 64.}: Atomic[int]
  tail* {.align: 64.}: Atomic[int]
  storage*: array[N, T]      ## The underlying storage.
  
A single-producer, single-consumer bounded queue implemented as a ring buffer. Pushing and popping are both wait-free.
  • N is the capacity of the queue.
  • T is the type of data the queue will hold.

head and tail are aligned on different cache lines to prevent thrashing, since reads/writes to each will be on different threads.

  Source   Edit

Consts

NoSlice = (val: (a: 0, b: 0), has: false)
  Source   Edit

Procs

proc capacity[N: static int; T](self: var Sipsic[N, T]): int {.inline.}
Returns the queue's storage capacity (N).   Source   Edit
proc initSipsic[N: static int; T](): Sipsic[N, T]
Initialize a new Sipsic queue.   Source   Edit
proc pop[N: static int; T](self: var Sipsic[N, T]): Option[T]
Pop a single item from the queue. If the queue is empty, none(T) is returned. Otherwise an item is popped, some(T) is returned.   Source   Edit
proc pop[N: static int; T](self: var Sipsic[N, T]; count: int): Option[seq[T]]
Pop count items from the queue. If the queue is empty, none(seq[T]) is returned. Otherwise some(seq[T]) is returned containing at least one item.   Source   Edit
proc push[N: static int; T](self: var Sipsic[N, T]; item: T): bool
Append a single item to the queue. If the queue is full, false is returned. If item is appended, true is returned.   Source   Edit
proc push[N: static int; T](self: var Sipsic[N, T]; items: openArray[T]): Option[
    HSlice[int, int]]
Append multiple items to the queue. If the queue is already full or is filled by this call, some(unpushed) is returned, where unpushed is an HSlice corresponding to the chunk of items which could not be pushed. If all items are appended, NoSlice is returned.   Source   Edit