Disable aux stack allocations for threads spawned by wasi_thread_start (#1867)

This syscall doesn't need allocating stack or TLS and it's expected from the application
to do that instead. E.g. WASI-libc already does this for `pthread_create`.

Also fix some of the examples to allocate memory for stack and not use stack before
the stack pointer is set to a correct value.
This commit is contained in:
Marcin Kolny
2023-01-09 12:36:34 +00:00
committed by GitHub
parent 2615646c20
commit 0e2382a959
12 changed files with 163 additions and 56 deletions

View File

@ -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.
*

View File

@ -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--;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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 @@ fail3:
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;

View File

@ -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