mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-08 20:56:13 +00:00
Fix terminating stale threads on trap/proc_exit (#1929)
This is to terminate suspended threads in case an atomic wait occurs with a huge or indefinite (-1) timeout, followed by a proc exit or trap.
This commit is contained in:
parent
8ed6687696
commit
f3c1ad4864
|
@ -2317,6 +2317,12 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||||
if (exec_env) {
|
if (exec_env) {
|
||||||
wasm_cluster_spread_exception(exec_env, exception ? false : true);
|
wasm_cluster_spread_exception(exec_env, exception ? false : true);
|
||||||
}
|
}
|
||||||
|
#if WASM_ENABLE_SHARED_MEMORY
|
||||||
|
if (exception) {
|
||||||
|
notify_stale_threads_on_exception(
|
||||||
|
(WASMModuleInstanceCommon *)module_inst);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
(void)exec_env;
|
(void)exec_env;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,6 +30,11 @@ typedef struct AtomicWaitNode {
|
||||||
korp_cond wait_cond;
|
korp_cond wait_cond;
|
||||||
} AtomicWaitNode;
|
} AtomicWaitNode;
|
||||||
|
|
||||||
|
typedef struct AtomicWaitAddressArgs {
|
||||||
|
uint32 index;
|
||||||
|
void **addr;
|
||||||
|
} AtomicWaitAddressArgs;
|
||||||
|
|
||||||
/* Atomic wait map */
|
/* Atomic wait map */
|
||||||
static HashMap *wait_map;
|
static HashMap *wait_map;
|
||||||
|
|
||||||
|
@ -87,6 +92,53 @@ search_module(WASMModuleCommon *module)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wait_map_address_count_callback(void *key, void *value,
|
||||||
|
void *p_total_elem_count)
|
||||||
|
{
|
||||||
|
*(uint32 *)p_total_elem_count = *(uint32 *)p_total_elem_count + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_list_of_waiter_addresses(void *key, void *value, void *user_data)
|
||||||
|
{
|
||||||
|
AtomicWaitAddressArgs *data = (AtomicWaitAddressArgs *)user_data;
|
||||||
|
data->addr[data->index++] = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
notify_stale_threads_on_exception(WASMModuleInstanceCommon *module_inst)
|
||||||
|
{
|
||||||
|
AtomicWaitAddressArgs args = { 0 };
|
||||||
|
uint32 i = 0, total_elem_count = 0;
|
||||||
|
|
||||||
|
os_mutex_lock(&shared_memory_list_lock);
|
||||||
|
|
||||||
|
/* count number of addresses in wait_map */
|
||||||
|
bh_hash_map_traverse(wait_map, wait_map_address_count_callback,
|
||||||
|
(void *)&total_elem_count);
|
||||||
|
|
||||||
|
/* allocate memory */
|
||||||
|
if (!(args.addr = wasm_runtime_malloc(sizeof(void *) * total_elem_count))) {
|
||||||
|
LOG_ERROR(
|
||||||
|
"failed to allocate memory for list of atomic wait addresses");
|
||||||
|
os_mutex_unlock(&shared_memory_list_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set values in list of addresses */
|
||||||
|
bh_hash_map_traverse(wait_map, create_list_of_waiter_addresses, &args);
|
||||||
|
os_mutex_unlock(&shared_memory_list_lock);
|
||||||
|
|
||||||
|
/* notify */
|
||||||
|
for (i = 0; i < args.index; i++) {
|
||||||
|
wasm_runtime_atomic_notify(module_inst, args.addr[i], UINT32_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free memory allocated to args data */
|
||||||
|
wasm_runtime_free(args.addr);
|
||||||
|
}
|
||||||
|
|
||||||
WASMSharedMemNode *
|
WASMSharedMemNode *
|
||||||
wasm_module_get_shared_memory(WASMModuleCommon *module)
|
wasm_module_get_shared_memory(WASMModuleCommon *module)
|
||||||
{
|
{
|
||||||
|
@ -322,6 +374,10 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||||
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)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Currently we have only one memory instance */
|
/* Currently we have only one memory instance */
|
||||||
if (!module_inst->memories[0]->is_shared) {
|
if (!module_inst->memories[0]->is_shared) {
|
||||||
wasm_runtime_set_exception(module, "expected shared memory");
|
wasm_runtime_set_exception(module, "expected shared memory");
|
||||||
|
|
|
@ -37,6 +37,9 @@ wasm_shared_memory_init();
|
||||||
void
|
void
|
||||||
wasm_shared_memory_destroy();
|
wasm_shared_memory_destroy();
|
||||||
|
|
||||||
|
void
|
||||||
|
notify_stale_threads_on_exception(WASMModuleInstanceCommon *module);
|
||||||
|
|
||||||
WASMSharedMemNode *
|
WASMSharedMemNode *
|
||||||
wasm_module_get_shared_memory(WASMModuleCommon *module);
|
wasm_module_get_shared_memory(WASMModuleCommon *module);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user