diff --git a/core/iwasm/common/wasm_application.c b/core/iwasm/common/wasm_application.c index ec3116c9..9155625d 100644 --- a/core/iwasm/common/wasm_application.c +++ b/core/iwasm/common/wasm_application.c @@ -10,6 +10,9 @@ #if WASM_ENABLE_AOT != 0 #include "../aot/aot_runtime.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) @@ -76,9 +79,8 @@ check_main_func_type(const WASMType *type) return true; } -bool -wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, - char *argv[]) +static bool +execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[]) { WASMFunctionInstanceCommon *func; WASMType *func_type = NULL; @@ -203,6 +205,28 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, return ret; } +bool +wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, + char *argv[]) +{ + bool ret; +#if WASM_ENABLE_THREAD_MGR != 0 + WASMCluster *cluster; + WASMExecEnv *exec_env; +#endif + + ret = execute_main(module_inst, argc, argv); + +#if WASM_ENABLE_THREAD_MGR != 0 + exec_env = wasm_runtime_get_exec_env_singleton(module_inst); + if (exec_env && (cluster = wasm_exec_env_get_cluster(exec_env))) { + wasm_cluster_wait_for_all_except_self(cluster, exec_env); + } +#endif + + return (ret && !wasm_runtime_get_exception(module_inst)) ? true : false; +} + #if WASM_ENABLE_MULTI_MODULE != 0 static WASMModuleInstance * get_sub_module_inst(const WASMModuleInstance *parent_module_inst, @@ -351,9 +375,9 @@ union ieee754_double { } ieee; }; -bool -wasm_application_execute_func(WASMModuleInstanceCommon *module_inst, - const char *name, int32 argc, char *argv[]) +static bool +execute_func(WASMModuleInstanceCommon *module_inst, const char *name, + int32 argc, char *argv[]) { WASMFunctionInstanceCommon *target_func; WASMModuleInstanceCommon *target_inst; @@ -689,3 +713,25 @@ fail: os_printf("%s\n", exception); return false; } + +bool +wasm_application_execute_func(WASMModuleInstanceCommon *module_inst, + const char *name, int32 argc, char *argv[]) +{ + bool ret; +#if WASM_ENABLE_THREAD_MGR != 0 + WASMCluster *cluster; + WASMExecEnv *exec_env; +#endif + + ret = execute_func(module_inst, name, argc, argv); + +#if WASM_ENABLE_THREAD_MGR != 0 + exec_env = wasm_runtime_get_exec_env_singleton(module_inst); + if (exec_env && (cluster = wasm_exec_env_get_cluster(exec_env))) { + wasm_cluster_wait_for_all_except_self(cluster, exec_env); + } +#endif + + return (ret && !wasm_runtime_get_exception(module_inst)) ? true : false; +} diff --git a/core/iwasm/common/wasm_exec_env.h b/core/iwasm/common/wasm_exec_env.h index f57780f3..f7e348d8 100644 --- a/core/iwasm/common/wasm_exec_env.h +++ b/core/iwasm/common/wasm_exec_env.h @@ -100,6 +100,9 @@ typedef struct WASMExecEnv { korp_cond wait_cond; /* the count of threads which are joining current thread */ uint32 wait_count; + + /* whether current thread is detached */ + bool thread_is_detached; #endif #if WASM_ENABLE_DEBUG_INTERP != 0 diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 768e0d7d..39726ac8 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -681,8 +681,8 @@ wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val) korp_tid handle; os_mutex_lock(&cluster_list_lock); - if (!clusters_have_exec_env(exec_env)) { - /* Invalid thread or the thread has exited */ + if (!clusters_have_exec_env(exec_env) || exec_env->thread_is_detached) { + /* Invalid thread, thread has exited or thread has been detached */ if (ret_val) *ret_val = NULL; os_mutex_unlock(&cluster_list_lock); @@ -710,6 +710,7 @@ wasm_cluster_detach_thread(WASMExecEnv *exec_env) joining it, otherwise let the system resources for the thread be released after joining */ ret = os_thread_detach(exec_env->handle); + exec_env->thread_is_detached = true; } os_mutex_unlock(&cluster_list_lock); return ret; @@ -802,6 +803,33 @@ wasm_cluster_terminate_all_except_self(WASMCluster *cluster, (void *)exec_env); } +static void +wait_for_thread_visitor(void *node, void *user_data) +{ + WASMExecEnv *curr_exec_env = (WASMExecEnv *)node; + WASMExecEnv *exec_env = (WASMExecEnv *)user_data; + korp_tid handle; + + if (curr_exec_env == exec_env) + return; + + wasm_cluster_join_thread(curr_exec_env, NULL); +} + +void +wams_cluster_wait_for_all(WASMCluster *cluster) +{ + traverse_list(&cluster->exec_env_list, wait_for_thread_visitor, NULL); +} + +void +wasm_cluster_wait_for_all_except_self(WASMCluster *cluster, + WASMExecEnv *exec_env) +{ + traverse_list(&cluster->exec_env_list, wait_for_thread_visitor, + (void *)exec_env); +} + bool wasm_cluster_register_destroy_callback(void (*callback)(WASMCluster *)) { diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.h b/core/iwasm/libraries/thread-mgr/thread_manager.h index 2d4962a2..18185105 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.h +++ b/core/iwasm/libraries/thread-mgr/thread_manager.h @@ -106,6 +106,13 @@ void wasm_cluster_terminate_all_except_self(WASMCluster *cluster, WASMExecEnv *exec_env); +void +wams_cluster_wait_for_all(WASMCluster *cluster); + +void +wasm_cluster_wait_for_all_except_self(WASMCluster *cluster, + WASMExecEnv *exec_env); + bool wasm_cluster_add_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env); @@ -148,8 +155,6 @@ typedef struct WASMCurrentEnvStatus { uint64 signal_flag : 32; uint64 step_count : 16; uint64 running_status : 16; - korp_mutex wait_lock; - korp_cond wait_cond; } WASMCurrentEnvStatus; WASMCurrentEnvStatus *