#include "alloc.h" #include "klibc.h" #include "ringbuffer.h" #include "synchro.h" struct ringbuffer_instance_t { int32_t wr_pos; int32_t rd_pos; uint8_t *data; uint32_t capacity; bool_t full; }; ringbuffer_t ringbufferCreate(uint32_t capacity) { ringbuffer_t inst = zalloc(1 * sizeof(struct ringbuffer_instance_t)); if (inst == NULL) return NULL; inst->data = zalloc(capacity * sizeof(uint8_t)); if (inst->data == NULL) { free(inst); return NULL; } inst->capacity = capacity; inst->wr_pos = 0; inst->rd_pos = 0; inst->full = capacity == 0; return inst; } uint32_t ringbufferCapacity(ringbuffer_t instance) { return instance->capacity; } uint32_t ringbufferUsed(ringbuffer_t instance) { if (instance->full) return instance->capacity; return (instance->wr_pos - instance->rd_pos) % instance->capacity; } bool_t ringbufferIsEmpty(ringbuffer_t instance) { return (!instance->full && (instance->wr_pos == instance->rd_pos)); } bool_t ringbufferIsFull(ringbuffer_t instance) { return instance->full; } bool_t ringbufferEnqueue(ringbuffer_t instance, uint8_t item) { if (ringbufferIsFull(instance)) return FALSE; instance->data[instance->wr_pos] = item; instance->wr_pos = (instance->wr_pos + 1) % instance->capacity; if (instance->rd_pos == instance->wr_pos) instance->full = TRUE; return TRUE; } bool_t ringbufferDequeue(ringbuffer_t instance, uint8_t *item) { if (ringbufferIsEmpty(instance)) return FALSE; instance->full = FALSE; *item = instance->data[instance->rd_pos]; instance->rd_pos = (instance->rd_pos + 1) % instance->capacity; return TRUE; } void ringbufferDestroy(ringbuffer_t instance) { if (instance) { if (instance->data) { free(instance->data); } free(instance); } } void ringbufferDebug(ringbuffer_t instance) { printf("%d/%d %d %d %s\n", ringbufferUsed(instance), ringbufferCapacity(instance), instance->wr_pos, instance->rd_pos, instance->full ? "(full)" : ""); } struct locked_ringbuffer_instance_t { struct ringbuffer_instance_t *ring; struct mutex mut; }; locked_ringbuffer_t lringbufferCreate(uint32_t capacity) { locked_ringbuffer_t inst = zalloc(sizeof(locked_ringbuffer_t)); if (inst == NULL) return NULL; inst->ring = ringbufferCreate(capacity); if (inst->ring == NULL) { free(inst); return NULL; } mutexInit(&inst->mut); return inst; } uint32_t lringbufferCapacity(locked_ringbuffer_t instance) { return instance->ring->capacity; } uint32_t lringbufferUsed(locked_ringbuffer_t instance) { int used; mutexLock(&instance->mut); used = ringbufferUsed(instance->ring); mutexUnlock(&instance->mut); return used; } bool_t lringbufferEnqueue(locked_ringbuffer_t instance, uint8_t item) { int ret; mutexLock(&instance->mut); ret = ringbufferEnqueue(instance->ring, item); mutexUnlock(&instance->mut); return ret; } bool_t lringbufferDequeue(locked_ringbuffer_t instance, uint8_t *item) { int ret; mutexLock(&instance->mut); ret = ringbufferDequeue(instance->ring, item); mutexUnlock(&instance->mut); return ret; } void lringbufferDestroy(locked_ringbuffer_t instance){ mutexFree(&instance->mut); ringbufferDestroy(instance->ring); instance->ring = NULL; free(instance); } void lringbufferDebug(locked_ringbuffer_t instance) { mutexLock(&instance->mut); ringbufferDebug(instance->ring); mutexUnlock(&instance->mut); } bool_t lringbufferIsEmpty(locked_ringbuffer_t instance) { bool_t ret; mutexLock(&instance->mut); ret = ringbufferIsEmpty(instance->ring); mutexUnlock(&instance->mut); return ret; } bool_t lringbufferIsFull(locked_ringbuffer_t instance) { bool_t ret; mutexLock(&instance->mut); ret = ringbufferIsFull(instance->ring); mutexUnlock(&instance->mut); return ret; }