@@ -37,10 +37,12 @@ template <int N>
37
37
class RingBufferN
38
38
{
39
39
public:
40
- uint8_t _aucBuffer[N] ;
40
+ uint8_t _aucBuffer[N + 1 ] ; // we need one extra byte for the empty/full distinction
41
41
volatile int _iHead ;
42
42
volatile int _iTail ;
43
- volatile int _numElems;
43
+ // Instead of using a counter, we use the head and tail markers to determine the number of elements
44
+ // this makes it thread-safe, as the head and tail are only modified by one thread
45
+ // volatile int _numElems;
44
46
45
47
public:
46
48
RingBufferN ( void ) ;
@@ -63,7 +65,7 @@ typedef RingBufferN<SERIAL_BUFFER_SIZE> RingBuffer;
63
65
template <int N>
64
66
RingBufferN<N>::RingBufferN( void )
65
67
{
66
- memset ( _aucBuffer, 0 , N ) ;
68
+ memset ( _aucBuffer, 0 , N + 1 ) ;
67
69
clear ();
68
70
}
69
71
@@ -78,7 +80,7 @@ void RingBufferN<N>::store_char( uint8_t c )
78
80
{
79
81
_aucBuffer[_iHead] = c ;
80
82
_iHead = nextIndex (_iHead);
81
- _numElems = _numElems + 1 ;
83
+ // _numElems++ ;
82
84
}
83
85
}
84
86
@@ -87,7 +89,7 @@ void RingBufferN<N>::clear()
87
89
{
88
90
_iHead = 0 ;
89
91
_iTail = 0 ;
90
- _numElems = 0 ;
92
+ // _numElems = 0;
91
93
}
92
94
93
95
template <int N>
@@ -98,21 +100,24 @@ int RingBufferN<N>::read_char()
98
100
99
101
uint8_t value = _aucBuffer[_iTail];
100
102
_iTail = nextIndex (_iTail);
101
- _numElems = _numElems - 1 ;
103
+ // _numElems-- ;
102
104
103
105
return value;
104
106
}
105
107
106
108
template <int N>
107
109
int RingBufferN<N>::available()
108
110
{
109
- return _numElems;
111
+ return ((_iHead >= _iTail) ? _iHead - _iTail : (N - _iTail + 1 + _iHead));
112
+ // return _numElems;
110
113
}
111
114
112
115
template <int N>
113
116
int RingBufferN<N>::availableForStore()
114
117
{
115
- return (N - _numElems);
118
+ return (N - available ());
119
+ // return ((_iHead >= _iTail) ? N - (_iHead - _iTail) : (_iTail - 1 - _iHead));
120
+ // return (N - _numElems);
116
121
}
117
122
118
123
template <int N>
@@ -127,13 +132,14 @@ int RingBufferN<N>::peek()
127
132
template <int N>
128
133
int RingBufferN<N>::nextIndex(int index)
129
134
{
130
- return (uint32_t )(index + 1 ) % N ;
135
+ return (uint32_t )(index + 1 ) % (N + 1 ) ;
131
136
}
132
137
133
138
template <int N>
134
139
bool RingBufferN<N>::isFull()
135
140
{
136
- return (_numElems == N);
141
+ return (0 == availableForStore ());
142
+ // return (_numElems == N);
137
143
}
138
144
139
145
}
0 commit comments