kernel: ringbuffer

This commit is contained in:
Matheus
2023-05-02 21:19:44 -03:00
parent 768ee865a0
commit 393e34a04e
2 changed files with 68 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
#ifndef _RINGBUFFER_H
#define _RINGBUFFER_H
#include <stddef.h>
#include <stdint.h>
typedef struct {
size_t size;
uintmax_t write;
uintmax_t read;
void *data;
} ringbuffer_t;
int ringbuffer_init(ringbuffer_t *ringbuffer, size_t size);
void ringbuffer_destroy(ringbuffer_t *ringbuffer);
size_t ringbuffer_read(ringbuffer_t* ringbuffer, void *buffer, size_t count);
size_t ringbuffer_write(ringbuffer_t* ringbuffer, void *buffer, size_t count);
#define RINGBUFFER_DATACOUNT(x) ((x)->write - (x)->read)
#endif
+47
View File
@@ -0,0 +1,47 @@
#include <ringbuffer.h>
#include <kernel/vmm.h>
#include <util.h>
#include <errno.h>
int ringbuffer_init(ringbuffer_t *ringbuffer, size_t size) {
ringbuffer->data = vmm_map(NULL, ROUND_UP(size, PAGE_SIZE), VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC, NULL);
if (ringbuffer->data == NULL)
return ENOMEM;
ringbuffer->size = size;
ringbuffer->write = 0;
ringbuffer->read = 0;
return 0;
}
void ringbuffer_destroy(ringbuffer_t *ringbuffer) {
vmm_unmap(ringbuffer->data, ROUND_UP(ringbuffer->size, PAGE_SIZE), 0);
}
size_t ringbuffer_read(ringbuffer_t* ringbuffer, void *buffer, size_t count) {
uint8_t *ptr = buffer;
size_t readc = 0;
for (; readc < count; ++readc) {
if (ringbuffer->read == ringbuffer->write)
break;
uintmax_t readoffset = ringbuffer->read % ringbuffer->size;
*ptr++ = *((uint8_t *)ringbuffer->data + readoffset);
++ringbuffer->read;
}
return readc;
}
size_t ringbuffer_write(ringbuffer_t* ringbuffer, void *buffer, size_t count) {
uint8_t *ptr = buffer;
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 *)ringbuffer->data + writeoffset) = *ptr++;
++ringbuffer->write;
}
return writec;
}