mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-11 12:11:14 +00:00
Implement threads suspension/resume (#2320)
Refer to https://github.com/bytecodealliance/wasm-micro-runtime/issues/2319
This commit is contained in:
parent
a837563840
commit
43bcf94265
|
@ -49,17 +49,12 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
|
|||
|
||||
if (os_cond_init(&exec_env->wait_cond) != 0)
|
||||
goto fail3;
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
if (!(exec_env->current_status = wasm_cluster_create_exenv_status()))
|
||||
goto fail4;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
if (!(exec_env->exce_check_guard_page =
|
||||
os_mmap(NULL, os_getpagesize(), MMAP_PROT_NONE, MMAP_MAP_NONE)))
|
||||
goto fail5;
|
||||
goto fail4;
|
||||
#endif
|
||||
|
||||
exec_env->module_inst = module_inst;
|
||||
|
@ -83,16 +78,10 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
|
|||
return exec_env;
|
||||
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
fail5:
|
||||
#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
|
||||
wasm_cluster_destroy_exenv_status(exec_env->current_status);
|
||||
#endif
|
||||
fail4:
|
||||
#endif
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
fail4:
|
||||
os_cond_destroy(&exec_env->wait_cond);
|
||||
#endif
|
||||
fail3:
|
||||
os_mutex_destroy(&exec_env->wait_lock);
|
||||
fail2:
|
||||
|
@ -114,9 +103,6 @@ wasm_exec_env_destroy_internal(WASMExecEnv *exec_env)
|
|||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
os_mutex_destroy(&exec_env->wait_lock);
|
||||
os_cond_destroy(&exec_env->wait_cond);
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
wasm_cluster_destroy_exenv_status(exec_env->current_status);
|
||||
#endif
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
wasm_runtime_free(exec_env->argv_buf);
|
||||
|
|
|
@ -21,9 +21,6 @@ struct WASMInterpFrame;
|
|||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
typedef struct WASMCluster WASMCluster;
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
typedef struct WASMCurrentEnvStatus WASMCurrentEnvStatus;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
|
@ -33,6 +30,22 @@ typedef struct WASMJmpBuf {
|
|||
} WASMJmpBuf;
|
||||
#endif
|
||||
|
||||
typedef enum ThreadRunningState {
|
||||
WASM_THREAD_RUNNING = 0,
|
||||
WASM_THREAD_VMWAIT = 1,
|
||||
WASM_THREAD_SUSPENDED = 2,
|
||||
WASM_THREAD_EXITED = 3,
|
||||
|
||||
WASM_THREAD_STOP = 4,
|
||||
WASM_THREAD_STEP = 5,
|
||||
} ThreadRunningState;
|
||||
|
||||
typedef struct WASMThreadStatus {
|
||||
uint64 signal_flag : 32;
|
||||
uint64 step_count : 16;
|
||||
uint64 running_state : 16;
|
||||
} WASMThreadStatus;
|
||||
|
||||
/* Execution environment */
|
||||
typedef struct WASMExecEnv {
|
||||
/* Next thread's exec env of a WASM module instance. */
|
||||
|
@ -106,20 +119,25 @@ typedef struct WASMExecEnv {
|
|||
/* pointer to the cluster */
|
||||
WASMCluster *cluster;
|
||||
|
||||
/* used to support debugger */
|
||||
/* the lock for protecting wait_cond, wait_count and
|
||||
thread_is_detached of this exec_env */
|
||||
korp_mutex wait_lock;
|
||||
|
||||
/* conditional variable for this thread to wait */
|
||||
korp_cond wait_cond;
|
||||
|
||||
/* the count of threads which are joining current thread */
|
||||
uint32 wait_count;
|
||||
|
||||
/* the count of threads which are suspending current thread */
|
||||
uint32 suspend_count;
|
||||
|
||||
WASMThreadStatus current_status;
|
||||
|
||||
/* whether current thread is detached */
|
||||
bool thread_is_detached;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
WASMCurrentEnvStatus *current_status;
|
||||
#endif
|
||||
|
||||
/* attachment for native function */
|
||||
void *attachment;
|
||||
|
||||
|
|
|
@ -702,19 +702,9 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
|||
|
||||
return_func:
|
||||
if (!ret && enlarge_memory_error_cb) {
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode)
|
||||
exec_env =
|
||||
((WASMModuleInstanceExtra *)module->e)->common.cur_exec_env;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
exec_env =
|
||||
((AOTModuleInstanceExtra *)module->e)->common.cur_exec_env;
|
||||
#endif
|
||||
|
||||
WASMExecEnv *exec_env =
|
||||
wasm_runtime_get_cur_exec_env((WASMModuleInstanceCommon *)module);
|
||||
bh_assert(exec_env);
|
||||
enlarge_memory_error_cb(inc_page_count, total_size_old, 0,
|
||||
failure_reason,
|
||||
(WASMModuleInstanceCommon *)module, exec_env,
|
||||
|
@ -809,19 +799,9 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
|||
|
||||
return_func:
|
||||
if (!ret && enlarge_memory_error_cb) {
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode)
|
||||
exec_env =
|
||||
((WASMModuleInstanceExtra *)module->e)->common.cur_exec_env;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
exec_env =
|
||||
((AOTModuleInstanceExtra *)module->e)->common.cur_exec_env;
|
||||
#endif
|
||||
|
||||
WASMExecEnv *exec_env =
|
||||
wasm_runtime_get_cur_exec_env((WASMModuleInstanceCommon *)module);
|
||||
bh_assert(exec_env);
|
||||
enlarge_memory_error_cb(inc_page_count, total_size_old, 0,
|
||||
failure_reason,
|
||||
(WASMModuleInstanceCommon *)module, exec_env,
|
||||
|
|
|
@ -1195,6 +1195,18 @@ wasm_runtime_set_max_thread_num(uint32 num)
|
|||
{
|
||||
wasm_cluster_set_max_thread_num(num);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_enter_safe_state()
|
||||
{
|
||||
wasm_cluster_change_curr_thread_to_safe();
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_exit_safe_state()
|
||||
{
|
||||
wasm_cluster_change_curr_thread_to_running();
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_THREAD_MGR */
|
||||
|
||||
static WASMModuleCommon *
|
||||
|
@ -1707,6 +1719,29 @@ wasm_runtime_get_user_data(WASMExecEnv *exec_env)
|
|||
return exec_env->user_data;
|
||||
}
|
||||
|
||||
WASMExecEnv *
|
||||
wasm_runtime_get_cur_exec_env(const WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
WASMExecEnv *cur_exec_env = NULL;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
cur_exec_env =
|
||||
((WASMModuleInstanceExtra *)module_inst->e)->common.cur_exec_env;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
cur_exec_env =
|
||||
((AOTModuleInstanceExtra *)module_inst->e)->common.cur_exec_env;
|
||||
#endif
|
||||
|
||||
return cur_exec_env;
|
||||
}
|
||||
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
void
|
||||
wasm_runtime_access_exce_check_guard_page()
|
||||
|
|
|
@ -594,6 +594,10 @@ wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data);
|
|||
WASM_RUNTIME_API_EXTERN void *
|
||||
wasm_runtime_get_user_data(WASMExecEnv *exec_env);
|
||||
|
||||
/* Get the exec_env currently used by the module instance */
|
||||
WASMExecEnv *
|
||||
wasm_runtime_get_cur_exec_env(const WASMModuleInstanceCommon *module_inst);
|
||||
|
||||
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
|
@ -845,6 +849,12 @@ wasm_exec_env_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset,
|
|||
bool
|
||||
wasm_exec_env_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset,
|
||||
uint32 size);
|
||||
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_enter_safe_state();
|
||||
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_exit_safe_state();
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
|
|
|
@ -310,7 +310,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
|||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
exec_env =
|
||||
wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst);
|
||||
wasm_runtime_get_cur_exec_env((WASMModuleInstanceCommon *)module_inst);
|
||||
bh_assert(exec_env);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -718,6 +718,7 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
will always be loaded from memory rather than register */
|
||||
LLVMSetVolatile(terminate_flags, true);
|
||||
|
||||
/* WASM_SUSPEND_FLAG_TERMINATE is 1 */
|
||||
if (!(flag = LLVMBuildAnd(comp_ctx->builder, terminate_flags, I32_ONE,
|
||||
"termination_flag"))) {
|
||||
aot_set_last_error("llvm build AND failed");
|
||||
|
|
|
@ -925,6 +925,7 @@ jit_check_suspend_flags(JitCompContext *cc)
|
|||
|
||||
offset = jit_cc_new_const_I32(cc, offsetof(WASMExecEnv, suspend_flags));
|
||||
GEN_INSN(LDI32, suspend_flags, exec_env, offset);
|
||||
/* WASM_SUSPEND_FLAG_TERMINATE is 1 */
|
||||
GEN_INSN(AND, terminate_flag, suspend_flags, NEW_CONST(I32, 1));
|
||||
|
||||
GEN_INSN(CMP, cc->cmp_reg, terminate_flag, NEW_CONST(I32, 0));
|
||||
|
|
|
@ -13,8 +13,10 @@
|
|||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
#include "../common/wasm_shared_memory.h"
|
||||
#endif
|
||||
#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
#include "../libraries/thread-mgr/thread_manager.h"
|
||||
#endif
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
#include "../libraries/debug-engine/debug_engine.h"
|
||||
#endif
|
||||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
|
@ -1049,47 +1051,42 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
|||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
#define CHECK_SUSPEND_FLAGS() \
|
||||
do { \
|
||||
os_mutex_lock(&exec_env->wait_lock); \
|
||||
if (IS_WAMR_TERM_SIG(exec_env->current_status->signal_flag)) { \
|
||||
os_mutex_unlock(&exec_env->wait_lock); \
|
||||
return; \
|
||||
} \
|
||||
if (IS_WAMR_STOP_SIG(exec_env->current_status->signal_flag)) { \
|
||||
SYNC_ALL_TO_FRAME(); \
|
||||
wasm_cluster_thread_waiting_run(exec_env); \
|
||||
} \
|
||||
os_mutex_unlock(&exec_env->wait_lock); \
|
||||
} while (0)
|
||||
#else
|
||||
#if WASM_SUSPEND_FLAGS_IS_ATOMIC != 0
|
||||
/* The lock is only needed when the suspend_flags is atomic; otherwise
|
||||
the lock is already taken at the time when SUSPENSION_LOCK() is called. */
|
||||
#define SUSPENSION_LOCK() os_mutex_lock(&exec_env->wait_lock);
|
||||
#define SUSPENSION_UNLOCK() os_mutex_unlock(&exec_env->wait_lock);
|
||||
#else
|
||||
#define SUSPENSION_LOCK()
|
||||
#define SUSPENSION_UNLOCK()
|
||||
#endif
|
||||
|
||||
#define CHECK_SUSPEND_FLAGS() \
|
||||
do { \
|
||||
WASM_SUSPEND_FLAGS_LOCK(exec_env->wait_lock); \
|
||||
if (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags) \
|
||||
& WASM_SUSPEND_FLAG_TERMINATE) { \
|
||||
/* terminate current thread */ \
|
||||
WASM_SUSPEND_FLAGS_UNLOCK(exec_env->wait_lock); \
|
||||
os_mutex_lock(&exec_env->wait_lock); \
|
||||
if (IS_WAMR_TERM_SIG(exec_env->current_status.signal_flag)) { \
|
||||
os_mutex_unlock(&exec_env->wait_lock); \
|
||||
return; \
|
||||
} \
|
||||
while (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags) \
|
||||
& WASM_SUSPEND_FLAG_SUSPEND) { \
|
||||
/* suspend current thread */ \
|
||||
SUSPENSION_LOCK() \
|
||||
os_cond_wait(&exec_env->wait_cond, &exec_env->wait_lock); \
|
||||
SUSPENSION_UNLOCK() \
|
||||
if (IS_WAMR_STOP_SIG(exec_env->current_status.signal_flag)) { \
|
||||
SYNC_ALL_TO_FRAME(); \
|
||||
wasm_cluster_thread_waiting_run(exec_env); \
|
||||
} \
|
||||
WASM_SUSPEND_FLAGS_UNLOCK(exec_env->wait_lock); \
|
||||
os_mutex_unlock(&exec_env->wait_lock); \
|
||||
} while (0)
|
||||
#else
|
||||
#define CHECK_SUSPEND_FLAGS() \
|
||||
do { \
|
||||
uint32 suspend_flags, suspend_count; \
|
||||
WASM_SUSPEND_FLAGS_LOCK(exec_env->cluster->thread_state_lock); \
|
||||
suspend_flags = WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags); \
|
||||
if (suspend_flags != 0) { \
|
||||
suspend_count = exec_env->suspend_count; \
|
||||
WASM_SUSPEND_FLAGS_UNLOCK(exec_env->cluster->thread_state_lock); \
|
||||
if (suspend_flags & WASM_SUSPEND_FLAG_TERMINATE) { \
|
||||
/* terminate current thread */ \
|
||||
return; \
|
||||
} \
|
||||
if (suspend_count > 0) { \
|
||||
SYNC_ALL_TO_FRAME(); \
|
||||
wasm_thread_change_to_running(exec_env); \
|
||||
if (wasm_copy_exception(module, NULL)) \
|
||||
goto got_exception; \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
WASM_SUSPEND_FLAGS_UNLOCK(exec_env->cluster->thread_state_lock); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif /* WASM_ENABLE_DEBUG_INTERP */
|
||||
#endif /* WASM_ENABLE_THREAD_MGR */
|
||||
|
@ -1106,9 +1103,9 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
|||
debugger can know the exact opcode who caused the exception */ \
|
||||
frame_ip_orig = frame_ip; \
|
||||
os_mutex_lock(&exec_env->wait_lock); \
|
||||
while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
|
||||
&& exec_env->current_status->step_count++ == 1) { \
|
||||
exec_env->current_status->step_count = 0; \
|
||||
while (exec_env->current_status.signal_flag == WAMR_SIG_SINGSTEP \
|
||||
&& exec_env->current_status.step_count++ == 1) { \
|
||||
exec_env->current_status.step_count = 0; \
|
||||
SYNC_ALL_TO_FRAME(); \
|
||||
wasm_cluster_thread_waiting_run(exec_env); \
|
||||
} \
|
||||
|
@ -1122,15 +1119,15 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
|||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||
#define HANDLE_OP(opcode) case opcode:
|
||||
#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
|
||||
#define HANDLE_OP_END() \
|
||||
os_mutex_lock(&exec_env->wait_lock); \
|
||||
if (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
|
||||
&& exec_env->current_status->step_count++ == 2) { \
|
||||
exec_env->current_status->step_count = 0; \
|
||||
SYNC_ALL_TO_FRAME(); \
|
||||
wasm_cluster_thread_waiting_run(exec_env); \
|
||||
} \
|
||||
os_mutex_unlock(&exec_env->wait_lock); \
|
||||
#define HANDLE_OP_END() \
|
||||
os_mutex_lock(&exec_env->wait_lock); \
|
||||
if (exec_env->current_status.signal_flag == WAMR_SIG_SINGSTEP \
|
||||
&& exec_env->current_status.step_count++ == 2) { \
|
||||
exec_env->current_status.step_count = 0; \
|
||||
SYNC_ALL_TO_FRAME(); \
|
||||
wasm_cluster_thread_waiting_run(exec_env); \
|
||||
} \
|
||||
os_mutex_unlock(&exec_env->wait_lock); \
|
||||
continue
|
||||
#else
|
||||
#define HANDLE_OP_END() continue
|
||||
|
|
|
@ -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
|
||||
|
||||
typedef int32 CellType_I32;
|
||||
typedef int64 CellType_I64;
|
||||
|
@ -1066,17 +1069,28 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
|
|||
#endif
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
#define CHECK_SUSPEND_FLAGS() \
|
||||
do { \
|
||||
WASM_SUSPEND_FLAGS_LOCK(exec_env->wait_lock); \
|
||||
if (WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags) \
|
||||
& WASM_SUSPEND_FLAG_TERMINATE) { \
|
||||
/* terminate current thread */ \
|
||||
WASM_SUSPEND_FLAGS_UNLOCK(exec_env->wait_lock); \
|
||||
return; \
|
||||
} \
|
||||
/* TODO: support suspend and breakpoint */ \
|
||||
WASM_SUSPEND_FLAGS_UNLOCK(exec_env->wait_lock); \
|
||||
#define CHECK_SUSPEND_FLAGS() \
|
||||
do { \
|
||||
uint32 suspend_flags, suspend_count; \
|
||||
WASM_SUSPEND_FLAGS_LOCK(exec_env->cluster->thread_state_lock); \
|
||||
suspend_flags = WASM_SUSPEND_FLAGS_GET(exec_env->suspend_flags); \
|
||||
if (suspend_flags != 0) { \
|
||||
suspend_count = exec_env->suspend_count; \
|
||||
WASM_SUSPEND_FLAGS_UNLOCK(exec_env->cluster->thread_state_lock); \
|
||||
if (suspend_flags & WASM_SUSPEND_FLAG_TERMINATE) { \
|
||||
/* terminate current thread */ \
|
||||
return; \
|
||||
} \
|
||||
if (suspend_count > 0) { \
|
||||
SYNC_ALL_TO_FRAME(); \
|
||||
wasm_thread_change_to_running(exec_env); \
|
||||
if (wasm_copy_exception(module, NULL)) \
|
||||
goto got_exception; \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
WASM_SUSPEND_FLAGS_UNLOCK(exec_env->cluster->thread_state_lock); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -166,12 +166,11 @@ control_thread_routine(void *arg)
|
|||
korp_tid tid;
|
||||
|
||||
status = (uint32)debug_inst->stopped_thread->current_status
|
||||
->signal_flag;
|
||||
.signal_flag;
|
||||
tid = debug_inst->stopped_thread->handle;
|
||||
|
||||
if (debug_inst->stopped_thread->current_status
|
||||
->running_status
|
||||
== STATUS_EXIT) {
|
||||
if (debug_inst->stopped_thread->current_status.running_state
|
||||
== WASM_THREAD_EXITED) {
|
||||
/* If the thread exits, report "W00" if it's the last
|
||||
* thread in the cluster, otherwise ignore this event */
|
||||
status = 0;
|
||||
|
@ -602,7 +601,7 @@ wasm_debug_instance_get_thread_status(WASMDebugInstance *instance, korp_tid tid)
|
|||
exec_env = bh_list_first_elem(&instance->cluster->exec_env_list);
|
||||
while (exec_env) {
|
||||
if (exec_env->handle == tid) {
|
||||
return (uint32)exec_env->current_status->signal_flag;
|
||||
return (uint32)exec_env->current_status.signal_flag;
|
||||
}
|
||||
exec_env = bh_list_elem_next(exec_env);
|
||||
}
|
||||
|
@ -1105,7 +1104,7 @@ wasm_debug_instance_on_failure(WASMDebugInstance *instance)
|
|||
/* Resume all threads so they can receive the TERM signal */
|
||||
os_mutex_lock(&exec_env->wait_lock);
|
||||
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM);
|
||||
exec_env->current_status->running_status = STATUS_RUNNING;
|
||||
exec_env->current_status.running_state = WASM_THREAD_RUNNING;
|
||||
os_cond_signal(&exec_env->wait_cond);
|
||||
os_mutex_unlock(&exec_env->wait_lock);
|
||||
exec_env = bh_list_elem_next(exec_env);
|
||||
|
@ -1208,7 +1207,7 @@ wasm_debug_instance_kill(WASMDebugInstance *instance)
|
|||
if (instance->current_state == APP_STOPPED) {
|
||||
/* Resume all threads so they can receive the TERM signal */
|
||||
os_mutex_lock(&exec_env->wait_lock);
|
||||
exec_env->current_status->running_status = STATUS_RUNNING;
|
||||
exec_env->current_status.running_state = WASM_THREAD_RUNNING;
|
||||
os_cond_signal(&exec_env->wait_cond);
|
||||
os_mutex_unlock(&exec_env->wait_lock);
|
||||
}
|
||||
|
|
|
@ -526,7 +526,7 @@ handle_threadstop_request(WASMGDBServer *server, char *payload)
|
|||
os_mutex_unlock(&debug_inst->wait_lock);
|
||||
|
||||
tid = debug_inst->stopped_thread->handle;
|
||||
status = (uint32)debug_inst->stopped_thread->current_status->signal_flag;
|
||||
status = (uint32)debug_inst->stopped_thread->current_status.signal_flag;
|
||||
|
||||
wasm_debug_instance_set_cur_thread(debug_inst, tid);
|
||||
|
||||
|
|
|
@ -674,7 +674,8 @@ pthread_join_wrapper(wasm_exec_env_t exec_env, uint32 thread,
|
|||
|
||||
if (node->status != THREAD_EXIT) {
|
||||
/* if the thread is still running, call the platforms join API */
|
||||
join_ret = wasm_cluster_join_thread(target_exec_env, (void **)&ret);
|
||||
join_ret =
|
||||
wasm_cluster_join_thread(target_exec_env, exec_env, (void **)&ret);
|
||||
}
|
||||
else {
|
||||
/* if the thread has exited, return stored results */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,9 +23,33 @@ typedef struct WASMDebugInstance WASMDebugInstance;
|
|||
struct WASMCluster {
|
||||
struct WASMCluster *next;
|
||||
|
||||
/* The lock for exec_env_list, has_exception and processing */
|
||||
korp_mutex lock;
|
||||
|
||||
bh_list exec_env_list;
|
||||
|
||||
/* The lock for thread_safe_cond, thread_resume_cond and the below
|
||||
fields of exec_env:
|
||||
suspend_flags, suspend_count, current_status, thread_ret_value */
|
||||
korp_mutex thread_state_lock;
|
||||
|
||||
/* Condition variable for notifying threads that are waiting for
|
||||
threads to go to a safe state. All threads waiting for this
|
||||
condition share this one condition varialbe, so when waken up,
|
||||
they must check whether the waited threads are really in a safe
|
||||
state. It's protected by thread_state_lock since it involves
|
||||
operations of thread states. */
|
||||
korp_cond thread_safe_cond;
|
||||
|
||||
/* Condition variable for notifying threads that are waiting for
|
||||
resumption that their suspend counts have changed and they may be
|
||||
able to resume (i.e. change to RUNNING state). All suspended
|
||||
threads share this one condition variable, so when waken up, they
|
||||
must recheck their suspend counts to check whether they are
|
||||
really able to resume. It's protected by thread_state_lock since
|
||||
it involves operations of suspend counts. */
|
||||
korp_cond thread_resume_cond;
|
||||
|
||||
#if WASM_ENABLE_HEAP_AUX_STACK_ALLOCATION == 0
|
||||
/* The aux stack of a module with shared memory will be
|
||||
divided into several segments. This array store the
|
||||
|
@ -34,13 +58,16 @@ struct WASMCluster {
|
|||
/* Record which segments are occupied */
|
||||
bool *stack_segment_occupied;
|
||||
#endif
|
||||
|
||||
/* Size of every stack segment */
|
||||
uint32 stack_size;
|
||||
|
||||
/* When has_exception == true, this cluster should refuse any spawn thread
|
||||
* requests, this flag can be cleared by calling
|
||||
* wasm_runtime_clear_exception on instances of any threads of this cluster
|
||||
*/
|
||||
bool has_exception;
|
||||
|
||||
/* When processing is true, this cluster should refuse any spawn thread
|
||||
* requests. This is a short-lived state, must be cleared immediately once
|
||||
* the processing finished.
|
||||
|
@ -48,6 +75,7 @@ struct WASMCluster {
|
|||
* with lock, see wams_cluster_wait_for_all and wasm_cluster_terminate_all
|
||||
*/
|
||||
bool processing;
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
WASMDebugInstance *debug_inst;
|
||||
#endif
|
||||
|
@ -85,7 +113,8 @@ wasm_cluster_create_thread(WASMExecEnv *exec_env,
|
|||
void *(*thread_routine)(void *), void *arg);
|
||||
|
||||
int32
|
||||
wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val);
|
||||
wasm_cluster_join_thread(WASMExecEnv *exec_env, WASMExecEnv *self,
|
||||
void **ret_val);
|
||||
|
||||
int32
|
||||
wasm_cluster_detach_thread(WASMExecEnv *exec_env);
|
||||
|
@ -103,18 +132,21 @@ void
|
|||
wasm_cluster_cancel_all_callbacks();
|
||||
|
||||
void
|
||||
wasm_cluster_suspend_all(WASMCluster *cluster);
|
||||
wasm_cluster_suspend_thread(WASMExecEnv *exec_env, WASMExecEnv *self);
|
||||
|
||||
void
|
||||
wasm_cluster_suspend_all_except_self(WASMCluster *cluster,
|
||||
WASMExecEnv *exec_env);
|
||||
|
||||
void
|
||||
wasm_cluster_suspend_thread(WASMExecEnv *exec_env);
|
||||
wasm_cluster_suspend_all(WASMCluster *cluster);
|
||||
|
||||
void
|
||||
wasm_cluster_resume_thread(WASMExecEnv *exec_env);
|
||||
|
||||
void
|
||||
wasm_cluster_resume_all_except_self(WASMCluster *cluster, WASMExecEnv *self);
|
||||
|
||||
void
|
||||
wasm_cluster_resume_all(WASMCluster *cluster);
|
||||
|
||||
|
@ -132,7 +164,7 @@ void
|
|||
wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
|
||||
WASMExecEnv *exec_env);
|
||||
|
||||
bool
|
||||
void
|
||||
wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env);
|
||||
|
||||
WASMExecEnv *
|
||||
|
@ -158,34 +190,27 @@ wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key,
|
|||
bool
|
||||
wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env);
|
||||
|
||||
ThreadRunningState
|
||||
wasm_thread_change_to_running(WASMExecEnv *self);
|
||||
|
||||
void
|
||||
wasm_cluster_change_curr_thread_to_running();
|
||||
|
||||
void
|
||||
wasm_cluster_change_curr_thread_to_safe();
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
|
||||
#define WAMR_SIG_TRAP (5)
|
||||
#define WAMR_SIG_STOP (19)
|
||||
#define WAMR_SIG_TERM (15)
|
||||
#define WAMR_SIG_SINGSTEP (0x1ff)
|
||||
|
||||
#define STATUS_RUNNING (0)
|
||||
#define STATUS_STOP (1)
|
||||
#define STATUS_EXIT (2)
|
||||
#define STATUS_STEP (3)
|
||||
|
||||
#define IS_WAMR_TERM_SIG(signo) ((signo) == WAMR_SIG_TERM)
|
||||
|
||||
#define IS_WAMR_STOP_SIG(signo) \
|
||||
((signo) == WAMR_SIG_STOP || (signo) == WAMR_SIG_TRAP)
|
||||
|
||||
struct WASMCurrentEnvStatus {
|
||||
uint64 signal_flag : 32;
|
||||
uint64 step_count : 16;
|
||||
uint64 running_status : 16;
|
||||
};
|
||||
|
||||
WASMCurrentEnvStatus *
|
||||
wasm_cluster_create_exenv_status();
|
||||
|
||||
void
|
||||
wasm_cluster_destroy_exenv_status(WASMCurrentEnvStatus *status);
|
||||
|
||||
void
|
||||
wasm_cluster_send_signal_all(WASMCluster *cluster, uint32 signo);
|
||||
|
||||
|
|
|
@ -249,6 +249,13 @@ os_mutex_lock(korp_mutex *mutex)
|
|||
return aos_mutex_lock(mutex, AOS_WAIT_FOREVER);
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_trylock(korp_mutex *mutex)
|
||||
{
|
||||
/* unsupported */
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
|
|
|
@ -344,6 +344,13 @@ os_mutex_lock(korp_mutex *mutex)
|
|||
return ret == pdPASS ? BHT_OK : BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_trylock(korp_mutex *mutex)
|
||||
{
|
||||
/* unsupported */
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
|
|
|
@ -154,6 +154,17 @@ os_mutex_lock(korp_mutex *mutex)
|
|||
return ret == 0 ? BHT_OK : BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_trylock(korp_mutex *mutex)
|
||||
{
|
||||
int ret;
|
||||
|
||||
assert(mutex);
|
||||
ret = pthread_mutex_trylock(mutex);
|
||||
|
||||
return ret == 0 ? BHT_OK : BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
|
|
|
@ -75,6 +75,12 @@ os_mutex_lock(korp_mutex *mutex)
|
|||
return pthread_mutex_lock(mutex);
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_trylock(korp_mutex *mutex)
|
||||
{
|
||||
return pthread_mutex_trylock(mutex);
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
|
@ -230,4 +236,4 @@ int
|
|||
os_cond_broadcast(korp_cond *cond)
|
||||
{
|
||||
return pthread_cond_broadcast(cond);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,6 +103,9 @@ os_mutex_destroy(korp_mutex *mutex);
|
|||
int
|
||||
os_mutex_lock(korp_mutex *mutex);
|
||||
|
||||
int
|
||||
os_mutex_trylock(korp_mutex *mutex);
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex);
|
||||
|
||||
|
|
|
@ -100,6 +100,16 @@ os_mutex_lock(korp_mutex *mutex)
|
|||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_trylock(korp_mutex *mutex)
|
||||
{
|
||||
#ifndef SGX_DISABLE_PTHREAD
|
||||
return pthread_mutex_lock(mutex);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
|
|
|
@ -323,6 +323,13 @@ os_mutex_lock(korp_mutex *mutex)
|
|||
return 0; // Riot mutexes do not return until success
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_trylock(korp_mutex *mutex)
|
||||
{
|
||||
/* unsupported */
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
|
|
|
@ -162,6 +162,13 @@ os_mutex_lock(korp_mutex *mutex)
|
|||
return rt_mutex_take(mutex, RT_WAITING_FOREVER);
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_trylock(korp_mutex *mutex)
|
||||
{
|
||||
/* unsupported */
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
|
|
|
@ -534,6 +534,13 @@ os_mutex_lock(korp_mutex *mutex)
|
|||
return ret != WAIT_FAILED ? BHT_OK : BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_trylock(korp_mutex *mutex)
|
||||
{
|
||||
/* unsupported */
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
|
|
|
@ -451,6 +451,13 @@ os_mutex_lock(korp_mutex *mutex)
|
|||
return k_mutex_lock(mutex, K_FOREVER);
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_trylock(korp_mutex *mutex)
|
||||
{
|
||||
/* unsupported */
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ run_aot_tests () {
|
|||
|
||||
test_aot="${test_wasm%.wasm}.aot"
|
||||
test_json="${test_wasm%.wasm}.json"
|
||||
|
||||
|
||||
if [ -f ${test_wasm} ]; then
|
||||
expected=$(jq .exit_code ${test_json})
|
||||
fi
|
||||
|
@ -87,9 +87,9 @@ if [[ $MODE != "aot" ]];then
|
|||
if [ "${ret}" -eq 0 ]; then
|
||||
ret=${PIPESTATUS[0]}
|
||||
fi
|
||||
|
||||
|
||||
exit_code=${ret}
|
||||
|
||||
|
||||
deactivate
|
||||
else
|
||||
target_option=""
|
||||
|
|
Loading…
Reference in New Issue
Block a user