[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.
This commit is contained in:
Geoffrey McRae 2021-12-25 10:41:42 +11:00
parent f403033ab1
commit d99ec3e9c0
2 changed files with 71 additions and 8 deletions

View File

@ -30,12 +30,23 @@ void ringbuffer_push(RingBuffer rb, const void * value);
bool ringbuffer_shift(RingBuffer rb, void * dst); bool ringbuffer_shift(RingBuffer rb, void * dst);
void ringbuffer_reset(RingBuffer rb); void ringbuffer_reset(RingBuffer rb);
/* Note that the following functions are NOT thread-safe */
int ringbuffer_getLength(const RingBuffer rb); int ringbuffer_getLength(const RingBuffer rb);
int ringbuffer_getStart (const RingBuffer rb); int ringbuffer_getStart (const RingBuffer rb);
int ringbuffer_getCount (const RingBuffer rb); int ringbuffer_getCount (const RingBuffer rb);
void * ringbuffer_getValues(const RingBuffer rb); void * ringbuffer_getValues(const RingBuffer rb);
void * ringBuffer_getLastValue(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); typedef void (*RingBufferValueFn)(void * value, void * udata);
// set a function to call before a value is about to be overwritten // set a function to call before a value is about to be overwritten

View File

@ -57,7 +57,6 @@ void ringbuffer_free(RingBuffer * rb)
void ringbuffer_push(RingBuffer rb, const void * value) void ringbuffer_push(RingBuffer rb, const void * value)
{ {
LG_LOCK(rb->lock);
void * dst = rb->values + rb->pos * rb->valueSize; void * dst = rb->values + rb->pos * rb->valueSize;
if (rb->count < rb->length) if (rb->count < rb->length)
++rb->count; ++rb->count;
@ -73,7 +72,6 @@ void ringbuffer_push(RingBuffer rb, const void * value)
memcpy(dst, value, rb->valueSize); memcpy(dst, value, rb->valueSize);
if (++rb->pos == rb->length) if (++rb->pos == rb->length)
rb->pos = 0; rb->pos = 0;
LG_UNLOCK(rb->lock);
} }
bool ringbuffer_shift(RingBuffer rb, void * dst) bool ringbuffer_shift(RingBuffer rb, void * dst)
@ -81,23 +79,19 @@ bool ringbuffer_shift(RingBuffer rb, void * dst)
if (rb->count == 0) if (rb->count == 0)
return false; return false;
LG_LOCK(rb->lock);
memcpy(dst, rb->values + rb->start * rb->valueSize, rb->valueSize); memcpy(dst, rb->values + rb->start * rb->valueSize, rb->valueSize);
--rb->count; --rb->count;
if (++rb->start == rb->length) if (++rb->start == rb->length)
rb->start = 0; rb->start = 0;
LG_UNLOCK(rb->lock);
return true; return true;
} }
void ringbuffer_reset(RingBuffer rb) void ringbuffer_reset(RingBuffer rb)
{ {
LG_LOCK(rb->lock);
rb->start = 0; rb->start = 0;
rb->pos = 0; rb->pos = 0;
rb->count = 0; rb->count = 0;
LG_UNLOCK(rb->lock);
} }
int ringbuffer_getLength(const RingBuffer rb) int ringbuffer_getLength(const RingBuffer rb)
@ -132,6 +126,66 @@ void * ringBuffer_getLastValue(const RingBuffer rb)
return rb->values + index * rb->valueSize; 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 ringbuffer_setPreOverwriteFn(const RingBuffer rb, RingBufferValueFn fn,
void * udata) void * udata)
{ {
@ -142,7 +196,6 @@ void ringbuffer_setPreOverwriteFn(const RingBuffer rb, RingBufferValueFn fn,
void ringbuffer_forEach(const RingBuffer rb, RingBufferIterator fn, void * udata, void ringbuffer_forEach(const RingBuffer rb, RingBufferIterator fn, void * udata,
bool reverse) bool reverse)
{ {
LG_LOCK(rb->lock);
if (reverse) if (reverse)
{ {
int index = rb->start + rb->count - 1; int index = rb->start + rb->count - 1;
@ -172,5 +225,4 @@ void ringbuffer_forEach(const RingBuffer rb, RingBufferIterator fn, void * udata
break; break;
} }
} }
LG_UNLOCK(rb->lock);
} }