mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
ringbuffers: initial implementation
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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)/$@
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user