Giter VIP home page Giter VIP logo

lockfreequeues's Introduction

build lint build-docs Join the chat at https://gitter.im/lockfreequeues/community

lockfreequeues

Lock-free queues for Nim, implemented as ring buffers.

Three implementations are provided:

  • Sipsic is a single-producer, single-consumer bounded queue. Pushing and popping are wait-free.
  • Mupsic is a multi-producer, single-consumer bounded queue. Popping is wait-free.
  • Mupmuc is a multi-producer, multi-consumer bounded queue.

API documentation: https://elijahr.github.io/lockfreequeues

Installation

nimble install lockfreequeues

Examples

Examples are located in the examples directory and can be compiled and run with:

nimble examples

Reference

Many thanks to Mamy Ratsimbazafy for reviewing the initial release and offering suggestions.

Contributing

  • Pull requests and feature requests are welcome!
  • Please file any issues you encounter.
  • For pull requests, please see the contribution guidelines.

Running tests

Tests can be run locally with nimble test.

CI runs the test suite for both C and C++ targets on:

  • Linux x86_64 and aarch64
  • macOS x86_64

The test suite is also run with LLVM thread sanitization to check for data races.

Linting

This project uses lintball to auto-format code. Please ensure your changeset passes linting. Enable the githooks with:

git config --local core.hooksPath .githooks

lockfreequeues's People

Contributors

elijahr avatar gitter-badger avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

lockfreequeues's Issues

Quick Review

Hello there, thanks for your interest in Nim!

A quick review of your code:

Padding

Instead of padding with arrays

type
SPSCQueueInterface* = object
head*: Atomic[uint]
# padding forces head and tail to different cache lines
padding: array[CACHELINE_BYTES, char]
tail*: Atomic[uint]

you can do

type
  SPSCQueueInterface* = object
    head* {.align: CACHELINE_BYTES.}: Atomic[uint]
    tail* {.align: CACHELINE_BYTES.}: Atomic[uint]

I recommend that you pad the start of the data structure as well since queues are often used in an arrays of queues:

SharedQueue*[T] = object
## A single-producer, single-consumer queue, suitable for when the max
## capacity is known at run-time or when the queue should reside in shared
## memory.
capacity*: int
face: ptr SPSCQueueInterface
storage: ptr UncheckedArray[T]

Sizing

Currently your buffer requires being a power of 2, this wastes memory for large buffers
Instead, to distinguish between the empty and the full queue, you can have your capacity run from 0 ..< 2*RealCapacity

See https://github.com/mratsim/weave/blob/master/weave/cross_thread_com/channels_spsc.md#litterature

And implementation in Nim for a serial queue: https://github.com/mratsim/weave/blob/2e528bd2/weave/datatypes/bounded_queues.nim

Misc

You don't need to return a seq here, you can return an array, it will be copied

proc state*[N: static int, T](
self: var StaticQueue[N, T],
): tuple[
head: uint,
tail: uint,
storage: seq[T],
] =
## Retrieve current state of the queue
let faceState = self.face.state
return (
head: faceState.head,
tail: faceState.tail,
storage: self.storage[0..^1],
)

Though the state might have torn copies.

Use correct memory orderings

hello, first of thank you for making this! Ive noticed you use moRelaxed everywhere, this is obviously not correct, as it leads to data races. One way to test this is with ThreadSanitizer, an example. An oversimplification, but a good starting point is to make all loads moAcquire and stores moRelease. Basically you need to do the publishing protocol. You can use moRelaxed when outside or inside a "critical section" (I think but that might also be an oversimplification), that is code between a load and a store.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.