@@ -37,10 +37,12 @@ template <int N>
3737class RingBufferN
3838{
3939 public:
40- uint8_t _aucBuffer[N] ;
40+ uint8_t _aucBuffer[N + 1 ] ; // we need one extra byte for the empty/full distinction
4141 volatile int _iHead ;
4242 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;
4446
4547 public:
4648 RingBufferN ( void ) ;
@@ -63,7 +65,7 @@ typedef RingBufferN<SERIAL_BUFFER_SIZE> RingBuffer;
6365template <int N>
6466RingBufferN<N>::RingBufferN( void )
6567{
66- memset ( _aucBuffer, 0 , N ) ;
68+ memset ( _aucBuffer, 0 , N + 1 ) ;
6769 clear ();
6870}
6971
@@ -78,7 +80,7 @@ void RingBufferN<N>::store_char( uint8_t c )
7880 {
7981 _aucBuffer[_iHead] = c ;
8082 _iHead = nextIndex (_iHead);
81- _numElems = _numElems + 1 ;
83+ // _numElems++ ;
8284 }
8385}
8486
@@ -87,7 +89,7 @@ void RingBufferN<N>::clear()
8789{
8890 _iHead = 0 ;
8991 _iTail = 0 ;
90- _numElems = 0 ;
92+ // _numElems = 0;
9193}
9294
9395template <int N>
@@ -98,21 +100,24 @@ int RingBufferN<N>::read_char()
98100
99101 uint8_t value = _aucBuffer[_iTail];
100102 _iTail = nextIndex (_iTail);
101- _numElems = _numElems - 1 ;
103+ // _numElems-- ;
102104
103105 return value;
104106}
105107
106108template <int N>
107109int RingBufferN<N>::available()
108110{
109- return _numElems;
111+ return ((_iHead >= _iTail) ? _iHead - _iTail : (N - _iTail + 1 + _iHead));
112+ // return _numElems;
110113}
111114
112115template <int N>
113116int RingBufferN<N>::availableForStore()
114117{
115- return (N - _numElems);
118+ return (N - available ());
119+ // return ((_iHead >= _iTail) ? N - (_iHead - _iTail) : (_iTail - 1 - _iHead));
120+ // return (N - _numElems);
116121}
117122
118123template <int N>
@@ -127,13 +132,14 @@ int RingBufferN<N>::peek()
127132template <int N>
128133int RingBufferN<N>::nextIndex(int index)
129134{
130- return (uint32_t )(index + 1 ) % N ;
135+ return (uint32_t )(index + 1 ) % (N + 1 ) ;
131136}
132137
133138template <int N>
134139bool RingBufferN<N>::isFull()
135140{
136- return (_numElems == N);
141+ return (0 == availableForStore ());
142+ // return (_numElems == N);
137143}
138144
139145}
0 commit comments