diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 136e9765..59411823 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -10,6 +10,9 @@ #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" #endif +#if WASM_ENABLE_THREAD_MGR != 0 +#include "../libraries/thread-mgr/thread_manager.h" +#endif static void set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) @@ -1319,17 +1322,33 @@ aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env; bool ret; - if (!(exec_env = wasm_exec_env_create((WASMModuleInstanceCommon*)module_inst, - module_inst->default_wasm_stack_size))) { - aot_set_exception(module_inst, "allocate memory failed"); - return false; - } +#if WASM_ENABLE_THREAD_MGR != 0 + WASMExecEnv *existing_exec_env = NULL; - /* set thread handle and stack boundary */ - wasm_exec_env_set_thread_info(exec_env); + if (!(existing_exec_env = exec_env = + wasm_clusters_search_exec_env( + (WASMModuleInstanceCommon*)module_inst))) { +#endif + if (!(exec_env = wasm_exec_env_create((WASMModuleInstanceCommon*)module_inst, + module_inst->default_wasm_stack_size))) { + aot_set_exception(module_inst, "allocate memory failed"); + return false; + } + + /* set thread handle and stack boundary */ + wasm_exec_env_set_thread_info(exec_env); +#if WASM_ENABLE_THREAD_MGR != 0 + } +#endif ret = aot_call_function(exec_env, func, argc, argv); - wasm_exec_env_destroy(exec_env); + +#if WASM_ENABLE_THREAD_MGR != 0 + /* don't destroy the exec_env if it's searched from the cluster */ + if (!existing_exec_env) +#endif + wasm_exec_env_destroy(exec_env); + return ret; } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index a17bd903..c742553c 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -13,6 +13,9 @@ #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" #endif +#if WASM_ENABLE_THREAD_MGR != 0 +#include "../libraries/thread-mgr/thread_manager.h" +#endif static void set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) @@ -1593,18 +1596,34 @@ wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env; bool ret; - if (!(exec_env = wasm_exec_env_create( - (WASMModuleInstanceCommon*)module_inst, - module_inst->default_wasm_stack_size))) { - wasm_set_exception(module_inst, "allocate memory failed"); - return false; - } +#if WASM_ENABLE_THREAD_MGR != 0 + WASMExecEnv *existing_exec_env = NULL; - /* set thread handle and stack boundary */ - wasm_exec_env_set_thread_info(exec_env); + if (!(existing_exec_env = exec_env = + wasm_clusters_search_exec_env( + (WASMModuleInstanceCommon*)module_inst))) { +#endif + if (!(exec_env = wasm_exec_env_create( + (WASMModuleInstanceCommon*)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; + } + + /* set thread handle and stack boundary */ + wasm_exec_env_set_thread_info(exec_env); +#if WASM_ENABLE_THREAD_MGR != 0 + } +#endif ret = wasm_call_function(exec_env, func, argc, argv); - wasm_exec_env_destroy(exec_env); + +#if WASM_ENABLE_THREAD_MGR != 0 + /* don't destroy the exec_env if it's searched from the cluster */ + if (!existing_exec_env) +#endif + wasm_exec_env_destroy(exec_env); + return ret; } diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 6f2dcbae..afcc170c 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -281,6 +281,49 @@ wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env) return ret; } +static WASMExecEnv * +wasm_cluster_search_exec_env(WASMCluster *cluster, + WASMModuleInstanceCommon *module_inst) +{ + WASMExecEnv *node = NULL; + + os_mutex_lock(&cluster->lock); + node = bh_list_first_elem(&cluster->exec_env_list); + while (node) { + if (node->module_inst == module_inst) { + os_mutex_unlock(&cluster->lock); + return node; + } + node = bh_list_elem_next(node); + } + + os_mutex_unlock(&cluster->lock); + return NULL; +} + +/* search the global cluster list to find if the given + module instance have a corresponding exec_env */ +WASMExecEnv * +wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst) +{ + WASMCluster *cluster = NULL; + WASMExecEnv *exec_env = NULL; + + os_mutex_lock(&cluster_list_lock); + cluster = bh_list_first_elem(cluster_list); + while (cluster) { + exec_env = wasm_cluster_search_exec_env(cluster, module_inst); + if (exec_env) { + os_mutex_unlock(&cluster_list_lock); + return exec_env; + } + cluster = bh_list_elem_next(cluster); + } + + os_mutex_unlock(&cluster_list_lock); + return NULL; +} + WASMExecEnv * wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env) { diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.h b/core/iwasm/libraries/thread-mgr/thread_manager.h index eb5550a2..c43d0e64 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.h +++ b/core/iwasm/libraries/thread-mgr/thread_manager.h @@ -106,6 +106,9 @@ wasm_cluster_add_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env); bool wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env); +WASMExecEnv * +wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst); + void wasm_cluster_spread_exception(WASMExecEnv *exec_env);