From c5250f9ce1d5a3381122043e2db21c836b624660 Mon Sep 17 00:00:00 2001 From: Michael <122316029+Michael121977@users.noreply.github.com> Date: Thu, 24 Jul 2025 21:57:45 +0200 Subject: [PATCH 1/4] 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 --- api/RingBuffer.h | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/api/RingBuffer.h b/api/RingBuffer.h index b69c20d4..0dd3ec13 100644 --- a/api/RingBuffer.h +++ b/api/RingBuffer.h @@ -37,10 +37,12 @@ template class RingBufferN { public: - uint8_t _aucBuffer[N] ; + uint8_t _aucBuffer[N + 1] ; // we need one extra byte for the empty/full distinction volatile int _iHead ; volatile int _iTail ; - volatile int _numElems; + // 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 + //volatile int _numElems; public: RingBufferN( void ) ; @@ -63,7 +65,7 @@ typedef RingBufferN RingBuffer; template RingBufferN::RingBufferN( void ) { - memset( _aucBuffer, 0, N ) ; + memset( _aucBuffer, 0, N + 1) ; clear(); } @@ -78,7 +80,7 @@ void RingBufferN::store_char( uint8_t c ) { _aucBuffer[_iHead] = c ; _iHead = nextIndex(_iHead); - _numElems = _numElems + 1; + //_numElems++; } } @@ -87,7 +89,7 @@ void RingBufferN::clear() { _iHead = 0; _iTail = 0; - _numElems = 0; + //_numElems = 0; } template @@ -98,7 +100,7 @@ int RingBufferN::read_char() uint8_t value = _aucBuffer[_iTail]; _iTail = nextIndex(_iTail); - _numElems = _numElems - 1; + //_numElems--; return value; } @@ -106,13 +108,16 @@ int RingBufferN::read_char() template int RingBufferN::available() { - return _numElems; + return ((_iHead >= _iTail) ? _iHead - _iTail : (N - _iTail + 1 + _iHead)); + // return _numElems; } template int RingBufferN::availableForStore() { - return (N - _numElems); + return (N - available()); + // return ((_iHead >= _iTail) ? N - (_iHead - _iTail) : (_iTail - 1 - _iHead)); + // return (N - _numElems); } template @@ -127,13 +132,14 @@ int RingBufferN::peek() template int RingBufferN::nextIndex(int index) { - return (uint32_t)(index + 1) % N; + return (uint32_t)(index + 1) % (N + 1); } template bool RingBufferN::isFull() { - return (_numElems == N); + return (0 == availableForStore()); + // return (_numElems == N); } } From 8cbc818078762a51e38f9fcb29f586d4e383a329 Mon Sep 17 00:00:00 2001 From: Michael <122316029+Michael121977@users.noreply.github.com> Date: Thu, 24 Jul 2025 22:07:25 +0200 Subject: [PATCH 2/4] Fix IsEmpty() methode --- api/RingBuffer.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/api/RingBuffer.h b/api/RingBuffer.h index 0dd3ec13..7e965f83 100644 --- a/api/RingBuffer.h +++ b/api/RingBuffer.h @@ -1,5 +1,4 @@ /* - RingBuffer.h - Ring buffer implementation Copyright (c) 2014 Arduino. All right reserved. This library is free software; you can redistribute it and/or @@ -9,8 +8,8 @@ This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software @@ -56,7 +55,7 @@ class RingBufferN private: int nextIndex(int index); - inline bool isEmpty() const { return (_numElems == 0); } + inline bool isEmpty() const { return (0 == available()); } }; typedef RingBufferN RingBuffer; From dc152440d40905681fda566b7a710ebb6a65d6b8 Mon Sep 17 00:00:00 2001 From: Michael <122316029+Michael121977@users.noreply.github.com> Date: Thu, 24 Jul 2025 22:33:01 +0200 Subject: [PATCH 3/4] Fix isEmpty --- api/RingBuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/RingBuffer.h b/api/RingBuffer.h index 7e965f83..99e94f44 100644 --- a/api/RingBuffer.h +++ b/api/RingBuffer.h @@ -55,7 +55,7 @@ class RingBufferN private: int nextIndex(int index); - inline bool isEmpty() const { return (0 == available()); } + inline bool isEmpty() const { return (_iHead == iTail); } }; typedef RingBufferN RingBuffer; From e1030882ceda5951b4a84ebc19bb8d7d82b7cb17 Mon Sep 17 00:00:00 2001 From: Michael <122316029+Michael121977@users.noreply.github.com> Date: Thu, 24 Jul 2025 22:35:03 +0200 Subject: [PATCH 4/4] Fix isEmpty --- api/RingBuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/RingBuffer.h b/api/RingBuffer.h index 99e94f44..c30e39ca 100644 --- a/api/RingBuffer.h +++ b/api/RingBuffer.h @@ -55,7 +55,7 @@ class RingBufferN private: int nextIndex(int index); - inline bool isEmpty() const { return (_iHead == iTail); } + inline bool isEmpty() const { return (_iHead == _iTail); } }; typedef RingBufferN RingBuffer;