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); }