Giter Site home page Giter Site logo

jpcima / ring-buffer Goto Github PK

View Code? Open in Web Editor NEW
34.0 4.0 5.0 24 KB

Ring buffer library for C++17

License: Boost Software License 1.0

CMake 5.98% C++ 94.02%
ring-buffer real-time soft-real-time audio low-latency multithreading message-queue fifo-queue cpp17

ring-buffer's Introduction

ring-buffer

Status

This package provides ring buffer classes for use with C++17.

C++17 features are used if available, and backward compatibility is implemented up to C++14.

Description

The purpose of a ring buffer is to provide a unidirectional FIFO communication from a thread to another. The implementation of this data structure can be lock-free, making it suitable for real-time programming.

I implement two variants of the ring buffer.

  • Ring_Buffer is a bounded, lock-free ring buffer. The capacity is fixed and determined at instantiation. It can only store messages up to the capacity of the buffer.
  • Soft_Ring_Buffer is an unbounded, mostly lock-free ring buffer. The storage expands as write operations require it, by a factor of 1.5. The access is protected by a shared-exclusive lock, and only blocks while the buffer expands. This object is adequate for soft real-time, when communicating all the messages is more important than missing a few deadlines.

Programming interface

Ring_Buffer(size_t capacity);

Instantiate the ring buffer with the given capacity.

size_t capacity() const;

Return the capacity.

Writer interface

size_t size_free() const;

Return the number of bytes available to write to.

template <class T> bool put(const T &x);

If the buffer has enough room (or the buffer is unbounded), store the sizeof(T) bytes of x, then return true. Otherwise, return false.

template <class T> bool put(const T *x, size_t n);

Similar to put above, except it stores an array of n consecutive T elements.

Reader interface

size_t size_used() const;

Return the number of bytes available to read.

bool discard(size_t len);

If the ringbuffer contains at least len bytes, extract them and ignore them, then return true. Otherwise, return false.

template <class T> bool get(T &x);

If the buffer contains enough data, extract sizeof(T) bytes and assign this data to x, then return true. Otherwise, return false.

template <class T> bool get(T *x, size_t n);

Similar to get above, except it extracts an array of n consecutive T elements.

template <class T> bool peek(T &x);

If the buffer contains enough data, extract sizeof(T) bytes without removing them from storage, assign this data to x, then return true. Otherwise, return false.

template <class T> bool peek(T *x, size_t n);

Similar to peek above, except it extracts an array of n consecutive T elements.

ring-buffer's People

Contributors

jpcima avatar wohlstand 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

Watchers

 avatar  avatar  avatar  avatar

ring-buffer's Issues

Need a detection of compiler's support for C++17 with fallback to C++14

Also, at me system GCC-5.4 doesn't supports C++17, but supports C++14. Configure fails when C++17 is set, however, works perfect when C++14 is set in CMakeLists.txt. Why not to detect C++17 support or even just rely on GCC version to specify C++ standard available since specific version.

Concurrent writes to Ring_Buffer are not thread-safe.

The following is an excerpt from ring_buffer.cc, see
https://github.com/jpcima/ring-buffer/blob/e0c7b5ee052ab67cecdf26ca20dda77363506a5d/sources/ring_buffer.cc#L127C1-L147C2

template <bool Atomic>
bool Ring_Buffer_Ex<Atomic>::putbytes_(const void *data, size_t len)
{
    if (len == 0)
        return true;

    if (size_free() < len)
        return false;

    const size_t wp = atomic_load_maybe(wp_, std::memory_order_relaxed);
    const size_t cap = cap_;
    const uint8_t *src = (const uint8_t *)data;
    uint8_t *dst = rbdata_.get();

    const size_t taillen = std::min(len, cap - wp);
    std::copy_n(src, taillen, &dst[wp]);
    std::copy_n(src + taillen, len - taillen, dst);

    atomic_store_maybe(wp_, (wp + len < cap) ? (wp + len) : (wp + len - cap), std::memory_order_release);
    return true;
}

I believe concurrent calls to Ring_Buffer::put(...) can cause a data race on the same memory region currently pointed to by wp_. There is no protection against two threads concurrently executing

const size_t wp = atomic_load_maybe(wp_, std::memory_order_relaxed);

and subsequently writing to the same address &dst[wp]. Specifically, the update of wp is not atomic. I believe this can lead to a lost update or corrupted data. As such, Ring_Buffer is not thread-safe.

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.