Skip to content

Commit c5250f9

Browse files
Instead of using a counter, we use the head and tail markers
Instead of using a counter, we use the head and tail markers to determine the number of elements. This makes it thread-safe, as the head and tail are only modified by one thread
1 parent 4a02bfc commit c5250f9

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

api/RingBuffer.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ template <int N>
3737
class 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;
6365
template <int N>
6466
RingBufferN<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

9395
template <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

106108
template <int N>
107109
int RingBufferN<N>::available()
108110
{
109-
return _numElems;
111+
return ((_iHead >= _iTail) ? _iHead - _iTail : (N - _iTail + 1 + _iHead));
112+
// return _numElems;
110113
}
111114

112115
template <int N>
113116
int 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

118123
template <int N>
@@ -127,13 +132,14 @@ int RingBufferN<N>::peek()
127132
template <int N>
128133
int RingBufferN<N>::nextIndex(int index)
129134
{
130-
return (uint32_t)(index + 1) % N;
135+
return (uint32_t)(index + 1) % (N + 1);
131136
}
132137

133138
template <int N>
134139
bool RingBufferN<N>::isFull()
135140
{
136-
return (_numElems == N);
141+
return (0 == availableForStore());
142+
// return (_numElems == N);
137143
}
138144

139145
}

0 commit comments

Comments
 (0)