From d99ec3e9c019fbc6576e03399dee5d7de3eb4f09 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Sat, 25 Dec 2021 10:41:42 +1100 Subject: [PATCH] [common] ringbuffer: remove exta locking and add append/consume funcs As the ringbuffer is now in use for audio it makes sense to provide bulk append and consume functions that are thread safe instead of adding locking over all of the functions. This partially reverts the prior commit that added the extra locking. --- common/include/common/ringbuffer.h | 11 +++++ common/src/ringbuffer.c | 68 ++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/common/include/common/ringbuffer.h b/common/include/common/ringbuffer.h index 1b40c903..baaf4271 100644 --- a/common/include/common/ringbuffer.h +++ b/common/include/common/ringbuffer.h @@ -30,12 +30,23 @@ void ringbuffer_push(RingBuffer rb, const void * value); bool ringbuffer_shift(RingBuffer rb, void * dst); void ringbuffer_reset(RingBuffer rb); +/* Note that the following functions are NOT thread-safe */ int ringbuffer_getLength(const RingBuffer rb); int ringbuffer_getStart (const RingBuffer rb); int ringbuffer_getCount (const RingBuffer rb); void * ringbuffer_getValues(const RingBuffer rb); void * ringBuffer_getLastValue(const RingBuffer rb); +/* appends up to count values to the buffer returning the number of values + * appended + * Note: This function is thread-safe */ +int ringbuffer_append(const RingBuffer rb, const void * values, int count); + +/* consumes and returns up to *count values from the buffer setting *count to + * the number of valid values returned. + * Note: This function is thread-safe */ +void * ringbuffer_consume(const RingBuffer rb, int * count); + typedef void (*RingBufferValueFn)(void * value, void * udata); // set a function to call before a value is about to be overwritten diff --git a/common/src/ringbuffer.c b/common/src/ringbuffer.c index 5744f916..dd6de3a0 100644 --- a/common/src/ringbuffer.c +++ b/common/src/ringbuffer.c @@ -57,7 +57,6 @@ void ringbuffer_free(RingBuffer * rb) void ringbuffer_push(RingBuffer rb, const void * value) { - LG_LOCK(rb->lock); void * dst = rb->values + rb->pos * rb->valueSize; if (rb->count < rb->length) ++rb->count; @@ -73,7 +72,6 @@ void ringbuffer_push(RingBuffer rb, const void * value) memcpy(dst, value, rb->valueSize); if (++rb->pos == rb->length) rb->pos = 0; - LG_UNLOCK(rb->lock); } bool ringbuffer_shift(RingBuffer rb, void * dst) @@ -81,23 +79,19 @@ bool ringbuffer_shift(RingBuffer rb, void * dst) if (rb->count == 0) return false; - LG_LOCK(rb->lock); memcpy(dst, rb->values + rb->start * rb->valueSize, rb->valueSize); --rb->count; if (++rb->start == rb->length) rb->start = 0; - LG_UNLOCK(rb->lock); return true; } void ringbuffer_reset(RingBuffer rb) { - LG_LOCK(rb->lock); rb->start = 0; rb->pos = 0; rb->count = 0; - LG_UNLOCK(rb->lock); } int ringbuffer_getLength(const RingBuffer rb) @@ -132,6 +126,66 @@ void * ringBuffer_getLastValue(const RingBuffer rb) return rb->values + index * rb->valueSize; } +int ringbuffer_append(const RingBuffer rb, const void * values, int count) +{ + if (count == 0) + return 0; + + LG_LOCK(rb->lock); + if (count > rb->length - rb->count) + count = rb->length - rb->count; + + const char * p = (const char *)values; + int remain = count; + do + { + int copy = rb->length - rb->pos; + if (copy > remain) + copy = remain; + + memcpy(rb->values + rb->pos * rb->valueSize, p, copy * rb->valueSize); + rb->pos += copy; + if (rb->pos == rb->length) + rb->pos = 0; + + p += copy * rb->valueSize; + remain -= copy; + } + while(remain > 0); + + rb->count += count; + LG_UNLOCK(rb->lock); + + return count; +} + +void * ringbuffer_consume(const RingBuffer rb, int * count) +{ + LG_LOCK(rb->lock); + if (rb->count == 0) + { + *count = 0; + LG_UNLOCK(rb->lock); + return NULL; + } + + if (*count > rb->count) + *count = rb->count; + + if (*count > rb->length - rb->start) + *count = rb->length - rb->start; + + void * values = rb->values + rb->start * rb->valueSize; + rb->start += *count; + rb->count -= *count; + if (rb->start == rb->length) + rb->start = 0; + + LG_UNLOCK(rb->lock); + + return values; +} + void ringbuffer_setPreOverwriteFn(const RingBuffer rb, RingBufferValueFn fn, void * udata) { @@ -142,7 +196,6 @@ void ringbuffer_setPreOverwriteFn(const RingBuffer rb, RingBufferValueFn fn, void ringbuffer_forEach(const RingBuffer rb, RingBufferIterator fn, void * udata, bool reverse) { - LG_LOCK(rb->lock); if (reverse) { int index = rb->start + rb->count - 1; @@ -172,5 +225,4 @@ void ringbuffer_forEach(const RingBuffer rb, RingBufferIterator fn, void * udata break; } } - LG_UNLOCK(rb->lock); }