Import ringbuffer implementation
From https://git.mathux.org/mathieu/ringbuffer
This commit is contained in:
parent
2b32908029
commit
288663ad58
87
core/ringbuffer.c
Normal file
87
core/ringbuffer.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include "alloc.h"
|
||||
#include "klibc.h"
|
||||
#include "ringbuffer.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));
|
||||
inst->data = zalloc(capacity * sizeof(uint8_t));
|
||||
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 ringbufferEmpty(ringbuffer_t instance)
|
||||
{
|
||||
return (!instance->full && (instance->wr_pos == instance->rd_pos));
|
||||
}
|
||||
|
||||
bool_t ringbufferFull(ringbuffer_t instance)
|
||||
{
|
||||
return instance->full;
|
||||
}
|
||||
|
||||
bool_t ringbufferEnqueue(ringbuffer_t instance, uint8_t item)
|
||||
{
|
||||
if (ringbufferFull(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 (ringbufferEmpty(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)" : "");
|
||||
}
|
15
core/ringbuffer.h
Normal file
15
core/ringbuffer.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdarg.h"
|
||||
|
||||
typedef struct ringbuffer_instance_t* ringbuffer_t;
|
||||
|
||||
ringbuffer_t ringbufferCreate(uint32_t capacity);
|
||||
uint32_t ringbufferCapacity(ringbuffer_t instance);
|
||||
uint32_t ringbufferUsed(ringbuffer_t instance);
|
||||
bool_t ringbufferEnqueue(ringbuffer_t instance, uint8_t item);
|
||||
bool_t ringbufferDequeue(ringbuffer_t instance, uint8_t* item);
|
||||
void ringbufferDestroy(ringbuffer_t instance);
|
||||
void ringbufferDebug(ringbuffer_t instance);
|
||||
bool_t ringbufferEmpty(ringbuffer_t instance);
|
||||
bool_t ringbufferFull(ringbuffer_t instance);
|
45
tests/test.c
45
tests/test.c
@ -16,6 +16,7 @@
|
||||
#include "synchro.h"
|
||||
#include "syscall.h"
|
||||
#include "swintr.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "time.h"
|
||||
|
||||
void testMemcpyPerf()
|
||||
@ -450,6 +451,49 @@ static void testProcess(){
|
||||
printf("Running user space app DONE\n");
|
||||
}
|
||||
|
||||
void testRingBuffer()
|
||||
{
|
||||
printf("Testing ring buffer\n");
|
||||
ringbuffer_t inst = ringbufferCreate(4);
|
||||
ringbufferDebug(inst);
|
||||
uint8_t item;
|
||||
assert(ringbufferEnqueue(inst, 1));
|
||||
ringbufferDebug(inst);
|
||||
assert(ringbufferEnqueue(inst, 2));
|
||||
ringbufferDebug(inst);
|
||||
assert(ringbufferEnqueue(inst, 3));
|
||||
ringbufferDebug(inst);
|
||||
assert(ringbufferEnqueue(inst, 4));
|
||||
ringbufferDebug(inst);
|
||||
assert(ringbufferEnqueue(inst, 5) == FALSE);
|
||||
ringbufferDebug(inst);
|
||||
assert(ringbufferDequeue(inst, &item));
|
||||
assert(item == 1);
|
||||
ringbufferDebug(inst);
|
||||
assert(ringbufferEnqueue(inst, 5));
|
||||
ringbufferDebug(inst);
|
||||
|
||||
assert(ringbufferDequeue(inst, &item));
|
||||
assert(item == 2);
|
||||
ringbufferDebug(inst);
|
||||
|
||||
assert(ringbufferDequeue(inst, &item));
|
||||
assert(item == 3);
|
||||
ringbufferDebug(inst);
|
||||
|
||||
assert(ringbufferDequeue(inst, &item));
|
||||
assert(item == 4);
|
||||
ringbufferDebug(inst);
|
||||
|
||||
assert(ringbufferDequeue(inst, &item));
|
||||
assert(item == 5);
|
||||
ringbufferDebug(inst);
|
||||
|
||||
assert(ringbufferDequeue(inst, &item) == FALSE);
|
||||
ringbufferDebug(inst);
|
||||
ringbufferDestroy(inst);
|
||||
}
|
||||
|
||||
void run_test(void)
|
||||
{
|
||||
|
||||
@ -494,4 +538,5 @@ void run_test(void)
|
||||
testProcess();
|
||||
memGetStat(&afterFreemem, &afterUsedmem);
|
||||
printf("free %d -> %d\n", freemem, afterFreemem);
|
||||
testRingBuffer();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user