#include #include #include #include #ifdef RINGBUFFER_THREAD_SAFE #include #endif #include "ringbuffer.h" void _ringBufferIncReader(struct ringBuffer *buf) { buf->reader += buf->blockSize; if (buf->reader >= buf->buffer + buf->blocks * buf->blockSize) { buf->reader = buf->buffer; } } void _ringBufferIncWriter(struct ringBuffer *buf) { buf->writer += buf->blockSize; if (buf->writer == buf->buffer + buf->blocks * buf->blockSize) { buf->writer = buf->buffer; } if (buf->writer == buf->reader) { // we incremented the writer and now it is equal to reader // this means, the writer is overtaking the reader // so push the reader forward, even if we are // loosing data but this is how ring buffers work, eh? _ringBufferIncReader(buf); } } void ringBufferCreate(int blocks, size_t blockSize, struct ringBuffer *out) { out->buffer = malloc(blocks * blockSize); out->blocks = blocks; out->blockSize = blockSize; out->reader = out->buffer; out->writer = out->buffer; #ifdef RINGBUFFER_THREAD_SAFE pthread_mutex_init(&out->mutex, NULL); #endif } void ringBufferDestroy(struct ringBuffer *buf) { free(buf->buffer); #ifdef RINGBUFFER_THREAD_SAFE pthread_mutex_destroy(&buf->mutex); #endif } int ringBufferRead(struct ringBuffer *buf, void *out) { #ifdef RINGBUFFER_THREAD_SAFE pthread_mutex_lock(&buf->mutex); #endif if (buf->reader != buf->writer) { // we have data to read memcpy(out, buf->reader, buf->blockSize); _ringBufferIncReader(buf); #ifdef RINGBUFFER_THREAD_SAFE pthread_mutex_unlock(&buf->mutex); #endif return 0; } else { // nothing to read #ifdef RINGBUFFER_THREAD_SAFE pthread_mutex_unlock(&buf->mutex); #endif return 1; } } void ringBufferWrite(struct ringBuffer *buf, void *in) { #ifdef RINGBUFFER_THREAD_SAFE pthread_mutex_lock(&buf->mutex); #endif memcpy(buf->writer, in, buf->blockSize); _ringBufferIncWriter(buf); #ifdef RINGBUFFER_THREAD_SAFE pthread_mutex_unlock(&buf->mutex); #endif }