ringbuffers: initial implementation

This commit is contained in:
Matheus
2022-09-07 15:00:45 -03:00
parent ad182d3872
commit 2f691d8051
4 changed files with 103 additions and 2 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
objects := $(patsubst %.c,%.o,$(wildcard *.c))
subdirs := stdio string hashtable
OBJPATH=$(OBJDIR)/include
subdirs := stdio string hashtable ringbuffer
OBJPATH=$(OBJDIR)/include/ringbuffer/
export
all: $(subdirs) $(objects)
+20
View File
@@ -0,0 +1,20 @@
#ifndef _RINGBUFFER_H_INCLUDE
#define _RINGBUFFER_H_INCLUDE
#include <stdint.h>
#include <stddef.h>
typedef struct{
int lock;
size_t size;
uintmax_t write, read;
void* data;
} ringbuffer_t;
int ringbuffer_init(ringbuffer_t* ringbuffer, size_t size);
size_t ringbuffer_read(ringbuffer_t* ringbuffer, void* buffer, size_t count);
size_t ringbuffer_write(ringbuffer_t* ringbuffer, void* buffer, size_t count);
#endif
+12
View File
@@ -0,0 +1,12 @@
objects := $(patsubst %.c,%.o,$(wildcard *.c))
subdirs :=
OBJPATH=$(OBJDIR)/include
export
all: $(subdirs) $(objects)
for subdir in $(subdirs) ; do $(MAKE) -C $${subdir} ; done
%.o: %.c
$(CC) $(CFLAGS) -o $@ $<
mkdir -p $(OBJPATH)
cp $@ $(OBJPATH)/$@
+69
View File
@@ -0,0 +1,69 @@
#include <ringbuffer.h>
#include <errno.h>
#include <arch/spinlock.h>
#include <kernel/alloc.h>
int ringbuffer_init(ringbuffer_t* ringbuffer, size_t size){
ringbuffer->data = alloc(size);
if(!ringbuffer->data)
return ENOMEM;
ringbuffer->size = size;
return 0;
}
size_t ringbuffer_read(ringbuffer_t* ringbuffer, void* buffer, size_t count){
spinlock_acquire(&ringbuffer->lock);
size_t readc = 0;
for(;readc < count; ++readc){
if(ringbuffer->read == ringbuffer->write)
break;
uintmax_t readoffset = ringbuffer->read % ringbuffer->size;
uint8_t* buf = buffer + readc;
uint8_t* rbuf = ringbuffer->data + readoffset;
*buf = *rbuf;
++ringbuffer->read;
}
spinlock_release(&ringbuffer->lock);
return readc;
}
size_t ringbuffer_write(ringbuffer_t* ringbuffer, void* buffer, size_t count){
spinlock_acquire(&ringbuffer->lock);
size_t writec = 0;
for(;writec < count; ++writec){
if(ringbuffer->write == ringbuffer->read + ringbuffer->size)
break;
uintmax_t writeoffset = ringbuffer->write % ringbuffer->size;
uint8_t* buf = buffer + writec;
uint8_t* wbuf = ringbuffer->data + writeoffset;
*wbuf = *buf;
++ringbuffer->write;
}
spinlock_release(&ringbuffer->lock);
return writec;
}