mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
ringbuffers: initial implementation
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
objects := $(patsubst %.c,%.o,$(wildcard *.c))
|
objects := $(patsubst %.c,%.o,$(wildcard *.c))
|
||||||
subdirs := stdio string hashtable
|
subdirs := stdio string hashtable ringbuffer
|
||||||
OBJPATH=$(OBJDIR)/include
|
OBJPATH=$(OBJDIR)/include/ringbuffer/
|
||||||
export
|
export
|
||||||
|
|
||||||
all: $(subdirs) $(objects)
|
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