18 #ifndef RAUL_RING_BUFFER_HPP
19 #define RAUL_RING_BUFFER_HPP
30 #include "raul/log.hpp"
45 :
_buf(static_cast<char*>(malloc(size)))
49 assert(read_space() == 0);
50 assert(write_space() == size - 1);
61 g_atomic_int_set(&_write_ptr, 0);
62 g_atomic_int_set(&_read_ptr, 0);
65 uint32_t write_space()
const {
66 const uint32_t w = g_atomic_int_get(&_write_ptr);
67 const uint32_t r = g_atomic_int_get(&_read_ptr);
78 uint32_t read_space()
const {
79 const uint32_t w = g_atomic_int_get(&_write_ptr);
80 const uint32_t r = g_atomic_int_get(&_read_ptr);
89 uint32_t capacity()
const {
return _size; }
91 uint32_t
peek(uint32_t size,
void* dst);
92 bool full_peek(uint32_t size,
void* dst);
94 uint32_t
read(uint32_t size,
void* dst);
95 bool full_read(uint32_t size,
void* dst);
97 bool skip(uint32_t size);
99 void write(uint32_t size,
const void* src);
102 mutable uint32_t _write_ptr;
103 mutable uint32_t _read_ptr;
119 const uint32_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
121 const uint32_t read_size = (priv_read_ptr + size <
_size)
123 :
_size - priv_read_ptr;
125 memcpy(dst, &
_buf[priv_read_ptr], read_size);
132 RingBuffer::full_peek(uint32_t size,
void* dst)
134 if (read_space() < size) {
138 const uint32_t read_size =
peek(size, dst);
140 if (read_size < size) {
141 peek(size - read_size, (
char*)dst + read_size);
157 const uint32_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
159 const uint32_t read_size = (priv_read_ptr + size <
_size)
161 :
_size - priv_read_ptr;
163 memcpy(dst, &
_buf[priv_read_ptr], read_size);
165 g_atomic_int_set(&_read_ptr, (priv_read_ptr + read_size) %
_size);
172 RingBuffer::full_read(uint32_t size,
void* dst)
174 if (read_space() < size) {
178 const uint32_t read_size =
read(size, dst);
180 if (read_size < size) {
181 read(size - read_size, (
char*)dst + read_size);
189 RingBuffer::skip(uint32_t size)
191 if (read_space() < size) {
192 warn <<
"Attempt to skip past end of RingBuffer" << std::endl;
196 const uint32_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
197 g_atomic_int_set(&_read_ptr, (priv_read_ptr + size) %
_size);
204 RingBuffer::write(uint32_t size,
const void* src)
206 const uint32_t priv_write_ptr = g_atomic_int_get(&_write_ptr);
208 if (priv_write_ptr + size <=
_size) {
209 memcpy(&
_buf[priv_write_ptr], src, size);
210 g_atomic_int_set(&_write_ptr, (priv_write_ptr + size) %
_size);
212 const uint32_t this_size =
_size - priv_write_ptr;
213 assert(this_size < size);
214 assert(priv_write_ptr + this_size <=
_size);
215 memcpy(&
_buf[priv_write_ptr], src, this_size);
216 memcpy(&
_buf[0], (
char*)src + this_size, size - this_size);
217 g_atomic_int_set(&_write_ptr, size - this_size);
224 #endif // RAUL_RING_BUFFER_HPP
void reset()
Reset(empty) the ringbuffer.
Definition: RingBuffer.hpp:60
uint32_t peek(uint32_t size, void *dst)
Peek at the ringbuffer (read w/o advancing read pointer).
Definition: RingBuffer.hpp:117
A lock-free RingBuffer.
Definition: RingBuffer.hpp:40
char *const _buf
Contents.
Definition: RingBuffer.hpp:105
RingBuffer(uint32_t size)
Definition: RingBuffer.hpp:44
uint32_t read(uint32_t size, void *dst)
Read from the ringbuffer.
Definition: RingBuffer.hpp:155
const uint32_t _size
Size (capacity) in bytes.
Definition: RingBuffer.hpp:106