Tidy up ringbuf and make tests
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user