Add/reorganize locks for thread synchronization (#1995)

Attempt to fix data races when using threads.
- Protect access (from multiple threads) to exception and memory
- Fix shared memory lock usage
This commit is contained in:
Enrico Loparco
2023-03-04 01:15:26 +01:00
committed by GitHub
parent 1c44411a97
commit e8d718096d
9 changed files with 274 additions and 81 deletions

View File

@ -194,7 +194,7 @@ runtime_signal_handler(void *sig_addr)
else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
&& (uint8 *)sig_addr
< exec_env_tls->exce_check_guard_page + page_size) {
bh_assert(wasm_get_exception(module_inst));
bh_assert(wasm_copy_exception(module_inst, NULL));
os_longjmp(jmpbuf_node->jmpbuf, 1);
}
}
@ -250,7 +250,7 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
&& (uint8 *)sig_addr
< exec_env_tls->exce_check_guard_page + page_size) {
bh_assert(wasm_get_exception(module_inst));
bh_assert(wasm_copy_exception(module_inst, NULL));
if (module_inst->module_type == Wasm_Module_Bytecode) {
return EXCEPTION_CONTINUE_SEARCH;
}
@ -1870,14 +1870,15 @@ static bool
clear_wasi_proc_exit_exception(WASMModuleInstanceCommon *module_inst_comm)
{
#if WASM_ENABLE_LIBC_WASI != 0
const char *exception;
bool has_exception;
char exception[EXCEPTION_BUF_LEN];
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
exception = wasm_get_exception(module_inst);
if (exception && !strcmp(exception, "Exception: wasi proc exit")) {
has_exception = wasm_copy_exception(module_inst, exception);
if (has_exception && !strcmp(exception, "Exception: wasi proc exit")) {
/* The "wasi proc exit" exception is thrown by native lib to
let wasm app exit, which is a normal behavior, we clear
the exception here. And just clear the exception of current
@ -2306,6 +2307,12 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
{
WASMExecEnv *exec_env = NULL;
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module_inst->module);
if (node)
os_mutex_lock(&node->shared_mem_lock);
#endif
if (exception) {
snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception),
"Exception: %s", exception);
@ -2313,6 +2320,10 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
else {
module_inst->cur_exception[0] = '\0';
}
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_unlock(&node->shared_mem_lock);
#endif
#if WASM_ENABLE_THREAD_MGR != 0
exec_env =
@ -2373,6 +2384,36 @@ wasm_get_exception(WASMModuleInstance *module_inst)
return module_inst->cur_exception;
}
bool
wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf)
{
bool has_exception = false;
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module_inst->module);
if (node)
os_mutex_lock(&node->shared_mem_lock);
#endif
if (module_inst->cur_exception[0] != '\0') {
/* NULL is passed if the caller is not interested in getting the
* exception content, but only in knowing if an exception has been
* raised
*/
if (exception_buf != NULL)
bh_memcpy_s(exception_buf, sizeof(module_inst->cur_exception),
module_inst->cur_exception,
sizeof(module_inst->cur_exception));
has_exception = true;
}
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_unlock(&node->shared_mem_lock);
#endif
return has_exception;
}
void
wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst_comm,
const char *exception)
@ -2394,6 +2435,17 @@ wasm_runtime_get_exception(WASMModuleInstanceCommon *module_inst_comm)
return wasm_get_exception(module_inst);
}
bool
wasm_runtime_copy_exception(WASMModuleInstanceCommon *module_inst_comm,
char *exception_buf)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
return wasm_copy_exception(module_inst, exception_buf);
}
void
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst_comm)
{
@ -3317,7 +3369,7 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
}
}
ret = !wasm_runtime_get_exception(module) ? true : false;
ret = !wasm_runtime_copy_exception(module, NULL);
fail:
if (argv1 != argv_buf)
@ -3792,7 +3844,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
exec_env->attachment = NULL;
ret = !wasm_runtime_get_exception(module) ? true : false;
ret = !wasm_runtime_copy_exception(module, NULL);
fail:
if (argv1 != argv_buf)
@ -4006,7 +4058,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
exec_env->attachment = NULL;
ret = !wasm_runtime_get_exception(module) ? true : false;
ret = !wasm_runtime_copy_exception(module, NULL);
fail:
if (argv1 != argv_buf)
@ -4333,7 +4385,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
exec_env->attachment = NULL;
ret = !wasm_runtime_get_exception(module) ? true : false;
ret = !wasm_runtime_copy_exception(module, NULL);
fail:
if (argv1 != argv_buf)
wasm_runtime_free(argv1);