@@ -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