Tidy up ringbuf and make tests

This commit is contained in:
Nils O. Selåsdal
2025-07-05 20:03:24 +02:00
parent 7373a93f9b
commit 1f6dee3a9a
4 changed files with 245 additions and 4 deletions
+93
View File
@@ -0,0 +1,93 @@
#ifdef __linux
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "ucore/ringbuf.h"
int uc_ringbuf_init(UCRingBuf *rb, uint32_t sz)
{
uint32_t pagesz = getpagesize();
// Round up to page size
sz = ((sz + pagesz - 1) / pagesz) * pagesz;
/* Reserve contiguous address space*/
void *base = mmap(NULL, sz * 2, PROT_NONE, MAP_POPULATE|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (base == NULL) {
return -errno;
}
/* MAP_PRIVATE doesn't work */
base = mmap(base, sz * 1, PROT_READ|PROT_WRITE, MAP_POPULATE|MAP_ANONYMOUS|MAP_FIXED|MAP_SHARED, -1, 0);
if (base == MAP_FAILED) {
return -errno;
}
void *mbase = mremap(base, sz * 1, sz, MREMAP_FIXED|MREMAP_MAYMOVE|MREMAP_DONTUNMAP, base + sz);
if (mbase == MAP_FAILED) {
munmap(base, sz);
return -errno;
}
rb->base = base;
rb->sz = sz;
rb->read_idx = 0;
rb->write_idx = 0;
return 0;
}
int uc_ringbuf_destroy(UCRingBuf *rb)
{
int rc = munmap(rb->base, rb->sz);
if (rc != 0) {
return -errno;
}
rc = munmap(rb->base + rb->sz, rb->sz);
if (rc != 0) {
return -errno;
}
rb->base = NULL;
return 0;
}
uint32_t uc_ringbuf_available(const UCRingBuf *rb)
{
return rb->sz - rb->write_idx + rb->read_idx;
}
int uc_ringbuf_write(UCRingBuf *rb, const void *restrict data, uint32_t len)
{
if (rb->write_idx - rb->read_idx + len > rb->sz) {
return -ENOMEM;
}
memcpy(&rb->base[rb->write_idx], data, len);
rb->write_idx += len;
return 0;
}
int uc_ringbuf_read(UCRingBuf *rb, void *restrict data, uint32_t len)
{
if (uc_ringbuf_len(rb) < len) {
return -ENOMEM;
}
memcpy(data, &rb->base[rb->read_idx], len);
rb->read_idx += len;
if (rb->read_idx == rb->write_idx) {
rb->read_idx = rb->write_idx = 0;
} else if (rb->read_idx > rb->sz) {
rb->read_idx -= rb->sz;
rb->write_idx -= rb->sz;
}
return 0;
}
#endif