Merge branch 'feature/e-endstop' into merge-abc-with-homing
[clinton/Smoothieware.git] / src / libs / TSRingBuffer.h
1 //
2 // Simple fixed size ring buffer.
3 // Manage objects by value.
4 // Thread safe for single Producer and single Consumer.
5 // By Dennis Lang http://home.comcast.net/~lang.dennis/code/ring/ring.html
6 // Slightly modified for naming
7
8 #pragma once
9
10 template <class T, size_t RingSize>
11 class TSRingBuffer
12 {
13 public:
14 TSRingBuffer()
15 : m_size(RingSize), m_buffer(new T[RingSize]), m_rIndex(0), m_wIndex(0)
16 { }
17
18 ~TSRingBuffer()
19 {
20 delete [] m_buffer;
21 };
22
23 size_t next(size_t n) const
24 {
25 return (n + 1) % m_size;
26 }
27
28 bool empty() const
29 {
30 return (m_rIndex == m_wIndex);
31 }
32
33 bool full() const
34 {
35 return (next(m_wIndex) == m_rIndex);
36 }
37
38 bool put(const T &value)
39 {
40 if (full())
41 return false;
42 m_buffer[m_wIndex] = value;
43 m_wIndex = next(m_wIndex);
44 return true;
45 }
46
47 bool get(T &value)
48 {
49 if (empty())
50 return false;
51 value = m_buffer[m_rIndex];
52 m_rIndex = next(m_rIndex);
53 return true;
54 }
55
56 private:
57 size_t m_size;
58 T *m_buffer;
59
60 // volatile is only used to keep compiler from placing values in registers.
61 // volatile does NOT make the index thread safe.
62 volatile size_t m_rIndex;
63 volatile size_t m_wIndex;
64 };