All Projects → rmind → Ringbuf

rmind / Ringbuf

Licence: other
Lock-free ring buffer (MPSC)

Programming Languages

c
50402 projects - #5 most used programming language

Projects that are alternatives of or similar to Ringbuf

Thmap
Concurrent trie-hash map library
Stars: ✭ 51 (-77.53%)
Mutual labels:  algorithm, lock-free, library
Solid
🎯 A comprehensive gradient-free optimization framework written in Python
Stars: ✭ 546 (+140.53%)
Mutual labels:  algorithm, library
React Native Blurhash
🖼️ A library to show colorful blurry placeholders while your content loads.
Stars: ✭ 430 (+89.43%)
Mutual labels:  algorithm, library
Rhashmap
Robin Hood hash map library
Stars: ✭ 33 (-85.46%)
Mutual labels:  algorithm, library
Klib
A standalone and lightweight C library
Stars: ✭ 3,442 (+1416.3%)
Mutual labels:  algorithm, library
Delaunay Triangulation
C++ version the delaunay triangulation
Stars: ✭ 339 (+49.34%)
Mutual labels:  algorithm, library
Polysnap
A work in progress polygon operations library with integer snap-rounding
Stars: ✭ 14 (-93.83%)
Mutual labels:  algorithm, library
Towel
Throw in the towel.
Stars: ✭ 333 (+46.7%)
Mutual labels:  algorithm, library
Libqsbr
QSBR and EBR library
Stars: ✭ 76 (-66.52%)
Mutual labels:  algorithm, library
Swarmz
A free, header-only C++ swarming (flocking) library for real-time applications
Stars: ✭ 108 (-52.42%)
Mutual labels:  algorithm, library
Xseries
Library for cross-version Minecraft Bukkit support and various efficient API methods.
Stars: ✭ 109 (-51.98%)
Mutual labels:  algorithm, library
Arabiccompetitiveprogramming
The repository contains the ENGLISH description files attached to the video series in my ARABIC algorithms channel.
Stars: ✭ 675 (+197.36%)
Mutual labels:  algorithm, library
Cosmos
Hacktoberfest 2021 | World's largest Contributor driven code dataset | Algorithms that run our universe | Your personal library of every algorithm and data structure code that you will ever encounter |
Stars: ✭ 12,936 (+5598.68%)
Mutual labels:  algorithm, library
Dtl
diff template library written by C++
Stars: ✭ 180 (-20.7%)
Mutual labels:  algorithm, library
C Algorithms
A library of common data structures and algorithms written in C.
Stars: ✭ 2,654 (+1069.16%)
Mutual labels:  algorithm, library
Php Validate
Lightweight and feature-rich PHP validation and filtering library. Support scene grouping, pre-filtering, array checking, custom validators, custom messages. 轻量且功能丰富的PHP验证、过滤库。支持场景分组,前置过滤,数组检查,自定义验证器,自定义消息。
Stars: ✭ 225 (-0.88%)
Mutual labels:  library
Stdlib
✨ Standard library for JavaScript and Node.js. ✨
Stars: ✭ 2,749 (+1111.01%)
Mutual labels:  library
Simplenetwork
simple TCP server / client C++ linux socket
Stars: ✭ 225 (-0.88%)
Mutual labels:  library
Newnode
NewNode decentralized Content Distribution Network
Stars: ✭ 223 (-1.76%)
Mutual labels:  library
Behaviortree.js
An JavaScript implementation of Behavior Trees.
Stars: ✭ 228 (+0.44%)
Mutual labels:  library

Lock-free ring buffer

Build Status

Lock-free multi-producer single-consumer (MPSC) ring buffer which supports contiguous range operations and which can be conveniently used for message passing. The implementation is written in C11 and distributed under the 2-clause BSD license.

API

  • int ringbuf_setup(ringbuf_t *rbuf, unsigned nworkers, size_t length)

    • Setup a new ring buffer of a given length. The rbuf is a pointer to the opaque ring buffer object; the caller is responsible to allocate the space for this object. Typically, the object would be allocated dynamically if using threads or reserved in a shared memory blocked if using processes. The allocation size for the object shall be obtained using the ringbuf_get_sizes function. Returns 0 on success and -1 on failure.
  • void ringbuf_get_sizes(unsigned nworkers, size_t *ringbuf_obj_size, size_t *ringbuf_worker_size)

    • Returns the size of the opaque ringbuf_t and, optionally, ringbuf_worker_t structures. The size of the ringbuf_t structure depends on the number of workers, specified by the nworkers parameter.
  • ringbuf_worker_t *ringbuf_register(ringbuf_t *rbuf, unsigned i)

    • Register the current worker (thread or process) as a producer. Each producer MUST register itself. The i is a worker number, starting from zero (i.e. shall be than nworkers used in the setup). On success, returns a pointer to an opaque ringbuf_worker_t structured, which is a part of the ringbuf_t memory block. On failure, returns NULL.
  • void ringbuf_unregister(ringbuf_t *rbuf, ringbuf_worker_t *worker)

    • Unregister the specified worker from the list of producers.
  • ssize_t ringbuf_acquire(ringbuf_t *rbuf, ringbuf_worker_t *worker, size_t len)

    • Request a space of a given length in the ring buffer. Returns the offset at which the space is available or -1 on failure. Once the data is ready (typically, when writing to the ring buffer is complete), the ringbuf_produce function must be called to indicate that. Nested acquire calls are not allowed.
  • void ringbuf_produce(ringbuf_t *rbuf, ringbuf_worker_t *worker)

    • Indicate that the acquired range in the buffer is produced and is ready to be consumed.
  • size_t ringbuf_consume(ringbuf_t *rbuf, size_t *offset)

    • Get a contiguous range which is ready to be consumed. Returns zero if there is no data available for consumption. Once the data is consumed (typically, when reading from the ring buffer is complete), the ringbuf_release function must be called to indicate that.
  • void ringbuf_release(ringbuf_t *rbuf, size_t nbytes)

    • Indicate that the consumed range can now be released and may now be reused by the producers.

Notes

The consumer will return a contiguous block of ranges produced i.e. the ringbuf_consume call will not return partial ranges. If you think of produced range as a message, then consumer will return a block of messages, always ending at the message boundary. Such behaviour allows us to use this ring buffer implementation as a message queue.

The implementation was extensively tested on a 24-core x86 machine, see the stress test for the details on the technique. It also provides an example how the mechanism can be used for message passing.

Caveats

This ring buffer implementation always provides a contiguous range of space for the producer. It is achieved by an early wrap-around if the requested range cannot fit in the end. The implication of this is that the ringbuf_acquire call may fail if the requested range is greater than half of the buffer size. Hence, it may be necessary to ensure that the ring buffer size is at least twice as large as the maximum production unit size.

It should also be noted that one of the trade-offs of such design is that the consumer currently performs an O(n) scan on the list of producers.

Example

Producers:

if ((w = ringbuf_register(r, worker_id)) == NULL)
	err(EXIT_FAILURE, "ringbuf_register")

...

if ((off = ringbuf_acquire(r, w, len)) != -1) {
	memcpy(&buf[off], payload, len);
	ringbuf_produce(r, tls);
}

Consumer:

if ((len = ringbuf_consume(r, &off)) != 0) {
	process(&buf[off], len);
	ringbuf_release(r, len);
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].