mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-03-12 00:45:28 +00:00
Add an API to terminate instance (#2538)
Add API wasm_runtime_terminate to terminate a module instance by setting "terminated by user" exception to the module instance. And update the product-mini of posix platforms. Note: this doesn't work for some situations like blocking system calls.
This commit is contained in:
parent
f128150d43
commit
a6fda9b7ab
|
@ -2342,8 +2342,8 @@ wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst_comm)
|
||||||
return module_inst->exec_env_singleton;
|
return module_inst->exec_env_singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
wasm_set_exception_local(WASMModuleInstance *module_inst, const char *exception)
|
||||||
{
|
{
|
||||||
exception_lock(module_inst);
|
exception_lock(module_inst);
|
||||||
if (exception) {
|
if (exception) {
|
||||||
|
@ -2354,13 +2354,22 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||||
module_inst->cur_exception[0] = '\0';
|
module_inst->cur_exception[0] = '\0';
|
||||||
}
|
}
|
||||||
exception_unlock(module_inst);
|
exception_unlock(module_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||||
|
{
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
WASMExecEnv *exec_env =
|
WASMExecEnv *exec_env =
|
||||||
wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst);
|
wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst);
|
||||||
if (exec_env) {
|
if (exec_env) {
|
||||||
wasm_cluster_spread_exception(exec_env, exception);
|
wasm_cluster_set_exception(exec_env, exception);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
wasm_set_exception_local(module_inst, exception);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
wasm_set_exception_local(module_inst, exception);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2468,6 +2477,18 @@ wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst_comm)
|
||||||
wasm_runtime_set_exception(module_inst_comm, NULL);
|
wasm_runtime_set_exception(module_inst_comm, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
void
|
||||||
|
wasm_runtime_terminate(WASMModuleInstanceCommon *module_inst_comm)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
wasm_set_exception(module_inst, "terminated by user");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_runtime_set_custom_data_internal(
|
wasm_runtime_set_custom_data_internal(
|
||||||
WASMModuleInstanceCommon *module_inst_comm, void *custom_data)
|
WASMModuleInstanceCommon *module_inst_comm, void *custom_data)
|
||||||
|
|
|
@ -675,6 +675,10 @@ wasm_runtime_get_exception(WASMModuleInstanceCommon *module);
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst);
|
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst);
|
||||||
|
|
||||||
|
/* See wasm_export.h for description */
|
||||||
|
WASM_RUNTIME_API_EXTERN void
|
||||||
|
wasm_runtime_terminate(WASMModuleInstanceCommon *module);
|
||||||
|
|
||||||
/* Internal API */
|
/* Internal API */
|
||||||
void
|
void
|
||||||
wasm_runtime_set_custom_data_internal(WASMModuleInstanceCommon *module_inst,
|
wasm_runtime_set_custom_data_internal(WASMModuleInstanceCommon *module_inst,
|
||||||
|
|
|
@ -894,6 +894,27 @@ wasm_runtime_set_exception(wasm_module_inst_t module_inst,
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_clear_exception(wasm_module_inst_t module_inst);
|
wasm_runtime_clear_exception(wasm_module_inst_t module_inst);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminate the WASM module instance.
|
||||||
|
*
|
||||||
|
* This function causes the module instance fail as if it raised a trap.
|
||||||
|
*
|
||||||
|
* This is intended to be used in situations like:
|
||||||
|
*
|
||||||
|
* - A thread is executing the WASM module instance
|
||||||
|
* (eg. it's in the middle of `wasm_application_execute_main`)
|
||||||
|
*
|
||||||
|
* - Another thread has a copy of `wasm_module_inst_t` of
|
||||||
|
* the module instance and wants to terminate it asynchronously.
|
||||||
|
*
|
||||||
|
* This function is provided only when WAMR is built with threading enabled.
|
||||||
|
* (`WASM_ENABLE_THREAD_MGR=1`)
|
||||||
|
*
|
||||||
|
* @param module_inst the WASM module instance
|
||||||
|
*/
|
||||||
|
WASM_RUNTIME_API_EXTERN void
|
||||||
|
wasm_runtime_terminate(wasm_module_inst_t module_inst);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set custom data to WASM module instance.
|
* Set custom data to WASM module instance.
|
||||||
* Note:
|
* Note:
|
||||||
|
|
|
@ -1061,6 +1061,15 @@ set_thread_cancel_flags(WASMExecEnv *exec_env)
|
||||||
os_mutex_unlock(&exec_env->wait_lock);
|
os_mutex_unlock(&exec_env->wait_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_thread_cancel_flags(WASMExecEnv *exec_env)
|
||||||
|
{
|
||||||
|
os_mutex_lock(&exec_env->wait_lock);
|
||||||
|
WASM_SUSPEND_FLAGS_FETCH_AND(exec_env->suspend_flags,
|
||||||
|
~WASM_SUSPEND_FLAG_TERMINATE);
|
||||||
|
os_mutex_unlock(&exec_env->wait_lock);
|
||||||
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
wasm_cluster_cancel_thread(WASMExecEnv *exec_env)
|
wasm_cluster_cancel_thread(WASMExecEnv *exec_env)
|
||||||
{
|
{
|
||||||
|
@ -1266,18 +1275,21 @@ set_exception_visitor(void *node, void *user_data)
|
||||||
if (data->exception != NULL) {
|
if (data->exception != NULL) {
|
||||||
set_thread_cancel_flags(exec_env);
|
set_thread_cancel_flags(exec_env);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
clear_thread_cancel_flags(exec_env);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_cluster_spread_exception(WASMExecEnv *exec_env, const char *exception)
|
wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception)
|
||||||
{
|
{
|
||||||
const bool has_exception = exception != NULL;
|
const bool has_exception = exception != NULL;
|
||||||
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
||||||
bh_assert(cluster);
|
bh_assert(cluster);
|
||||||
|
|
||||||
struct spread_exception_data data;
|
struct spread_exception_data data;
|
||||||
data.skip = exec_env;
|
data.skip = NULL;
|
||||||
data.exception = exception;
|
data.exception = exception;
|
||||||
|
|
||||||
os_mutex_lock(&cluster->lock);
|
os_mutex_lock(&cluster->lock);
|
||||||
|
|
|
@ -139,7 +139,7 @@ WASMExecEnv *
|
||||||
wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst);
|
wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst);
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_cluster_spread_exception(WASMExecEnv *exec_env, const char *exception);
|
wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception);
|
||||||
|
|
||||||
WASMExecEnv *
|
WASMExecEnv *
|
||||||
wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env);
|
wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env);
|
||||||
|
|
|
@ -97,6 +97,11 @@ print_help()
|
||||||
#if WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0
|
#if WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0
|
||||||
printf(" --max-threads=n Set maximum thread number per cluster, default is 4\n");
|
printf(" --max-threads=n Set maximum thread number per cluster, default is 4\n");
|
||||||
#endif
|
#endif
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
printf(" --timeout=ms Set the maximum execution time in ms.\n");
|
||||||
|
printf(" If it expires, the runtime aborts the execution\n");
|
||||||
|
printf(" with a trap.\n");
|
||||||
|
#endif
|
||||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||||
printf(" -g=ip:port Set the debug sever address, default is debug disabled\n");
|
printf(" -g=ip:port Set the debug sever address, default is debug disabled\n");
|
||||||
printf(" if port is 0, then a random port will be used\n");
|
printf(" if port is 0, then a random port will be used\n");
|
||||||
|
@ -488,6 +493,37 @@ dump_pgo_prof_data(wasm_module_inst_t module_inst, const char *path)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
struct timeout_arg {
|
||||||
|
uint32 timeout_ms;
|
||||||
|
wasm_module_inst_t inst;
|
||||||
|
_Atomic bool cancel;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *
|
||||||
|
timeout_thread(void *vp)
|
||||||
|
{
|
||||||
|
const struct timeout_arg *arg = vp;
|
||||||
|
uint32 left = arg->timeout_ms;
|
||||||
|
while (!arg->cancel) {
|
||||||
|
uint32 ms;
|
||||||
|
if (left >= 100) {
|
||||||
|
ms = 100;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ms = left;
|
||||||
|
}
|
||||||
|
os_usleep((uint64)ms * 1000);
|
||||||
|
left -= ms;
|
||||||
|
if (left == 0) {
|
||||||
|
wasm_runtime_terminate(arg->inst);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -546,6 +582,9 @@ main(int argc, char *argv[])
|
||||||
#if WASM_ENABLE_STATIC_PGO != 0
|
#if WASM_ENABLE_STATIC_PGO != 0
|
||||||
const char *gen_prof_file = NULL;
|
const char *gen_prof_file = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
int timeout_ms = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Process options. */
|
/* Process options. */
|
||||||
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
|
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
|
||||||
|
@ -742,6 +781,13 @@ main(int argc, char *argv[])
|
||||||
wasm_runtime_set_max_thread_num(atoi(argv[0] + 14));
|
wasm_runtime_set_max_thread_num(atoi(argv[0] + 14));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
else if (!strncmp(argv[0], "--timeout=", 10)) {
|
||||||
|
if (argv[0][10] == '\0')
|
||||||
|
return print_help();
|
||||||
|
timeout_ms = atoi(argv[0] + 10);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||||
else if (!strncmp(argv[0], "-g=", 3)) {
|
else if (!strncmp(argv[0], "-g=", 3)) {
|
||||||
char *port_str = strchr(argv[0] + 3, ':');
|
char *port_str = strchr(argv[0] + 3, ':');
|
||||||
|
@ -902,6 +948,22 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
struct timeout_arg timeout_arg;
|
||||||
|
korp_tid timeout_tid;
|
||||||
|
if (timeout_ms >= 0) {
|
||||||
|
timeout_arg.timeout_ms = timeout_ms;
|
||||||
|
timeout_arg.inst = wasm_module_inst;
|
||||||
|
timeout_arg.cancel = false;
|
||||||
|
ret = os_thread_create(&timeout_tid, timeout_thread, &timeout_arg,
|
||||||
|
APP_THREAD_STACK_SIZE_DEFAULT);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("Failed to start timeout\n");
|
||||||
|
goto fail5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (is_repl_mode) {
|
if (is_repl_mode) {
|
||||||
app_instance_repl(wasm_module_inst);
|
app_instance_repl(wasm_module_inst);
|
||||||
|
@ -932,6 +994,16 @@ main(int argc, char *argv[])
|
||||||
dump_pgo_prof_data(wasm_module_inst, gen_prof_file);
|
dump_pgo_prof_data(wasm_module_inst, gen_prof_file);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
if (timeout_ms >= 0) {
|
||||||
|
timeout_arg.cancel = true;
|
||||||
|
os_thread_join(timeout_tid, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
fail5:
|
||||||
|
#endif
|
||||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||||
fail4:
|
fail4:
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user