49template<
typename T,
size_t max_count = default_count>
class ringbuffer {
66 TracePrintln(
"ringbuffer",
"");
71 int getFullCount()
const {
return fullCount; }
73 int getEmptyCount()
const {
return emptyCount; }
75 int getWriteCount()
const {
return writeCount; }
79 std::unique_lock<std::mutex> lk(mutex);
80 write_index = read_index = 0;
86 std::unique_lock<std::mutex> lk(mutex);
89 write_index = max_count / 2;
90 nonfullCV.notify_all();
91 nonemptyCV.notify_all();
94 void setBlockSize(
int size)
96 TracePrintln(
"ringbuffer",
"");
98 if (block_size != size)
102 int aligned_block_size = (block_size + ALIGN - 1) & (~(ALIGN - 1));
104 DebugPrintln(
"ringbuffer",
"New raw buffer size : %ld", max_count * aligned_block_size);
106 for(
auto it = buffers.begin(); it < buffers.end(); it++)
108 it->resize(aligned_block_size);
113 T* peekWritePtr(
int offset)
115 return buffers[(write_index.load() + max_count + offset) % max_count].data();
118 T* peekReadPtr(
int offset)
120 return buffers[(read_index.load() + max_count + offset) % max_count].data();
123 void push(std::vector<T> arr)
127 std::unique_lock<std::mutex> lk(mutex);
129 buffers[write_index] = arr;
131 write_index = (write_index + 1) % max_count;
134 if (blocks_available == 1)
136 nonemptyCV.notify_all();
146 std::unique_lock<std::mutex> lk(mutex);
148 std::vector<T> vec = buffers[read_index];
150 read_index = (read_index + 1) % max_count;
153 if (blocks_available == max_count - 1)
155 nonfullCV.notify_all();
161 int getBlockSize()
const {
return block_size; }
163 void WaitUntilNotEmpty()
168 for (
int i = 0; i < spin_count; i++)
170 if (blocks_available > 0)
174 if(blocks_available <= 0)
176 std::unique_lock<std::mutex> lk(mutex);
179 nonemptyCV.wait(lk, [
this] {
180 return blocks_available > 0;
185 void WaitUntilNotFull()
189 for (
int i = 0; i < spin_count; i++)
191 if (blocks_available < max_count)
195 if (blocks_available >= max_count)
197 std::unique_lock<std::mutex> lk(mutex);
199 nonfullCV.wait(lk, [
this] {
200 return blocks_available < max_count;
205 volatile std::atomic<size_t> read_index;
206 volatile std::atomic<size_t> write_index;
207 volatile std::atomic<size_t> blocks_available;
216 std::condition_variable nonemptyCV;
217 std::condition_variable nonfullCV;
221 std::array<std::vector<T>, max_count> buffers;