Add Ring Buffer implementation
This commit is contained in:
commit
e4a531530e
49
Makefile
Normal file
49
Makefile
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Preproc options
|
||||||
|
# -MMD is used to generate .d files for user header dependencies (use -MD for system and user header instead)
|
||||||
|
CPPFLAGS = -MMD
|
||||||
|
# main compilation
|
||||||
|
CFLAGS ?= -Werror -Wall #$(shell pkg-config --cflags sdl)
|
||||||
|
# C++ flags
|
||||||
|
CXXFLAGS =
|
||||||
|
#Linker flags
|
||||||
|
LDFLAGS =
|
||||||
|
#Linker path
|
||||||
|
LDLIBS = #$(shell pkg-config --libs sdl)
|
||||||
|
|
||||||
|
ifneq ($(CROSS_COMPILE),)
|
||||||
|
CC :=$(CROSS_COMPILE)$(CC)
|
||||||
|
CXX :=$(CROSS_COMPILE)$(CXX)
|
||||||
|
LD :=$(CROSS_COMPILE)$(LD)
|
||||||
|
endif
|
||||||
|
|
||||||
|
bin = main
|
||||||
|
lib = libringbuffer.so
|
||||||
|
|
||||||
|
#Will be compiled with -fpic
|
||||||
|
lib_src = ringbuffer.c
|
||||||
|
lib_obj = $(lib_src:%.c=%.o)
|
||||||
|
lib_dep = $(lib_src:%.c=%.d)
|
||||||
|
|
||||||
|
sources = $(filter-out $(lib_src), $(wildcard *.c))
|
||||||
|
objects = $(sources:%.c=%.o)
|
||||||
|
depends = $(sources:%.c=%.d)
|
||||||
|
|
||||||
|
all: $(bin) $(lib)
|
||||||
|
|
||||||
|
$(bin): $(objects) $(lib)
|
||||||
|
|
||||||
|
|
||||||
|
$(lib): CFLAGS += -fpic
|
||||||
|
$(lib): $(lib_obj)
|
||||||
|
|
||||||
|
%.so:
|
||||||
|
$(LINK.c) -shared $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
$(RM) $(bin) $(objects) $(depends) $(lib) $(lib_obj) $(lib_dep)
|
||||||
|
|
||||||
|
ifneq ($(MAKECMDGOALS),clean)
|
||||||
|
-include $(depends)
|
||||||
|
-include $(lib_dep)
|
||||||
|
endif
|
45
main.c
Normal file
45
main.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "ringbuffer.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
ringbuffer_t inst = ringbuffer_create(4);
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
uint8_t item;
|
||||||
|
assert(ringbuffer_enqueue(inst, 1));
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
assert(ringbuffer_enqueue(inst, 2));
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
assert(ringbuffer_enqueue(inst, 3));
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
assert(ringbuffer_enqueue(inst, 4));
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
assert(ringbuffer_enqueue(inst, 5) == false);
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
assert(ringbuffer_dequeue(inst, &item));
|
||||||
|
assert(item == 1);
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
assert(ringbuffer_enqueue(inst, 5));
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
|
||||||
|
assert(ringbuffer_dequeue(inst, &item));
|
||||||
|
assert(item == 2);
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
|
||||||
|
assert(ringbuffer_dequeue(inst, &item));
|
||||||
|
assert(item == 3);
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
|
||||||
|
assert(ringbuffer_dequeue(inst, &item));
|
||||||
|
assert(item == 4);
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
|
||||||
|
assert(ringbuffer_dequeue(inst, &item));
|
||||||
|
assert(item == 5);
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
|
||||||
|
assert(ringbuffer_dequeue(inst, &item) == false);
|
||||||
|
ringbuffer_debug(inst);
|
||||||
|
return 0;
|
||||||
|
}
|
87
ringbuffer.c
Normal file
87
ringbuffer.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include "ringbuffer.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct ringbuffer_instance_t {
|
||||||
|
int32_t wr_pos;
|
||||||
|
int32_t rd_pos;
|
||||||
|
uint8_t *data;
|
||||||
|
uint32_t capacity;
|
||||||
|
bool full;
|
||||||
|
};
|
||||||
|
|
||||||
|
ringbuffer_t ringbuffer_create(uint32_t capacity)
|
||||||
|
{
|
||||||
|
ringbuffer_t inst = calloc(1, sizeof(struct ringbuffer_instance_t));
|
||||||
|
inst->data = calloc(capacity, sizeof(uint8_t));
|
||||||
|
inst->capacity = capacity;
|
||||||
|
inst->wr_pos = 0;
|
||||||
|
inst->rd_pos = 0;
|
||||||
|
inst->full = capacity == 0;
|
||||||
|
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ringbuffer_capacity(ringbuffer_t instance)
|
||||||
|
{
|
||||||
|
return instance->capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ringbuffer_used(ringbuffer_t instance)
|
||||||
|
{
|
||||||
|
if (instance->full)
|
||||||
|
return instance->capacity;
|
||||||
|
|
||||||
|
return (instance->wr_pos - instance->rd_pos) % instance->capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ringbuffer_empty(ringbuffer_t instance)
|
||||||
|
{
|
||||||
|
return (!instance->full && (instance->wr_pos == instance->rd_pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ringbuffer_full(ringbuffer_t instance)
|
||||||
|
{
|
||||||
|
return instance->full;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ringbuffer_enqueue(ringbuffer_t instance, uint8_t item)
|
||||||
|
{
|
||||||
|
if (ringbuffer_full(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 ringbuffer_dequeue(ringbuffer_t instance, uint8_t *item)
|
||||||
|
{
|
||||||
|
if (ringbuffer_empty(instance))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
instance->full = false;
|
||||||
|
*item = instance->data[instance->rd_pos];
|
||||||
|
instance->rd_pos = (instance->rd_pos + 1) % instance->capacity;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ringbuffer_destroy(ringbuffer_t instance)
|
||||||
|
{
|
||||||
|
if (instance) {
|
||||||
|
if (instance->data) {
|
||||||
|
free(instance->data);
|
||||||
|
}
|
||||||
|
free(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ringbuffer_debug(ringbuffer_t instance)
|
||||||
|
{
|
||||||
|
printf("%d/%d %d %d %s\n", ringbuffer_used(instance), ringbuffer_capacity(instance),
|
||||||
|
instance->wr_pos, instance->rd_pos, instance->full ? "(full)" : "");
|
||||||
|
}
|
16
ringbuffer.h
Normal file
16
ringbuffer.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct ringbuffer_instance_t* ringbuffer_t;
|
||||||
|
|
||||||
|
ringbuffer_t ringbuffer_create(uint32_t capacity);
|
||||||
|
uint32_t ringbuffer_capacity(ringbuffer_t instance);
|
||||||
|
uint32_t ringbuffer_used(ringbuffer_t instance);
|
||||||
|
bool ringbuffer_enqueue(ringbuffer_t instance, uint8_t item);
|
||||||
|
bool ringbuffer_dequeue(ringbuffer_t instance, uint8_t* item);
|
||||||
|
void ringbuffer_destroy(ringbuffer_t instance);
|
||||||
|
void ringbuffer_debug(ringbuffer_t instance);
|
||||||
|
bool ringbuffer_empty(ringbuffer_t instance);
|
||||||
|
bool ringbuffer_full(ringbuffer_t instance);
|
Loading…
Reference in New Issue
Block a user