From ff7a28ff59ddf164f4a0363bfafc038aba944d1c Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Tue, 24 May 2022 10:10:18 +0200 Subject: [PATCH] RingBuffer class: implemented eraseElement() function, rewritten the pop() function in a cleaner way, fixed a bug in the pop() function causing the not_full condition variable to be never rised. --- openrtx/include/core/ringbuf.h | 53 ++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/openrtx/include/core/ringbuf.h b/openrtx/include/core/ringbuf.h index 419e427b..77385e6b 100644 --- a/openrtx/include/core/ringbuf.h +++ b/openrtx/include/core/ringbuf.h @@ -108,25 +108,27 @@ public: { pthread_mutex_lock(&mutex); - if(numElements == 0) + if((numElements == 0) && (blocking == false)) { - if(blocking) - { - while(numElements == 0) - { - pthread_cond_wait(¬_empty, &mutex); - } - } - else - { - pthread_mutex_unlock(&mutex); - return false; - } + // No elements present and non-blocking call: unlock mutex and return + pthread_mutex_unlock(&mutex); + return false; } - elem = data[readPos]; - readPos = (readPos + 1) % N; + // The call is blocking: wait until there is something into the queue + while(numElements == 0) + { + pthread_cond_wait(¬_empty, &mutex); + } + + // At least one element present pop one. + elem = data[readPos]; + readPos = (readPos + 1) % N; + + // Signal that the queue is no more full + if(numElements >= N) pthread_cond_signal(¬_full); numElements -= 1; + pthread_mutex_unlock(&mutex); return true; @@ -152,6 +154,27 @@ public: return numElements >= N; } + /** + * Discard one element from the buffer's tail, creating a new empty slot. + * In case the buffer is full calling this function unlocks the eventual + * threads waiting to push data. + */ + void eraseElement() + { + // Nothing to erase + if(numElements == 0) return; + + pthread_mutex_lock(&mutex); + + // Chomp away one element just by advancing the read pointer. + readPos = (readPos + 1) % N; + + if(numElements >= N) pthread_cond_signal(¬_full); + numElements -= 1; + + pthread_mutex_unlock(&mutex); + } + private: size_t readPos; ///< Read pointer.