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:
@ -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.
|
||||
*
|
||||
|
||||
@ -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--;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user