diff options
-rw-r--r-- | include/libtf/heap.h | 3 | ||||
-rw-r--r-- | include/libtf/memory.h | 22 | ||||
-rw-r--r-- | src/TFbuild | 2 | ||||
-rw-r--r-- | src/heap.c | 12 | ||||
-rw-r--r-- | src/mem-mmap.c | 41 | ||||
-rw-r--r-- | src/uctx.h | 7 | ||||
-rw-r--r-- | test/sleep.c | 2 |
7 files changed, 80 insertions, 9 deletions
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 <libtf/defines.h> +#include <libtf/memory.h> #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 <timo.teras@iki.fi> + * 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 @@ -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 <timo.teras@iki.fi> + * 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 <sys/mman.h> +#include <libtf/defines.h> +#include <libtf/memory.h> + +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); +} @@ -11,6 +11,7 @@ */ #include <libtf/fiber.h> +#include <libtf/memory.h> #include <stdio.h> #include <stdlib.h> @@ -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); } |