"Module":"alloc",
"Title":"alloc - memory allocator routines",
"Author":"test",
"Dependencies":[
{
"depends":"ccan/build_assert"
},
]
"Description":[
{
"str":""
},
{
"str":"The alloc module implements a simple allocator which you can use to"
},
{
"str":"dynamically allocate space within a region of memory.  This can be useful"
},
{
"str":"for suballocations within a given region, or a memory-mapped file."
},
{
"str":""
},
{
"str":"All metadata is kept within the memory handed to the allocator: you only"
},
{
"str":"need hand the pointer and the size of the memory to each call."
},
{
"str":""
},
{
"str":"The region contents is always in offsets, so it can be mapped in different"
},
{
"str":"places, but is not endian-safe."
},
{
"str":""
},
{
"str":"Example:"
},
{
"str":"	#include <sys/mman.h>"
},
{
"str":"	#include <unistd.h>"
},
{
"str":"	#include <sys/types.h>"
},
{
"str":"	#include <err.h>"
},
{
"str":"	#include "alloc/alloc.h""
},
{
"str":""
},
{
"str":"	static void usage(const char *name)"
},
{
"str":"	{"
},
{
"str":"		errx(1, "Usage: %s --create <mapfile>\n""
},
{
"str":"		     " %s --check <mapfile>\n""
},
{
"str":"		     " %s --alloc <mapfile>\n""
},
{
"str":"		     " %s --free=<offset> <mapfile>\n", name, name, name);"
},
{
"str":"	}"
},
{
"str":""
},
{
"str":"	// Create a memory mapped file, and allocate from within it"
},
{
"str":"	int main(int argc, char *argv[])"
},
{
"str":"	{"
},
{
"str":"		void *a, *p;"
},
{
"str":"		int fd;"
},
{
"str":"		enum { CREATE, CHECK, ALLOC, FREE } cmd;"
},
{
"str":""
},
{
"str":"		if (argc != 3)"
},
{
"str":"			usage(argv[0]);"
},
{
"str":""
},
{
"str":"		if (strcmp(argv[1], "--create") == 0)"
},
{
"str":"			cmd = CREATE;"
},
{
"str":"		else if (strcmp(argv[1], "--check") == 0)"
},
{
"str":"			cmd = CHECK;"
},
{
"str":"		else if (strcmp(argv[1], "--alloc") == 0)"
},
{
"str":"			cmd = ALLOC;"
},
{
"str":"		else if (strncmp(argv[1], "--free=", strlen("--free=")) == 0)"
},
{
"str":"			cmd = FREE;"
},
{
"str":"		else"
},
{
"str":"			usage(argv[0]);"
},
{
"str":""
},
{
"str":"		if (cmd == CREATE) {"
},
{
"str":"			fd = open(argv[2], O_RDWR|O_CREAT|O_EXCL, 0600);"
},
{
"str":"			if (fd < 0)"
},
{
"str":"				err(1, "Could not create %s", argv[2]);"
},
{
"str":"			if (ftruncate(fd, 1048576) != 0)"
},
{
"str":"				err(1, "Could not set length on %s", argv[2]);"
},
{
"str":"		} else {"
},
{
"str":"			fd = open(argv[2], O_RDWR);"
},
{
"str":"			if (fd < 0)"
},
{
"str":"				err(1, "Could not open %s", argv[2]);"
},
{
"str":"		}"
},
{
"str":""
},
{
"str":"		a = mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_SHARED, fd,0);"
},
{
"str":"		if (a == MAP_FAILED)"
},
{
"str":"			err(1, "Could not map %s", argv[2]);"
},
{
"str":""
},
{
"str":"		switch (cmd) {"
},
{
"str":"		case CREATE:"
},
{
"str":"			alloc_init(a, 1048576);"
},
{
"str":"			break;"
},
{
"str":"		case CHECK:"
},
{
"str":"			if (!alloc_check(a, 1048576))"
},
{
"str":"				err(1, "Region is corrupt");"
},
{
"str":"			break;"
},
{
"str":"		case ALLOC:"
},
{
"str":"			p = alloc_get(a, 1048576, 1024, 16);"
},
{
"str":"			if (!p)"
},
{
"str":"				errx(1, "Could not allocate");"
},
{
"str":"			printf("%zu\n", (char *)p - (char *)a);"
},
{
"str":"			break;"
},
{
"str":"		case FREE:"
},
{
"str":"			p = (char *)a + atol(argv[1] + strlen("--free="));"
},
{
"str":"			alloc_free(a, 1048576, p);"
},
{
"str":"			break;"
},
{
"str":"		}"
},
{
"str":"		return 0;"
},
{
"str":"	}"
},
]
