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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 274 additions and 81 deletions

View File

@ -8,6 +8,10 @@
#include "bh_platform.h" #include "bh_platform.h"
#include "mem_alloc.h" #include "mem_alloc.h"
#if WASM_ENABLE_SHARED_MEMORY != 0
#include "../common/wasm_shared_memory.h"
#endif
typedef enum Memory_Mode { typedef enum Memory_Mode {
MEMORY_MODE_UNKNOWN = 0, MEMORY_MODE_UNKNOWN = 0,
MEMORY_MODE_POOL, MEMORY_MODE_POOL,
@ -506,7 +510,7 @@ wasm_get_default_memory(WASMModuleInstance *module_inst)
#ifndef OS_ENABLE_HW_BOUND_CHECK #ifndef OS_ENABLE_HW_BOUND_CHECK
bool bool
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
{ {
WASMMemoryInstance *memory = wasm_get_default_memory(module); WASMMemoryInstance *memory = wasm_get_default_memory(module);
uint8 *memory_data_old, *memory_data_new, *heap_data_old; uint8 *memory_data_old, *memory_data_new, *heap_data_old;
@ -624,7 +628,7 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
} }
#else #else
bool bool
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
{ {
WASMMemoryInstance *memory = wasm_get_default_memory(module); WASMMemoryInstance *memory = wasm_get_default_memory(module);
uint32 num_bytes_per_page, total_size_old; uint32 num_bytes_per_page, total_size_old;
@ -697,3 +701,59 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
return true; return true;
} }
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */ #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
bool
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
{
bool ret = false;
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
if (node)
os_mutex_lock(&node->shared_mem_lock);
#endif
ret = wasm_enlarge_memory_internal(module, inc_page_count);
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_unlock(&node->shared_mem_lock);
#endif
return ret;
}
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0
uint32
wasm_get_num_bytes_per_page(WASMMemoryInstance *memory, void *node)
{
uint32 num_bytes_per_page;
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_lock(&((WASMSharedMemNode *)node)->shared_mem_lock);
#endif
num_bytes_per_page = memory->num_bytes_per_page;
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_unlock(&((WASMSharedMemNode *)node)->shared_mem_lock);
#endif
return num_bytes_per_page;
}
uint32
wasm_get_linear_memory_size(WASMMemoryInstance *memory, void *node)
{
uint32 linear_mem_size;
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_lock(&((WASMSharedMemNode *)node)->shared_mem_lock);
#endif
linear_mem_size = memory->num_bytes_per_page * memory->cur_page_count;
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_unlock(&((WASMSharedMemNode *)node)->shared_mem_lock);
#endif
return linear_mem_size;
}
#endif

View File

@ -8,6 +8,7 @@
#include "bh_common.h" #include "bh_common.h"
#include "../include/wasm_export.h" #include "../include/wasm_export.h"
#include "../interpreter/wasm_runtime.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -23,6 +24,16 @@ wasm_runtime_memory_destroy();
unsigned unsigned
wasm_runtime_memory_pool_size(); wasm_runtime_memory_pool_size();
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0
uint32
wasm_get_num_bytes_per_page(WASMMemoryInstance *memory, void *node);
uint32
wasm_get_linear_memory_size(WASMMemoryInstance *memory, void *node);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -194,7 +194,7 @@ runtime_signal_handler(void *sig_addr)
else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
&& (uint8 *)sig_addr && (uint8 *)sig_addr
< exec_env_tls->exce_check_guard_page + page_size) { < 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); 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 else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
&& (uint8 *)sig_addr && (uint8 *)sig_addr
< exec_env_tls->exce_check_guard_page + page_size) { < 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) { if (module_inst->module_type == Wasm_Module_Bytecode) {
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }
@ -1870,14 +1870,15 @@ static bool
clear_wasi_proc_exit_exception(WASMModuleInstanceCommon *module_inst_comm) clear_wasi_proc_exit_exception(WASMModuleInstanceCommon *module_inst_comm)
{ {
#if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_LIBC_WASI != 0
const char *exception; bool has_exception;
char exception[EXCEPTION_BUF_LEN];
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT); || module_inst_comm->module_type == Wasm_Module_AoT);
exception = wasm_get_exception(module_inst); has_exception = wasm_copy_exception(module_inst, exception);
if (exception && !strcmp(exception, "Exception: wasi proc exit")) { if (has_exception && !strcmp(exception, "Exception: wasi proc exit")) {
/* The "wasi proc exit" exception is thrown by native lib to /* The "wasi proc exit" exception is thrown by native lib to
let wasm app exit, which is a normal behavior, we clear let wasm app exit, which is a normal behavior, we clear
the exception here. And just clear the exception of current 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; 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) { if (exception) {
snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception), snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception),
"Exception: %s", exception); "Exception: %s", exception);
@ -2313,6 +2320,10 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
else { else {
module_inst->cur_exception[0] = '\0'; 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 #if WASM_ENABLE_THREAD_MGR != 0
exec_env = exec_env =
@ -2373,6 +2384,36 @@ wasm_get_exception(WASMModuleInstance *module_inst)
return module_inst->cur_exception; 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 void
wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst_comm, wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst_comm,
const char *exception) const char *exception)
@ -2394,6 +2435,17 @@ wasm_runtime_get_exception(WASMModuleInstanceCommon *module_inst_comm)
return wasm_get_exception(module_inst); 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 void
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst_comm) 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: fail:
if (argv1 != argv_buf) if (argv1 != argv_buf)
@ -3792,7 +3844,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
} }
exec_env->attachment = NULL; exec_env->attachment = NULL;
ret = !wasm_runtime_get_exception(module) ? true : false; ret = !wasm_runtime_copy_exception(module, NULL);
fail: fail:
if (argv1 != argv_buf) if (argv1 != argv_buf)
@ -4006,7 +4058,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
} }
exec_env->attachment = NULL; exec_env->attachment = NULL;
ret = !wasm_runtime_get_exception(module) ? true : false; ret = !wasm_runtime_copy_exception(module, NULL);
fail: fail:
if (argv1 != argv_buf) if (argv1 != argv_buf)
@ -4333,7 +4385,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
} }
exec_env->attachment = NULL; exec_env->attachment = NULL;
ret = !wasm_runtime_get_exception(module) ? true : false; ret = !wasm_runtime_copy_exception(module, NULL);
fail: fail:
if (argv1 != argv_buf) if (argv1 != argv_buf)
wasm_runtime_free(argv1); wasm_runtime_free(argv1);

View File

@ -37,6 +37,7 @@ typedef struct AtomicWaitAddressArgs {
/* Atomic wait map */ /* Atomic wait map */
static HashMap *wait_map; static HashMap *wait_map;
static korp_mutex wait_map_lock;
static uint32 static uint32
wait_address_hash(void *address); wait_address_hash(void *address);
@ -52,11 +53,18 @@ wasm_shared_memory_init()
{ {
if (os_mutex_init(&shared_memory_list_lock) != 0) if (os_mutex_init(&shared_memory_list_lock) != 0)
return false; return false;
if (os_mutex_init(&wait_map_lock) != 0) {
os_mutex_destroy(&shared_memory_list_lock);
return false;
}
/* wait map not exists, create new map */ /* wait map not exists, create new map */
if (!(wait_map = bh_hash_map_create(32, true, (HashFunc)wait_address_hash, if (!(wait_map = bh_hash_map_create(32, true, (HashFunc)wait_address_hash,
(KeyEqualFunc)wait_address_equal, NULL, (KeyEqualFunc)wait_address_equal, NULL,
destroy_wait_info))) { destroy_wait_info))) {
os_mutex_destroy(&shared_memory_list_lock); os_mutex_destroy(&shared_memory_list_lock);
os_mutex_destroy(&wait_map_lock);
return false; return false;
} }
@ -67,6 +75,7 @@ void
wasm_shared_memory_destroy() wasm_shared_memory_destroy()
{ {
os_mutex_destroy(&shared_memory_list_lock); os_mutex_destroy(&shared_memory_list_lock);
os_mutex_destroy(&wait_map_lock);
if (wait_map) { if (wait_map) {
bh_hash_map_destroy(wait_map); bh_hash_map_destroy(wait_map);
} }
@ -113,14 +122,14 @@ notify_stale_threads_on_exception(WASMModuleInstanceCommon *module_inst)
uint32 i = 0, total_elem_count = 0; uint32 i = 0, total_elem_count = 0;
uint64 total_elem_count_size = 0; uint64 total_elem_count_size = 0;
os_mutex_lock(&shared_memory_list_lock); os_mutex_lock(&wait_map_lock); /* Make the two traversals atomic */
/* count number of addresses in wait_map */ /* count number of addresses in wait_map */
bh_hash_map_traverse(wait_map, wait_map_address_count_callback, bh_hash_map_traverse(wait_map, wait_map_address_count_callback,
(void *)&total_elem_count); (void *)&total_elem_count);
if (!total_elem_count) { if (!total_elem_count) {
os_mutex_unlock(&shared_memory_list_lock); os_mutex_unlock(&wait_map_lock);
return; return;
} }
@ -130,13 +139,13 @@ notify_stale_threads_on_exception(WASMModuleInstanceCommon *module_inst)
|| !(args.addr = wasm_runtime_malloc((uint32)total_elem_count_size))) { || !(args.addr = wasm_runtime_malloc((uint32)total_elem_count_size))) {
LOG_ERROR( LOG_ERROR(
"failed to allocate memory for list of atomic wait addresses"); "failed to allocate memory for list of atomic wait addresses");
os_mutex_unlock(&shared_memory_list_lock); os_mutex_unlock(&wait_map_lock);
return; return;
} }
/* set values in list of addresses */ /* set values in list of addresses */
bh_hash_map_traverse(wait_map, create_list_of_waiter_addresses, &args); bh_hash_map_traverse(wait_map, create_list_of_waiter_addresses, &args);
os_mutex_unlock(&shared_memory_list_lock); os_mutex_unlock(&wait_map_lock);
/* notify */ /* notify */
for (i = 0; i < args.index; i++) { for (i = 0; i < args.index; i++) {
@ -276,9 +285,11 @@ notify_wait_list(bh_list *wait_list, uint32 count)
bh_assert(node); bh_assert(node);
next = bh_list_elem_next(node); next = bh_list_elem_next(node);
os_mutex_lock(&node->wait_lock);
node->status = S_NOTIFIED; node->status = S_NOTIFIED;
/* wakeup */ /* wakeup */
os_cond_signal(&node->wait_cond); os_cond_signal(&node->wait_cond);
os_mutex_unlock(&node->wait_lock);
node = next; node = next;
} }
@ -292,13 +303,13 @@ acquire_wait_info(void *address, bool create)
AtomicWaitInfo *wait_info = NULL; AtomicWaitInfo *wait_info = NULL;
bh_list_status ret; bh_list_status ret;
os_mutex_lock(&shared_memory_list_lock); os_mutex_lock(&wait_map_lock); /* Make find + insert atomic */
if (address) if (address)
wait_info = (AtomicWaitInfo *)bh_hash_map_find(wait_map, address); wait_info = (AtomicWaitInfo *)bh_hash_map_find(wait_map, address);
if (!create) { if (!create) {
os_mutex_unlock(&shared_memory_list_lock); os_mutex_unlock(&wait_map_lock);
return wait_info; return wait_info;
} }
@ -325,7 +336,7 @@ acquire_wait_info(void *address, bool create)
} }
} }
os_mutex_unlock(&shared_memory_list_lock); os_mutex_unlock(&wait_map_lock);
bh_assert(wait_info); bh_assert(wait_info);
(void)ret; (void)ret;
@ -338,7 +349,7 @@ fail2:
wasm_runtime_free(wait_info); wasm_runtime_free(wait_info);
fail1: fail1:
os_mutex_unlock(&shared_memory_list_lock); os_mutex_unlock(&wait_map_lock);
return NULL; return NULL;
} }
@ -365,17 +376,16 @@ destroy_wait_info(void *wait_info)
} }
} }
static void static bool
release_wait_info(HashMap *wait_map_, AtomicWaitInfo *wait_info, void *address) map_remove_wait_info(HashMap *wait_map_, AtomicWaitInfo *wait_info,
void *address)
{ {
os_mutex_lock(&shared_memory_list_lock); if (wait_info->wait_list->len > 0) {
return false;
if (wait_info->wait_list->len == 0) {
bh_hash_map_remove(wait_map_, address, NULL, NULL);
destroy_wait_info(wait_info);
} }
os_mutex_unlock(&shared_memory_list_lock); bh_hash_map_remove(wait_map_, address, NULL, NULL);
return true;
} }
uint32 uint32
@ -386,12 +396,12 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
AtomicWaitInfo *wait_info; AtomicWaitInfo *wait_info;
AtomicWaitNode *wait_node; AtomicWaitNode *wait_node;
WASMSharedMemNode *node; WASMSharedMemNode *node;
bool check_ret, is_timeout, no_wait; bool check_ret, is_timeout, no_wait, removed_from_map;
bh_assert(module->module_type == Wasm_Module_Bytecode bh_assert(module->module_type == Wasm_Module_Bytecode
|| module->module_type == Wasm_Module_AoT); || module->module_type == Wasm_Module_AoT);
if (wasm_get_exception(module_inst)) { if (wasm_copy_exception(module_inst, NULL)) {
return -1; return -1;
} }
@ -416,8 +426,6 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
return -1; return -1;
} }
os_mutex_lock(&wait_info->wait_list_lock);
node = search_module((WASMModuleCommon *)module_inst->module); node = search_module((WASMModuleCommon *)module_inst->module);
os_mutex_lock(&node->shared_mem_lock); os_mutex_lock(&node->shared_mem_lock);
no_wait = (!wait64 && *(uint32 *)address != (uint32)expect) no_wait = (!wait64 && *(uint32 *)address != (uint32)expect)
@ -425,7 +433,6 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
os_mutex_unlock(&node->shared_mem_lock); os_mutex_unlock(&node->shared_mem_lock);
if (no_wait) { if (no_wait) {
os_mutex_unlock(&wait_info->wait_list_lock);
return 1; return 1;
} }
else { else {
@ -433,33 +440,29 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
if (!(wait_node = wasm_runtime_malloc(sizeof(AtomicWaitNode)))) { if (!(wait_node = wasm_runtime_malloc(sizeof(AtomicWaitNode)))) {
wasm_runtime_set_exception(module, "failed to create wait node"); wasm_runtime_set_exception(module, "failed to create wait node");
os_mutex_unlock(&wait_info->wait_list_lock);
return -1; return -1;
} }
memset(wait_node, 0, sizeof(AtomicWaitNode)); memset(wait_node, 0, sizeof(AtomicWaitNode));
if (0 != os_mutex_init(&wait_node->wait_lock)) { if (0 != os_mutex_init(&wait_node->wait_lock)) {
wasm_runtime_free(wait_node); wasm_runtime_free(wait_node);
os_mutex_unlock(&wait_info->wait_list_lock);
return -1; return -1;
} }
if (0 != os_cond_init(&wait_node->wait_cond)) { if (0 != os_cond_init(&wait_node->wait_cond)) {
os_mutex_destroy(&wait_node->wait_lock); os_mutex_destroy(&wait_node->wait_lock);
wasm_runtime_free(wait_node); wasm_runtime_free(wait_node);
os_mutex_unlock(&wait_info->wait_list_lock);
return -1; return -1;
} }
wait_node->status = S_WAITING; wait_node->status = S_WAITING;
os_mutex_lock(&wait_info->wait_list_lock);
ret = bh_list_insert(wait_info->wait_list, wait_node); ret = bh_list_insert(wait_info->wait_list, wait_node);
os_mutex_unlock(&wait_info->wait_list_lock);
bh_assert(ret == BH_LIST_SUCCESS); bh_assert(ret == BH_LIST_SUCCESS);
(void)ret; (void)ret;
} }
os_mutex_unlock(&wait_info->wait_list_lock);
/* condition wait start */ /* condition wait start */
os_mutex_lock(&wait_node->wait_lock); os_mutex_lock(&wait_node->wait_lock);
@ -467,23 +470,26 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
timeout < 0 ? BHT_WAIT_FOREVER timeout < 0 ? BHT_WAIT_FOREVER
: (uint64)timeout / 1000); : (uint64)timeout / 1000);
is_timeout = wait_node->status == S_WAITING ? true : false;
os_mutex_unlock(&wait_node->wait_lock); os_mutex_unlock(&wait_node->wait_lock);
/* Check the wait node status */ os_mutex_lock(&node->shared_mem_lock);
os_mutex_lock(&wait_info->wait_list_lock); os_mutex_lock(&wait_info->wait_list_lock);
check_ret = is_wait_node_exists(wait_info->wait_list, wait_node); check_ret = is_wait_node_exists(wait_info->wait_list, wait_node);
bh_assert(check_ret); bh_assert(check_ret);
is_timeout = wait_node->status == S_WAITING ? true : false; /* Remove wait node */
bh_list_remove(wait_info->wait_list, wait_node); bh_list_remove(wait_info->wait_list, wait_node);
os_mutex_destroy(&wait_node->wait_lock); os_mutex_destroy(&wait_node->wait_lock);
os_cond_destroy(&wait_node->wait_cond); os_cond_destroy(&wait_node->wait_cond);
wasm_runtime_free(wait_node); wasm_runtime_free(wait_node);
os_mutex_unlock(&wait_info->wait_list_lock);
os_mutex_lock(&node->shared_mem_lock); /* Release wait info if no wait nodes attached */
release_wait_info(wait_map, wait_info, address); removed_from_map = map_remove_wait_info(wait_map, wait_info, address);
os_mutex_unlock(&wait_info->wait_list_lock);
if (removed_from_map)
destroy_wait_info(wait_info);
os_mutex_unlock(&node->shared_mem_lock); os_mutex_unlock(&node->shared_mem_lock);
(void)check_ret; (void)check_ret;
@ -518,16 +524,20 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
} }
wait_info = acquire_wait_info(address, false); wait_info = acquire_wait_info(address, false);
if (node)
os_mutex_unlock(&node->shared_mem_lock);
/* Nobody wait on this address */ /* Nobody wait on this address */
if (!wait_info) if (!wait_info) {
if (node)
os_mutex_unlock(&node->shared_mem_lock);
return 0; return 0;
}
os_mutex_lock(&wait_info->wait_list_lock); os_mutex_lock(&wait_info->wait_list_lock);
notify_result = notify_wait_list(wait_info->wait_list, count); notify_result = notify_wait_list(wait_info->wait_list, count);
os_mutex_unlock(&wait_info->wait_list_lock); os_mutex_unlock(&wait_info->wait_list_lock);
if (node)
os_mutex_unlock(&node->shared_mem_lock);
return notify_result; return notify_result;
} }

View File

@ -8,6 +8,7 @@
#include "wasm_runtime.h" #include "wasm_runtime.h"
#include "wasm_opcode.h" #include "wasm_opcode.h"
#include "wasm_loader.h" #include "wasm_loader.h"
#include "wasm_memory.h"
#include "../common/wasm_exec_env.h" #include "../common/wasm_exec_env.h"
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
#include "../common/wasm_shared_memory.h" #include "../common/wasm_shared_memory.h"
@ -954,7 +955,7 @@ fast_jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
WASMFunctionInstance *cur_func = module_inst->e->functions + func_idx; WASMFunctionInstance *cur_func = module_inst->e->functions + func_idx;
wasm_interp_call_func_native(module_inst, exec_env, cur_func, prev_frame); wasm_interp_call_func_native(module_inst, exec_env, cur_func, prev_frame);
return wasm_get_exception(module_inst) ? false : true; return wasm_copy_exception(module_inst, NULL) ? false : true;
} }
#endif #endif
@ -1023,7 +1024,7 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
/* transfer exception if it is thrown */ /* transfer exception if it is thrown */
if (wasm_get_exception(sub_module_inst)) { if (wasm_copy_exception(sub_module_inst, NULL)) {
bh_memcpy_s(module_inst->cur_exception, bh_memcpy_s(module_inst->cur_exception,
sizeof(module_inst->cur_exception), sizeof(module_inst->cur_exception),
sub_module_inst->cur_exception, sub_module_inst->cur_exception,
@ -1126,14 +1127,22 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMFunctionInstance *cur_func, WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
#else
void *node = NULL;
#endif
WASMMemoryInstance *memory = wasm_get_default_memory(module); WASMMemoryInstance *memory = wasm_get_default_memory(module);
uint8 *global_data = module->global_data; uint8 *global_data = module->global_data;
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \ #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_BULK_MEMORY != 0
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; uint32 num_bytes_per_page =
memory ? wasm_get_num_bytes_per_page(memory, node) : 0;
uint32 linear_mem_size = uint32 linear_mem_size =
memory ? num_bytes_per_page * memory->cur_page_count : 0; memory ? wasm_get_linear_memory_size(memory, node) : 0;
#endif #endif
WASMType **wasm_types = module->module->types; WASMType **wasm_types = module->module->types;
WASMGlobalInstance *globals = module->e->globals, *global; WASMGlobalInstance *globals = module->e->globals, *global;
@ -1157,11 +1166,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 cache_index, type_index, param_cell_num, cell_num; uint32 cache_index, type_index, param_cell_num, cell_num;
uint8 value_type; uint8 value_type;
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0 #if WASM_ENABLE_DEBUG_INTERP != 0
uint8 *frame_ip_orig = NULL; uint8 *frame_ip_orig = NULL;
WASMDebugInstance *debug_instance = wasm_exec_env_get_instance(exec_env); WASMDebugInstance *debug_instance = wasm_exec_env_get_instance(exec_env);
@ -3859,7 +3863,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (memory) if (memory)
linear_mem_size = num_bytes_per_page * memory->cur_page_count; linear_mem_size = num_bytes_per_page * memory->cur_page_count;
#endif #endif
if (wasm_get_exception(module)) if (wasm_copy_exception(module, NULL))
goto got_exception; goto got_exception;
} }
else { else {
@ -4002,7 +4006,7 @@ fast_jit_call_func_bytecode(WASMModuleInstance *module_inst,
module_inst->fast_jit_func_ptrs[func_idx_non_import]); module_inst->fast_jit_func_ptrs[func_idx_non_import]);
bh_assert(action == JIT_INTERP_ACTION_NORMAL bh_assert(action == JIT_INTERP_ACTION_NORMAL
|| (action == JIT_INTERP_ACTION_THROWN || (action == JIT_INTERP_ACTION_THROWN
&& wasm_runtime_get_exception(exec_env->module_inst))); && wasm_runtime_copy_exception(exec_env->module_inst, NULL)));
/* Get the return values form info.out.ret */ /* Get the return values form info.out.ret */
if (func_type->result_count) { if (func_type->result_count) {
@ -4137,7 +4141,7 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
exec_env, module_inst->func_ptrs[func_idx], func_type, NULL, NULL, exec_env, module_inst->func_ptrs[func_idx], func_type, NULL, NULL,
argv, argc, argv); argv, argc, argv);
return ret && !wasm_get_exception(module_inst) ? true : false; return ret && !wasm_copy_exception(module_inst, NULL) ? true : false;
} }
} }
#endif /* end of WASM_ENABLE_JIT != 0 */ #endif /* end of WASM_ENABLE_JIT != 0 */
@ -4157,6 +4161,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num); unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);
unsigned i; unsigned i;
bool copy_argv_from_frame = true; bool copy_argv_from_frame = true;
char exception[EXCEPTION_BUF_LEN];
if (argc < function->param_cell_num) { if (argc < function->param_cell_num) {
char buf[128]; char buf[128];
@ -4267,7 +4272,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
} }
/* Output the return value to the caller */ /* Output the return value to the caller */
if (!wasm_get_exception(module_inst)) { if (!wasm_copy_exception(module_inst, NULL)) {
if (copy_argv_from_frame) { if (copy_argv_from_frame) {
for (i = 0; i < function->ret_cell_num; i++) { for (i = 0; i < function->ret_cell_num; i++) {
argv[i] = *(frame->sp + i - function->ret_cell_num); argv[i] = *(frame->sp + i - function->ret_cell_num);
@ -4280,7 +4285,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
wasm_interp_dump_call_stack(exec_env, true, NULL, 0); wasm_interp_dump_call_stack(exec_env, true, NULL, 0);
} }
#endif #endif
LOG_DEBUG("meet an exception %s", wasm_get_exception(module_inst)); wasm_copy_exception(module_inst, exception);
LOG_DEBUG("meet an exception %s", exception);
} }
wasm_exec_env_set_cur_frame(exec_env, prev_frame); wasm_exec_env_set_cur_frame(exec_env, prev_frame);

View File

@ -8,6 +8,7 @@
#include "wasm_runtime.h" #include "wasm_runtime.h"
#include "wasm_opcode.h" #include "wasm_opcode.h"
#include "wasm_loader.h" #include "wasm_loader.h"
#include "wasm_memory.h"
#include "../common/wasm_exec_env.h" #include "../common/wasm_exec_env.h"
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
#include "../common/wasm_shared_memory.h" #include "../common/wasm_shared_memory.h"
@ -1042,7 +1043,7 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
/* transfer exception if it is thrown */ /* transfer exception if it is thrown */
if (wasm_get_exception(sub_module_inst)) { if (wasm_copy_exception(sub_module_inst, NULL)) {
bh_memcpy_s(module_inst->cur_exception, bh_memcpy_s(module_inst->cur_exception,
sizeof(module_inst->cur_exception), sizeof(module_inst->cur_exception),
sub_module_inst->cur_exception, sub_module_inst->cur_exception,
@ -1154,13 +1155,22 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMFunctionInstance *cur_func, WASMFunctionInstance *cur_func,
WASMInterpFrame *prev_frame) WASMInterpFrame *prev_frame)
{ {
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
#else
void *node = NULL;
#endif
WASMMemoryInstance *memory = wasm_get_default_memory(module); WASMMemoryInstance *memory = wasm_get_default_memory(module);
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \ #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_BULK_MEMORY != 0
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; uint32 num_bytes_per_page =
memory ? wasm_get_num_bytes_per_page(memory, node) : 0;
uint32 linear_mem_size = uint32 linear_mem_size =
memory ? num_bytes_per_page * memory->cur_page_count : 0; memory ? wasm_get_linear_memory_size(memory, node) : 0;
#endif #endif
uint8 *global_data = module->global_data; uint8 *global_data = module->global_data;
WASMGlobalInstance *globals = module->e ? module->e->globals : NULL; WASMGlobalInstance *globals = module->e ? module->e->globals : NULL;
@ -1186,11 +1196,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 local_idx, local_offset, global_idx; uint32 local_idx, local_offset, global_idx;
uint8 opcode, local_type, *global_addr; uint8 opcode, local_type, *global_addr;
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
#endif
#if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_ENABLE_LABELS_AS_VALUES != 0
#define HANDLE_OPCODE(op) &&HANDLE_##op #define HANDLE_OPCODE(op) &&HANDLE_##op
DEFINE_GOTO_TABLE(const void *, handle_table); DEFINE_GOTO_TABLE(const void *, handle_table);
@ -3797,7 +3802,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (memory) if (memory)
linear_mem_size = num_bytes_per_page * memory->cur_page_count; linear_mem_size = num_bytes_per_page * memory->cur_page_count;
#endif #endif
if (wasm_get_exception(module)) if (wasm_copy_exception(module, NULL))
goto got_exception; goto got_exception;
} }
else { else {
@ -3908,6 +3913,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
/* This frame won't be used by JITed code, so only allocate interp /* This frame won't be used by JITed code, so only allocate interp
frame here. */ frame here. */
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num); unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);
char exception[EXCEPTION_BUF_LEN];
if (argc < function->param_cell_num) { if (argc < function->param_cell_num) {
char buf[128]; char buf[128];
@ -3973,7 +3979,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
} }
/* Output the return value to the caller */ /* Output the return value to the caller */
if (!wasm_get_exception(module_inst)) { if (!wasm_copy_exception(module_inst, NULL)) {
for (i = 0; i < function->ret_cell_num; i++) for (i = 0; i < function->ret_cell_num; i++)
argv[i] = *(frame->lp + i); argv[i] = *(frame->lp + i);
} }
@ -3983,7 +3989,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
wasm_interp_dump_call_stack(exec_env, true, NULL, 0); wasm_interp_dump_call_stack(exec_env, true, NULL, 0);
} }
#endif #endif
LOG_DEBUG("meet an exception %s", wasm_get_exception(module_inst)); wasm_copy_exception(module_inst, exception);
LOG_DEBUG("meet an exception %s", exception);
} }
wasm_exec_env_set_cur_frame(exec_env, prev_frame); wasm_exec_env_set_cur_frame(exec_env, prev_frame);

View File

@ -2243,6 +2243,8 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
#ifdef BH_PLATFORM_WINDOWS #ifdef BH_PLATFORM_WINDOWS
const char *exce; const char *exce;
int result; int result;
bool has_exception;
char exception[EXCEPTION_BUF_LEN];
#endif #endif
bool ret = true; bool ret = true;
@ -2275,14 +2277,14 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
#else #else
__try { __try {
wasm_interp_call_wasm(module_inst, exec_env, function, argc, argv); wasm_interp_call_wasm(module_inst, exec_env, function, argc, argv);
} __except (wasm_get_exception(module_inst) } __except (wasm_copy_exception(module_inst, NULL)
? EXCEPTION_EXECUTE_HANDLER ? EXCEPTION_EXECUTE_HANDLER
: EXCEPTION_CONTINUE_SEARCH) { : EXCEPTION_CONTINUE_SEARCH) {
/* exception was thrown in wasm_exception_handler */ /* exception was thrown in wasm_exception_handler */
ret = false; ret = false;
} }
if ((exce = wasm_get_exception(module_inst)) has_exception = wasm_copy_exception(module_inst, exception);
&& strstr(exce, "native stack overflow")) { if (has_exception && strstr(exception, "native stack overflow")) {
/* After a stack overflow, the stack was left /* After a stack overflow, the stack was left
in a damaged state, let the CRT repair it */ in a damaged state, let the CRT repair it */
result = _resetstkoflw(); result = _resetstkoflw();
@ -2336,7 +2338,7 @@ wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
wasm_exec_env_set_thread_info(exec_env); wasm_exec_env_set_thread_info(exec_env);
interp_call_wasm(module_inst, exec_env, function, argc, argv); interp_call_wasm(module_inst, exec_env, function, argc, argv);
return !wasm_get_exception(module_inst) ? true : false; return !wasm_copy_exception(module_inst, NULL);
} }
bool bool
@ -2509,6 +2511,12 @@ wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr)
return; return;
} }
#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
addr = memory->memory_data + ptr; addr = memory->memory_data + ptr;
if (memory->heap_handle && memory->heap_data <= addr if (memory->heap_handle && memory->heap_data <= addr
@ -2521,6 +2529,10 @@ wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr)
execute_free_function(module_inst, module_inst->e->free_function, execute_free_function(module_inst, module_inst->e->free_function,
ptr); ptr);
} }
#if WASM_ENABLE_SHARED_MEMORY != 0
if (node)
os_mutex_unlock(&node->shared_mem_lock);
#endif
} }
} }
@ -2633,7 +2645,7 @@ call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
interp_call_wasm(module_inst, exec_env, func_inst, argc, argv); interp_call_wasm(module_inst, exec_env, func_inst, argc, argv);
return !wasm_get_exception(module_inst) ? true : false; return !wasm_copy_exception(module_inst, NULL);
got_exception: got_exception:
return false; return false;

View File

@ -19,6 +19,8 @@
extern "C" { extern "C" {
#endif #endif
#define EXCEPTION_BUF_LEN 128
typedef struct WASMModuleInstance WASMModuleInstance; typedef struct WASMModuleInstance WASMModuleInstance;
typedef struct WASMFunctionInstance WASMFunctionInstance; typedef struct WASMFunctionInstance WASMFunctionInstance;
typedef struct WASMMemoryInstance WASMMemoryInstance; typedef struct WASMMemoryInstance WASMMemoryInstance;
@ -282,7 +284,7 @@ struct WASMModuleInstance {
DefPointer(WASMExportTabInstance *, export_tables); DefPointer(WASMExportTabInstance *, export_tables);
/* The exception buffer of wasm interpreter for current thread. */ /* The exception buffer of wasm interpreter for current thread. */
char cur_exception[128]; char cur_exception[EXCEPTION_BUF_LEN];
/* The WASM module or AOT module, for AOTModuleInstance, /* The WASM module or AOT module, for AOTModuleInstance,
it denotes `AOTModule *` */ it denotes `AOTModule *` */
@ -444,6 +446,15 @@ wasm_set_exception_with_id(WASMModuleInstance *module_inst, uint32 id);
const char * const char *
wasm_get_exception(WASMModuleInstance *module); wasm_get_exception(WASMModuleInstance *module);
/**
* @brief Copy exception in buffer passed as parameter. Thread-safe version of
* `wasm_get_exception()`
* @note Buffer size must be no smaller than EXCEPTION_BUF_LEN
* @return true if exception found
*/
bool
wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf);
uint32 uint32
wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size, wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
void **p_native_addr); void **p_native_addr);

View File

@ -16,6 +16,10 @@
#include "debug_engine.h" #include "debug_engine.h"
#endif #endif
#if WASM_ENABLE_SHARED_MEMORY != 0
#include "wasm_shared_memory.h"
#endif
typedef struct { typedef struct {
bh_list_link l; bh_list_link l;
void (*destroy_cb)(WASMCluster *); void (*destroy_cb)(WASMCluster *);
@ -826,15 +830,18 @@ clusters_have_exec_env(WASMExecEnv *exec_env)
WASMExecEnv *node; WASMExecEnv *node;
while (cluster) { while (cluster) {
os_mutex_lock(&cluster->lock);
node = bh_list_first_elem(&cluster->exec_env_list); node = bh_list_first_elem(&cluster->exec_env_list);
while (node) { while (node) {
if (node == exec_env) { if (node == exec_env) {
bh_assert(exec_env->cluster == cluster); bh_assert(exec_env->cluster == cluster);
os_mutex_unlock(&cluster->lock);
return true; return true;
} }
node = bh_list_elem_next(node); node = bh_list_elem_next(node);
} }
os_mutex_unlock(&cluster->lock);
cluster = bh_list_elem_next(cluster); cluster = bh_list_elem_next(cluster);
} }
@ -848,13 +855,11 @@ wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val)
korp_tid handle; korp_tid handle;
os_mutex_lock(&cluster_list_lock); os_mutex_lock(&cluster_list_lock);
os_mutex_lock(&exec_env->cluster->lock);
if (!clusters_have_exec_env(exec_env) || exec_env->thread_is_detached) { if (!clusters_have_exec_env(exec_env) || exec_env->thread_is_detached) {
/* Invalid thread, thread has exited or thread has been detached */ /* Invalid thread, thread has exited or thread has been detached */
if (ret_val) if (ret_val)
*ret_val = NULL; *ret_val = NULL;
os_mutex_unlock(&exec_env->cluster->lock);
os_mutex_unlock(&cluster_list_lock); os_mutex_unlock(&cluster_list_lock);
return 0; return 0;
} }
@ -864,7 +869,6 @@ wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val)
handle = exec_env->handle; handle = exec_env->handle;
os_mutex_unlock(&exec_env->wait_lock); os_mutex_unlock(&exec_env->wait_lock);
os_mutex_unlock(&exec_env->cluster->lock);
os_mutex_unlock(&cluster_list_lock); os_mutex_unlock(&cluster_list_lock);
return os_thread_join(handle, ret_val); return os_thread_join(handle, ret_val);
@ -1146,12 +1150,22 @@ set_exception_visitor(void *node, void *user_data)
(WASMModuleInstance *)get_module_inst(curr_exec_env); (WASMModuleInstance *)get_module_inst(curr_exec_env);
/* Only spread non "wasi proc exit" exception */ /* Only spread non "wasi proc exit" exception */
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *shared_mem_node = wasm_module_get_shared_memory(
(WASMModuleCommon *)curr_wasm_inst->module);
if (shared_mem_node)
os_mutex_lock(&shared_mem_node->shared_mem_lock);
#endif
if (!strstr(wasm_inst->cur_exception, "wasi proc exit")) { if (!strstr(wasm_inst->cur_exception, "wasi proc exit")) {
bh_memcpy_s(curr_wasm_inst->cur_exception, bh_memcpy_s(curr_wasm_inst->cur_exception,
sizeof(curr_wasm_inst->cur_exception), sizeof(curr_wasm_inst->cur_exception),
wasm_inst->cur_exception, wasm_inst->cur_exception,
sizeof(wasm_inst->cur_exception)); sizeof(wasm_inst->cur_exception));
} }
#if WASM_ENABLE_SHARED_MEMORY != 0
if (shared_mem_node)
os_mutex_unlock(&shared_mem_node->shared_mem_lock);
#endif
/* Terminate the thread so it can exit from dead loops */ /* Terminate the thread so it can exit from dead loops */
set_thread_cancel_flags(curr_exec_env); set_thread_cancel_flags(curr_exec_env);
@ -1168,7 +1182,17 @@ clear_exception_visitor(void *node, void *user_data)
WASMModuleInstance *curr_wasm_inst = WASMModuleInstance *curr_wasm_inst =
(WASMModuleInstance *)get_module_inst(curr_exec_env); (WASMModuleInstance *)get_module_inst(curr_exec_env);
#if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *shared_mem_node = wasm_module_get_shared_memory(
(WASMModuleCommon *)curr_wasm_inst->module);
if (shared_mem_node)
os_mutex_lock(&shared_mem_node->shared_mem_lock);
#endif
curr_wasm_inst->cur_exception[0] = '\0'; curr_wasm_inst->cur_exception[0] = '\0';
#if WASM_ENABLE_SHARED_MEMORY != 0
if (shared_mem_node)
os_mutex_unlock(&shared_mem_node->shared_mem_lock);
#endif
} }
} }