#include #include #include #include #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; pthread_mutex_init(&out->mutex, NULL); } void ringBufferDestroy(struct ringBuffer *buf) { free(buf->buffer); pthread_mutex_destroy(&buf->mutex); } int ringBufferRead(struct ringBuffer *buf, void *out) { pthread_mutex_lock(&buf->mutex); if (buf->reader != buf->writer) { // we have data to read memcpy(out, buf->reader, buf->blockSize); _ringBufferIncReader(buf); pthread_mutex_unlock(&buf->mutex); return 0; } else { // nothing to read pthread_mutex_unlock(&buf->mutex); return 1; } } void ringBufferWrite(struct ringBuffer *buf, void *in) { pthread_mutex_lock(&buf->mutex); memcpy(buf->writer, in, buf->blockSize); _ringBufferIncWriter(buf); pthread_mutex_unlock(&buf->mutex); }