Improve handling the async wake interval
[alure.git] / src / ringbuf.h
blob54da2f3a7acba037c32d4ed897c4207b31dd92d1
1 #ifndef RINGBUF_H
2 #define RINGBUF_H
4 #include "alure2.h"
6 #include <atomic>
7 #include <array>
9 namespace alure
12 /* NOTE: This lockless ringbuffer implementation is based on JACK's, extended
13 * to include an element size. Consequently, parameters and return values for a
14 * size or count is in 'elements', not bytes. Additionally, it only supports
15 * single-consumer/single-provider operation.
17 class RingBuffer {
18 std::atomic<size_t> mWritePtr;
19 std::atomic<size_t> mReadPtr;
20 size_t mSize;
21 size_t mSizeMask;
22 size_t mElemSize;
24 UniquePtr<char[]> mBuffer;
26 public:
27 struct Data {
28 char *buf;
29 size_t len;
32 /* Create a new ringbuffer to hold at least `sz' elements of `elem_sz'
33 * bytes. The number of elements is rounded up to the next power of two.
35 RingBuffer(size_t sz, size_t elem_sz);
36 RingBuffer(const RingBuffer&) = delete;
38 /* Reset the read and write pointers to zero. This is not thread safe. */
39 void reset();
41 /* Return the number of elements available for reading. This is the number
42 * of elements in front of the read pointer and behind the write pointer.
44 size_t read_space() const;
46 /* Return the number of elements available for writing. This is the number
47 * of elements in front of the write pointer and behind the read pointer.
49 size_t write_space() const;
51 /* The copying data reader. Copy at most `cnt' elements to `dest'. Returns
52 * the actual number of elements copied.
54 size_t read(char *dest, size_t cnt);
56 /* The copying data reader w/o read pointer advance. Copy at most `cnt'
57 * elements to `dest'. Returns the actual number of elements copied.
59 size_t peek(char *dest, size_t cnt);
61 /* The copying data writer. Copy at most `cnt' elements from `src'. Returns
62 * the actual number of elements copied.
64 size_t write(const char *src, size_t cnt);
66 /* Advance the read pointer `cnt' places. */
67 void read_advance(size_t cnt);
69 /* Advance the write pointer `cnt' places. */
70 void write_advance(size_t cnt);
72 /* The non-copying data reader. `vec' is an array of two places. Set the
73 * values at `vec' to hold the current readable data. If the readable data
74 * is in one segment the second segment has zero length.
76 Array<Data,2> get_read_vector() const;
78 /* The non-copying data writer. `vec' is an array of two places. Set the
79 * values at `vec' to hold the current writeable data. If the writeable
80 * data is in one segment the second segment has zero length.
82 Array<Data,2> get_write_vector() const;
85 } // namespace alure
87 #endif /* RINGBUF_H */