From a33289b749c71eb31b48c77159ba1d8bd23265ec Mon Sep 17 00:00:00 2001 From: Dmitry Simonenko Date: Mon, 27 Nov 2017 16:54:16 +0300 Subject: [PATCH] machinarium: allocate coroutine stack using mmap and redzone --- sources/context_stack.c | 16 +++++++++++----- sources/context_stack.h | 3 ++- sources/coroutine.c | 4 ++-- sources/coroutine.h | 2 +- sources/coroutine_cache.c | 8 ++++++-- sources/coroutine_cache.h | 3 ++- sources/machinarium_private.h | 1 + sources/mm.c | 12 +++++++++++- 8 files changed, 36 insertions(+), 13 deletions(-) diff --git a/sources/context_stack.c b/sources/context_stack.c index 40480df9..2217cea2 100644 --- a/sources/context_stack.c +++ b/sources/context_stack.c @@ -12,12 +12,17 @@ # include #endif -int mm_contextstack_create(mm_contextstack_t *stack, size_t size) +int mm_contextstack_create(mm_contextstack_t *stack, size_t size, size_t size_guard) { - stack->size = size; - stack->pointer = malloc(stack->size); - if (stack->pointer == NULL) + char *base; + base = mmap(0, size_guard + size, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (base == MAP_FAILED) return -1; + mprotect(base, size_guard, PROT_NONE); + base += size_guard; + stack->pointer = base; + stack->size = size; #ifdef HAVE_VALGRIND stack->valgrind_stack = VALGRIND_STACK_REGISTER(stack->pointer, stack->pointer + stack->size); @@ -32,5 +37,6 @@ void mm_contextstack_free(mm_contextstack_t *stack) #ifdef HAVE_VALGRIND VALGRIND_STACK_DEREGISTER(stack->valgrind_stack); #endif - free(stack->pointer); + char *base = stack->pointer - stack->size_guard; + munmap(base, stack->size_guard + stack->size); } diff --git a/sources/context_stack.h b/sources/context_stack.h index 9b74a5e2..b7ce5cb3 100644 --- a/sources/context_stack.h +++ b/sources/context_stack.h @@ -13,12 +13,13 @@ struct mm_contextstack { char *pointer; size_t size; + size_t size_guard; #ifdef HAVE_VALGRIND int valgrind_stack; #endif }; -int mm_contextstack_create(mm_contextstack_t*, size_t); +int mm_contextstack_create(mm_contextstack_t*, size_t, size_t); void mm_contextstack_free(mm_contextstack_t*); #endif /* MM_CONTEXT_STACK_H */ diff --git a/sources/coroutine.c b/sources/coroutine.c index 737e8382..ecb32ef1 100644 --- a/sources/coroutine.c +++ b/sources/coroutine.c @@ -21,7 +21,7 @@ void mm_coroutine_init(mm_coroutine_t *coroutine) } mm_coroutine_t* -mm_coroutine_allocate(int stack_size) +mm_coroutine_allocate(int stack_size, int stack_size_guard) { mm_coroutine_t *coroutine; coroutine = malloc(sizeof(mm_coroutine_t)); @@ -29,7 +29,7 @@ mm_coroutine_allocate(int stack_size) return NULL; mm_coroutine_init(coroutine); int rc; - rc = mm_contextstack_create(&coroutine->stack, stack_size); + rc = mm_contextstack_create(&coroutine->stack, stack_size, stack_size_guard); if (rc == -1) { free(coroutine); return NULL; diff --git a/sources/coroutine.h b/sources/coroutine.h index 8d1f7074..0d5c8de7 100644 --- a/sources/coroutine.h +++ b/sources/coroutine.h @@ -37,7 +37,7 @@ struct mm_coroutine }; mm_coroutine_t* -mm_coroutine_allocate(int); +mm_coroutine_allocate(int, int); void mm_coroutine_init(mm_coroutine_t*); void mm_coroutine_free(mm_coroutine_t*); diff --git a/sources/coroutine_cache.c b/sources/coroutine_cache.c index 7ee5da56..debe2135 100644 --- a/sources/coroutine_cache.c +++ b/sources/coroutine_cache.c @@ -8,12 +8,16 @@ #include #include -void mm_coroutine_cache_init(mm_coroutine_cache_t *cache, int stack_size, int limit) +void mm_coroutine_cache_init(mm_coroutine_cache_t *cache, + int stack_size, + int stack_size_guard, + int limit) { pthread_spin_init(&cache->lock, PTHREAD_PROCESS_PRIVATE); mm_list_init(&cache->list); cache->count = 0; cache->stack_size = stack_size; + cache->stack_size_guard = stack_size_guard; cache->limit = limit; } @@ -42,7 +46,7 @@ mm_coroutine_cache_pop(mm_coroutine_cache_t *cache) } pthread_spin_unlock(&cache->lock); - return mm_coroutine_allocate(cache->stack_size); + return mm_coroutine_allocate(cache->stack_size, cache->stack_size_guard); } void mm_coroutine_cache_push(mm_coroutine_cache_t *cache, mm_coroutine_t *coroutine) diff --git a/sources/coroutine_cache.h b/sources/coroutine_cache.h index 10301759..aebf8609 100644 --- a/sources/coroutine_cache.h +++ b/sources/coroutine_cache.h @@ -13,12 +13,13 @@ struct mm_coroutine_cache { pthread_spinlock_t lock; int stack_size; + int stack_size_guard; mm_list_t list; int count; int limit; }; -void mm_coroutine_cache_init(mm_coroutine_cache_t*, int, int); +void mm_coroutine_cache_init(mm_coroutine_cache_t*, int, int, int); void mm_coroutine_cache_free(mm_coroutine_cache_t*); mm_coroutine_t* diff --git a/sources/machinarium_private.h b/sources/machinarium_private.h index 2fb3148b..80523d1e 100644 --- a/sources/machinarium_private.h +++ b/sources/machinarium_private.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/sources/mm.c b/sources/mm.c index a735605f..a7f88be7 100644 --- a/sources/mm.c +++ b/sources/mm.c @@ -11,12 +11,22 @@ static int machinarium_initialized = 0; mm_t machinarium; +static inline size_t +machinarium_page_size(void) +{ + return sysconf(_SC_PAGESIZE); +} + MACHINE_API int machinarium_init(void) { mm_machinemgr_init(&machinarium.machine_mgr); mm_msgcache_init(&machinarium.msg_cache); - mm_coroutine_cache_init(&machinarium.coroutine_cache, 12288, 100); + size_t page_size; + page_size = machinarium_page_size(); + mm_coroutine_cache_init(&machinarium.coroutine_cache, + page_size * 3, + page_size, 100); mm_tls_init(); mm_taskmgr_init(&machinarium.task_mgr); mm_taskmgr_start(&machinarium.task_mgr, 3);