From 0fe13749d095ca22c788e55902979323e85367c3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Dec 2016 23:26:51 +0100 Subject: utils: add helper functions useful for allocating a ring buffer This creates a mapping with twice the size of the allocated memory. The second half of that mapping points at the same memory as the first half. This is useful for ring buffers, because any read starting in the first half can overflow into the second half as long as the read size is smaller than the size of the memory area. Signed-off-by: Felix Fietkau --- utils.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'utils.c') diff --git a/utils.c b/utils.c index 91dd71e..e59002e 100644 --- a/utils.c +++ b/utils.c @@ -16,10 +16,11 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "utils.h" +#include #include #include #include +#include "utils.h" #define foreach_arg(_arg, _addr, _len, _first_addr, _first_len) \ for (_addr = (_first_addr), _len = (_first_len); \ @@ -103,3 +104,48 @@ out: } #endif + +void *cbuf_alloc(unsigned int order) +{ + char path[] = "/tmp/cbuf-XXXXXX"; + unsigned long size = cbuf_size(order); + void *ret = NULL; + int fd; + + fd = mkstemp(path); + if (fd < 0) + return NULL; + + if (unlink(path)) + goto close; + + if (ftruncate(fd, cbuf_size(order))) + goto close; + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + + ret = mmap(NULL, size * 2, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0); + if (ret == MAP_FAILED) { + ret = NULL; + goto close; + } + + if (mmap(ret, size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, + fd, 0) != ret || + mmap(ret + size, size, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_SHARED, fd, 0) != ret + size) { + munmap(ret, size * 2); + ret = NULL; + } + +close: + close(fd); + return ret; +} + +void cbuf_free(void *ptr, unsigned int order) +{ + munmap(ptr, cbuf_size(order) * 2); +} -- cgit v1.2.3