From 4ec47440629af662f88a64bda1c6dac2e2806d65 Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Fri, 6 Jan 2023 10:09:14 +0000 Subject: [PATCH] Do not allocate aux stack for threads spawned by wasi_thread_start This syscall doesn't need allocating stack or TLS and it's expected from the application to do that instead. --- core/iwasm/common/wasm_exec_env.h | 7 +++++ core/iwasm/interpreter/wasm_interp_classic.c | 20 ++++++++----- core/iwasm/interpreter/wasm_interp_fast.c | 20 ++++++++----- .../lib-pthread/lib_pthread_wrapper.c | 5 ++-- .../lib_wasi_threads_wrapper.c | 4 +-- .../libraries/thread-mgr/thread_manager.c | 29 ++++++++++++------- .../libraries/thread-mgr/thread_manager.h | 2 +- 7 files changed, 55 insertions(+), 32 deletions(-) diff --git a/core/iwasm/common/wasm_exec_env.h b/core/iwasm/common/wasm_exec_env.h index 398292079a..72f973e7bf 100644 --- a/core/iwasm/common/wasm_exec_env.h +++ b/core/iwasm/common/wasm_exec_env.h @@ -179,6 +179,13 @@ wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst, void wasm_exec_env_destroy(WASMExecEnv *exec_env); +static inline bool +wasm_exec_env_is_aux_stack_managed_by_runtime(WASMExecEnv *exec_env) +{ + return exec_env->aux_stack_boundary.boundary != 0 + || exec_env->aux_stack_bottom.bottom != 0; +} + /** * Allocate a WASM frame from the WASM stack. * diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index fa542b14e0..d9cb3f5f38 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1783,14 +1783,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, global = globals + global_idx; global_addr = get_global_addr(global_data, global); aux_stack_top = *(uint32 *)(frame_sp - 1); - if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) { - wasm_set_exception(module, "wasm auxiliary stack overflow"); - goto got_exception; - } - if (aux_stack_top > exec_env->aux_stack_bottom.bottom) { - wasm_set_exception(module, - "wasm auxiliary stack underflow"); - goto got_exception; + if (wasm_exec_env_is_aux_stack_managed_by_runtime(exec_env)) { + if (aux_stack_top + <= exec_env->aux_stack_boundary.boundary) { + wasm_set_exception(module, + "wasm auxiliary stack overflow"); + goto got_exception; + } + if (aux_stack_top > exec_env->aux_stack_bottom.bottom) { + wasm_set_exception(module, + "wasm auxiliary stack underflow"); + goto got_exception; + } } *(int32 *)global_addr = aux_stack_top; frame_sp--; diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 3109b0c824..4f1ae3c7c0 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1576,14 +1576,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, global = globals + global_idx; global_addr = get_global_addr(global_data, global); aux_stack_top = frame_lp[GET_OFFSET()]; - if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) { - wasm_set_exception(module, "wasm auxiliary stack overflow"); - goto got_exception; - } - if (aux_stack_top > exec_env->aux_stack_bottom.bottom) { - wasm_set_exception(module, - "wasm auxiliary stack underflow"); - goto got_exception; + if (wasm_exec_env_is_aux_stack_managed_by_runtime(exec_env)) { + if (aux_stack_top + <= exec_env->aux_stack_boundary.boundary) { + wasm_set_exception(module, + "wasm auxiliary stack overflow"); + goto got_exception; + } + if (aux_stack_top > exec_env->aux_stack_bottom.bottom) { + wasm_set_exception(module, + "wasm auxiliary stack underflow"); + goto got_exception; + } } *(int32 *)global_addr = aux_stack_top; #if WASM_ENABLE_MEMORY_PROFILING != 0 diff --git a/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c b/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c index 9f5a9a8f30..9ab7848c42 100644 --- a/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c +++ b/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c @@ -619,8 +619,9 @@ pthread_create_wrapper(wasm_exec_env_t exec_env, routine_args->module_inst = new_module_inst; os_mutex_lock(&exec_env->wait_lock); - ret = wasm_cluster_create_thread( - exec_env, new_module_inst, pthread_start_routine, (void *)routine_args); + ret = + wasm_cluster_create_thread(exec_env, new_module_inst, true, + pthread_start_routine, (void *)routine_args); if (ret != 0) { os_mutex_unlock(&exec_env->wait_lock); goto fail; diff --git a/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c b/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c index 846c908c99..044e5d22e1 100644 --- a/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c +++ b/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c @@ -126,8 +126,8 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg) thread_start_arg->start_func = start_func; os_mutex_lock(&exec_env->wait_lock); - ret = wasm_cluster_create_thread(exec_env, new_module_inst, thread_start, - thread_start_arg); + ret = wasm_cluster_create_thread(exec_env, new_module_inst, false, + thread_start, thread_start_arg); if (ret != 0) { LOG_ERROR("Failed to spawn a new thread"); goto thread_spawn_fail; diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 611414a434..e2a0df8beb 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -125,6 +125,10 @@ free_aux_stack(WASMExecEnv *exec_env, uint32 start) WASMModuleInstanceCommon *module_inst = wasm_exec_env_get_module_inst(exec_env); + if (!wasm_exec_env_is_aux_stack_managed_by_runtime(exec_env)) { + return true; + } + bh_assert(start >= cluster->stack_size); wasm_runtime_module_free(module_inst, start - cluster->stack_size); @@ -534,7 +538,7 @@ thread_manager_start_routine(void *arg) int32 wasm_cluster_create_thread(WASMExecEnv *exec_env, - wasm_module_inst_t module_inst, + wasm_module_inst_t module_inst, bool alloc_aux_stack, void *(*thread_routine)(void *), void *arg) { WASMCluster *cluster; @@ -550,16 +554,18 @@ wasm_cluster_create_thread(WASMExecEnv *exec_env, if (!new_exec_env) return -1; - if (!allocate_aux_stack(exec_env, &aux_stack_start, &aux_stack_size)) { - LOG_ERROR("thread manager error: " - "failed to allocate aux stack space for new thread"); - goto fail1; - } + if (alloc_aux_stack) { + if (!allocate_aux_stack(exec_env, &aux_stack_start, &aux_stack_size)) { + LOG_ERROR("thread manager error: " + "failed to allocate aux stack space for new thread"); + goto fail1; + } - /* Set aux stack for current thread */ - if (!wasm_exec_env_set_aux_stack(new_exec_env, aux_stack_start, - aux_stack_size)) { - goto fail2; + /* Set aux stack for current thread */ + if (!wasm_exec_env_set_aux_stack(new_exec_env, aux_stack_start, + aux_stack_size)) { + goto fail2; + } } if (!wasm_cluster_add_exec_env(cluster, new_exec_env)) @@ -581,7 +587,8 @@ wasm_cluster_create_thread(WASMExecEnv *exec_env, wasm_cluster_del_exec_env(cluster, new_exec_env); fail2: /* free the allocated aux stack space */ - free_aux_stack(exec_env, aux_stack_start); + if (alloc_aux_stack) + free_aux_stack(exec_env, aux_stack_start); fail1: wasm_exec_env_destroy(new_exec_env); return -1; diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.h b/core/iwasm/libraries/thread-mgr/thread_manager.h index aa1a9154ba..54e71ce729 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.h +++ b/core/iwasm/libraries/thread-mgr/thread_manager.h @@ -64,7 +64,7 @@ wasm_exec_env_get_cluster(WASMExecEnv *exec_env); int32 wasm_cluster_create_thread(WASMExecEnv *exec_env, - wasm_module_inst_t module_inst, + wasm_module_inst_t module_inst, bool alloc_aux_stack, void *(*thread_routine)(void *), void *arg); int32