From 4bd461d9e2bf4b051c9f7172c9defe3335538e88 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 15 Sep 2016 21:25:32 -0400 Subject: [PATCH] added new generic memory allocator --- include/villas/memory.h | 43 ++++++++++++++++++++++ lib/memory.c | 80 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 include/villas/memory.h create mode 100644 lib/memory.c diff --git a/include/villas/memory.h b/include/villas/memory.h new file mode 100644 index 000000000..19711f7a0 --- /dev/null +++ b/include/villas/memory.h @@ -0,0 +1,43 @@ +/** + * + */ + +#ifndef _MEMORY_H_ +#define _MEMORY_H_ + +typedef void *(*memzone_allocator_t)(size_t); +typedef int (*memzone_deallocator_t)(void *, size_t); + +enum memtype_flags { + MEMORY_MMAP = (1 << 0), + MEMORY_DMA = (1 << 1), + MEMORY_HUGEPAGE = (1 << 2), + MEMORY_HEAP = (1 << 3) +}; + +struct memtype { + const char *name; + int flags; + + size_t alignment; + + memzone_allocator_t alloc; + memzone_deallocator_t dealloc; +}; + +/** @todo Unused for now */ +struct memzone { + struct memtype * const type; + + void *addr; + uintptr_t physaddr; + size_t len; +}; + +void * memory_alloc(const struct memtype *m, size_t len); +int memory_free(const struct memtype *m, void *ptr, size_t len); + +extern const struct memtype memtype_heap; +extern const struct memtype memtype_hugepage; + +#endif /* _MEMORY_H_ */ \ No newline at end of file diff --git a/lib/memory.c b/lib/memory.c new file mode 100644 index 000000000..e7c01e38f --- /dev/null +++ b/lib/memory.c @@ -0,0 +1,80 @@ +/** + * + */ + +#include +#include + +/* Required to allocate hugepages on Apple OS X */ +#ifdef __MACH__ + #include +#endif + +#include "memory.h" + +void * memory_alloc(const struct memtype *m, size_t len) +{ + return m->alloc(len); +} + +int memory_free(const struct memtype *m, void *ptr, size_t len) +{ + return m->dealloc(ptr, len); +} + +static void * memory_heap_alloc(size_t len) +{ + return malloc(len); +} + +int memory_heap_dealloc(void *ptr, size_t len) +{ + free(ptr); + + return 0; +} + +/** Allocate memory backed by hugepages with malloc() like interface */ +static void * memory_hugepage_alloc(size_t len) +{ + int prot = PROT_READ | PROT_WRITE; + int flags = MAP_PRIVATE | MAP_ANONYMOUS; + +#ifdef __MACH__ + flags |= VM_FLAGS_SUPERPAGE_SIZE_2MB; +#elif defined(__linux__) + flags |= MAP_HUGETLB | MAP_LOCKED; +#endif + + return mmap(NULL, len, prot, flags, -1, 0); +} + +static int memory_hugepage_dealloc(void *ptr, size_t len) +{ + return munmap(ptr, len); +} + +/* List of available memory types */ +const struct memtype memtype_heap = { + .name = "heap", + .flags = MEMORY_HEAP, + .alloc = memory_heap_alloc, + .dealloc = memory_heap_dealloc, + .alignment = 1 +}; + +const struct memtype memtype_hugepage = { + .name = "mmap_hugepages", + .flags = MEMORY_MMAP | MEMORY_HUGEPAGE, + .alloc = memory_hugepage_alloc, + .dealloc = memory_hugepage_dealloc, + .alignment = 1 << 21 /* 2 MiB hugepage */ +}; + +/** @todo */ +const struct memtype memtype_dma = { + .name = "dma", + .flags = MEMORY_DMA | MEMORY_MMAP, + .alloc = NULL, .dealloc = NULL, + .alignment = 1 << 12 +};