9#include <condition_variable>
21 template <
class T,
size_t CAPACITY>
25#pragma warning(suppress:26495)
37 std::tuple<T*, size_t>
back()
39 std::unique_lock<std::mutex> lk(m_mutex);
41 m_head_moved.wait(lk, [&]{
return m_quit || space();});
42 if (m_quit) _Unlikely_
43 return {
nullptr, 0 };
45 size_t tail = wrap(m_head + m_size);
46 return { &m_data[tail], m_head <= tail ? CAPACITY - tail : m_head - tail };
54 void push(_In_
size_t size)
57 const std::lock_guard<std::mutex> lg(m_mutex);
59 size_t tail = wrap(m_head + m_size);
60 _Assume_(size <= (m_head <= tail ? CAPACITY - tail : m_head - tail));
64 m_tail_moved.notify_one();
74 std::unique_lock<std::mutex> lk(m_mutex);
76 m_tail_moved.wait(lk, [&]{
return m_quit || !empty();});
77 if (m_quit && empty()) _Unlikely_
78 return {
nullptr, 0 };
80 size_t tail = wrap(m_head + m_size);
81 return { &m_data[m_head], m_head < tail ? m_size : CAPACITY - m_head };
89 void pop(_In_
size_t size)
92 const std::lock_guard<std::mutex> lg(m_mutex);
94 size_t tail = wrap(m_head + m_size);
95 _Assume_(size <= (m_head < tail ? m_size : CAPACITY - m_head));
97 m_head = wrap(m_head + size);
100 m_head_moved.notify_one();
109 const std::lock_guard<std::mutex> lg(m_mutex);
112 m_head_moved.notify_one();
113 m_tail_moved.notify_one();
121 std::unique_lock<std::mutex> lk(m_mutex);
122 m_head_moved.wait(lk, [&]{
return m_quit || empty();});
126 inline size_t wrap(_In_
size_t idx)
const
129 return idx % CAPACITY;
132 inline size_t space()
const
134 return CAPACITY - m_size;
137 inline bool empty()
const
144 std::condition_variable m_head_moved, m_tail_moved;
145 size_t m_head, m_size;
Ring buffer.
Definition ring.hpp:23
void quit()
Cancells waiting sender and receiver.
Definition ring.hpp:106
std::tuple< T *, size_t > back()
Allocates the data after the ring tail. Use push() after the allocated data is populated.
Definition ring.hpp:37
void pop(size_t size)
Notifies the sender the data was consumed.
Definition ring.hpp:89
void sync()
Waits until the ring is flush.
Definition ring.hpp:119
std::tuple< T *, size_t > front()
Peeks the data at the ring head. Use pop() after the data was consumed.
Definition ring.hpp:72
void push(size_t size)
Notifies the receiver the data was populated.
Definition ring.hpp:54