From 0183e33d9a4759764716e771b85e19f7a997b8bd Mon Sep 17 00:00:00 2001 From: Timo Teras Date: Wed, 10 Mar 2010 20:11:06 +0200 Subject: mem: add mmap allocator use it for heaps and fiber stacks. --- include/libtf/heap.h | 3 ++- include/libtf/memory.h | 22 ++++++++++++++++++++++ src/TFbuild | 2 +- src/heap.c | 12 ++++++++---- src/mem-mmap.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/uctx.h | 7 +++++-- test/sleep.c | 2 +- 7 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 include/libtf/memory.h create mode 100644 src/mem-mmap.c diff --git a/include/libtf/heap.h b/include/libtf/heap.h index 3a16159..72c675a 100644 --- a/include/libtf/heap.h +++ b/include/libtf/heap.h @@ -14,6 +14,7 @@ #define TF_HEAP_H #include +#include #define TF_HEAP_D 4 #define TF_HEAP_ITEM0 (TF_HEAP_D - 1) @@ -78,7 +79,7 @@ static inline void tf_heap_destroy(struct tf_heap_head *head) { if (head->item) - free(head->item); + tf_bmem_free(head->item, head->allocated * sizeof(struct tf_heap_child)); head->item = NULL; head->num_items = 0; head->allocated = 0; diff --git a/include/libtf/memory.h b/include/libtf/memory.h new file mode 100644 index 0000000..04c2242 --- /dev/null +++ b/include/libtf/memory.h @@ -0,0 +1,22 @@ +/* memory.h - libtf memory allocator + * + * Copyright (C) 2009-2010 Timo Teräs + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 or later as + * published by the Free Software Foundation. + * + * See http://www.gnu.org/ for details. + */ + +#ifndef TF_MEMORY_H +#define TF_MEMORY_H + +/* Big/bulk memory allocation using mmap() or similar */ +void *tf_bmem_alloc(size_t size); +void *tf_bmem_resize(void *ptr, size_t oldsize, size_t newsize); +void tf_bmem_free(void *ptr, size_t size); + +#endif + diff --git a/src/TFbuild b/src/TFbuild index ef1c5ae..9277f9a 100644 --- a/src/TFbuild +++ b/src/TFbuild @@ -1,7 +1,7 @@ libs-y += libtf libtf-objs-y += fiber.o scheduler.o heap.o -libtf-objs-$(OS_LINUX) += io-epoll.o +libtf-objs-$(OS_LINUX) += io-epoll.o mem-mmap.o libtf-objs-$(OS_UNIX) += io-unix.o CFLAGS_heap.c += -funroll-all-loops diff --git a/src/heap.c b/src/heap.c index e93abe3..2473a70 100644 --- a/src/heap.c +++ b/src/heap.c @@ -112,12 +112,16 @@ int __tf_heap_grow(struct tf_heap_head *head) { void *item; - if (head->allocated) + if (head->allocated) { + item = tf_bmem_resize(head->item, + head->allocated * sizeof(struct tf_heap_child), + 2 * head->allocated * sizeof(struct tf_heap_child)); head->allocated *= 2; - else - head->allocated = 128; + } else { + head->allocated = 4096 / sizeof(struct tf_heap_child); + item = tf_bmem_alloc(head->allocated * sizeof(struct tf_heap_child)); + } - item = realloc(head->item, head->allocated * sizeof(head->item[0])); if (item == NULL) return -ENOMEM; diff --git a/src/mem-mmap.c b/src/mem-mmap.c new file mode 100644 index 0000000..b8e83cb --- /dev/null +++ b/src/mem-mmap.c @@ -0,0 +1,41 @@ +/* mem-mmap.c - mmap wrappings for large memory allocation + * + * Copyright (C) 2009 Timo Teräs + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 or later as + * published by the Free Software Foundation. + * + * See http://www.gnu.org/ for details. + */ + +#include +#include +#include + +void *tf_bmem_alloc(size_t size) +{ + void *ptr; + + ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + if (ptr == MAP_FAILED) + return NULL; + return ptr; +} + +void *tf_bmem_resize(void *oldptr, size_t oldsize, size_t newsize) +{ + void *ptr; + + ptr = mremap(oldptr, oldsize, newsize, MREMAP_MAYMOVE); + if (ptr == MAP_FAILED) + return NULL; + return ptr; +} + +void tf_bmem_free(void *ptr, size_t size) +{ + munmap(ptr, size); +} diff --git a/src/uctx.h b/src/uctx.h index 5eca6be..3ec30c4 100644 --- a/src/uctx.h +++ b/src/uctx.h @@ -11,6 +11,7 @@ */ #include +#include #include #include @@ -26,6 +27,7 @@ struct tf_uctx { int *stack_guard; + size_t size; void *alloc; void *current_sp; unsigned int stack_id; @@ -110,7 +112,7 @@ tf_uctx_create_embedded( void *stack, *stack_base; /* Allocate new stack */ - stack_base = malloc(size); + stack_base = tf_bmem_alloc(size); if (stack_base == NULL) return NULL; @@ -127,6 +129,7 @@ tf_uctx_create_embedded( *uctx = (struct tf_uctx) { .stack_guard = stack_guard(stack_base, size), .alloc = stack_base, + .size = size, .current_sp = stack, .stack_id = VALGRIND_STACK_REGISTER(stack_base, stack_base+size), }; @@ -140,7 +143,7 @@ void tf_uctx_destroy(struct tf_uctx *uctx) { if (uctx->alloc != NULL) { VALGRIND_STACK_DEREGISTER(uctx->stack_id); - free(uctx->alloc); + tf_bmem_free(uctx->alloc, uctx->size); } } diff --git a/test/sleep.c b/test/sleep.c index ec21a76..8e225a7 100644 --- a/test/sleep.c +++ b/test/sleep.c @@ -22,7 +22,7 @@ int main(int argc, char **argv) int i; tf_scheduler_enable(NULL); - for (i = 0; i < 100; i++) { + for (i = 0; i < 1000; i++) { c = tf_fiber_create(work_fiber, sizeof(struct ctx)); tf_fiber_put(c); } -- cgit v1.2.3