Просмотр исходного кода

Refactor interrupting blocking threads (#1948)

- Disable the feature by default, use `cmake -DWAMR_BUILD_INTERRUPT_BLOCK_INSN` to enable it
- Reuse the original signal handler
- Move kill threads to be after notifying atomic waiting threads
- Add os_thread_set_interruptible to control whether a thread can be interrupted
- Fix some issues and refine the code
Wenyong Huang 2 лет назад
Родитель
Сommit
ed98d8805d

+ 3 - 3
build-scripts/config_common.cmake

@@ -248,9 +248,9 @@ else ()
     add_definitions (-DWASM_DISABLE_STACK_HW_BOUND_CHECK=0)
   endif ()
 endif ()
-if (WAMR_DISABLE_BLOCK_INSN_INTERRUPT EQUAL 1)
-  add_definitions (-DWASM_DISABLE_BLOCK_INSN_INTERRUPT=1)
-  message ("     Interruption of blocking instructions disabled")
+if (WAMR_BUILD_INTERRUPT_BLOCK_INSN EQUAL 1)
+  add_definitions (-DWASM_ENABLE_INTERRUPT_BLOCK_INSN=1)
+  message ("     Interruption of blocking instructions enabled")
 endif ()
 if (WAMR_BUILD_SIMD EQUAL 1)
   if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*")

+ 3 - 3
core/config.h

@@ -266,11 +266,11 @@
 #define WASM_DISABLE_STACK_HW_BOUND_CHECK 0
 #endif
 
-/* Disable the capability of interrupting blocking instructions
+/* Enable the capability of interrupting blocking instructions
  * (e.g. atomic.wait, sleep) when an exception (e.g. trap, proc_exit) is raised
  */
-#ifndef WASM_DISABLE_BLOCK_INSN_INTERRUPT
-#define WASM_DISABLE_BLOCK_INSN_INTERRUPT 0
+#ifndef WASM_ENABLE_INTERRUPT_BLOCK_INSN
+#define WASM_ENABLE_INTERRUPT_BLOCK_INSN 0
 #endif
 
 /* Disable SIMD unless it is manualy enabled somewhere */

+ 32 - 8
core/iwasm/aot/aot_runtime.c

@@ -1276,10 +1276,16 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
         return false;
     }
 
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 0;
+#endif
     wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
-
     wasm_runtime_set_exec_env_tls(exec_env);
+
     if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+        exec_env->canjump = 1;
+#endif
         /* Quick call with func_ptr if the function signature is simple */
         if (!signature && param_count == 1 && types[0] == VALUE_TYPE_I32) {
             if (result_count == 0) {
@@ -1321,6 +1327,10 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
         ret = false;
     }
 
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 0;
+#endif
+
     jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
     bh_assert(&jmpbuf_node == jmpbuf_node_pop);
     if (!exec_env->jmpbuf_stack_top) {
@@ -1330,12 +1340,16 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
         os_sigreturn();
         os_signal_unmask();
     }
+
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 1;
+#endif
     (void)jmpbuf_node_pop;
     return ret;
 }
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
-#ifndef OS_ENABLE_BLOCK_INSN_INTERRUPT
+#ifndef OS_ENABLE_INTERRUPT_BLOCK_INSN
 
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #define invoke_native_internal invoke_native_with_hw_bound_check
@@ -1343,7 +1357,7 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
 #define invoke_native_internal wasm_runtime_invoke_native
 #endif
 
-#else /* else of OS_ENABLE_BLOCK_INSN_INTERRUPT */
+#else /* else of OS_ENABLE_INTERRUPT_BLOCK_INSN */
 
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #define invoke_native_block_insn_interrupt invoke_native_with_hw_bound_check
@@ -1357,29 +1371,39 @@ invoke_native_internal(WASMExecEnv *exec_env, void *func_ptr,
                        void *attachment, uint32 *argv, uint32 argc,
                        uint32 *argv_ret)
 {
-    int ret = false;
+    bool ret;
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
+
+    exec_env->canjump = 0;
+    wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
     wasm_runtime_set_exec_env_tls(exec_env);
 
     if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
-        wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
+        exec_env->canjump = 1;
         ret = invoke_native_block_insn_interrupt(exec_env, func_ptr, func_type,
                                                  signature, attachment, argv,
                                                  argc, argv_ret);
     }
     else {
+        /* Exception has been set in signal handler before calling longjmp */
         ret = false;
     }
 
+    exec_env->canjump = 0;
     jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
     bh_assert(&jmpbuf_node == jmpbuf_node_pop);
     if (!exec_env->jmpbuf_stack_top) {
         wasm_runtime_set_exec_env_tls(NULL);
     }
-
+    if (!ret) {
+        os_sigreturn();
+        os_signal_unmask();
+    }
+    exec_env->canjump = 1;
+    (void)jmpbuf_node_pop;
     return ret;
 }
-#endif /* end of OS_ENABLE_BLOCK_INSN_INTERRUPT */
+#endif /* end of OS_ENABLE_INTERRUPT_BLOCK_INSN */
 
 bool
 aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
@@ -1536,7 +1560,7 @@ aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
     WASMExecEnv *exec_env = NULL, *existing_exec_env = NULL;
     bool ret;
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     existing_exec_env = exec_env = wasm_runtime_get_exec_env_tls();
 #elif WASM_ENABLE_THREAD_MGR != 0
     existing_exec_env = exec_env =

+ 1 - 1
core/iwasm/common/wasm_exec_env.c

@@ -228,7 +228,7 @@ wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg)
 }
 #endif
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
 void
 wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf)
 {

+ 9 - 3
core/iwasm/common/wasm_exec_env.h

@@ -25,7 +25,7 @@ typedef struct WASMCurrentEnvStatus WASMCurrentEnvStatus;
 #endif
 #endif
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
 typedef struct WASMJmpBuf {
     struct WASMJmpBuf *prev;
     korp_jmpbuf jmpbuf;
@@ -120,6 +120,12 @@ typedef struct WASMExecEnv {
 
     /* whether current thread is detached */
     bool thread_is_detached;
+
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    /* Whether the signal handler of interrupting blocking instruction
+       feature can longjmp to the place of setjmp */
+    volatile sig_atomic_t canjump;
+#endif
 #endif
 
 #if WASM_ENABLE_DEBUG_INTERP != 0
@@ -141,7 +147,7 @@ typedef struct WASMExecEnv {
     BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
 #endif
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     WASMJmpBuf *jmpbuf_stack_top;
 #endif
 #ifdef OS_ENABLE_HW_BOUND_CHECK
@@ -303,7 +309,7 @@ void
 wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg);
 #endif
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
 void
 wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf);
 

+ 52 - 36
core/iwasm/common/wasm_runtime_common.c

@@ -134,17 +134,17 @@ static LLVMJITOptions llvm_jit_options = { 3, 3 };
 
 static RunningMode runtime_running_mode = Mode_Default;
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
 /* The exec_env of thread local storage, set before calling function
    and used in signal handler, as we cannot get it from the argument
    of signal handler */
 static os_thread_local_attribute WASMExecEnv *exec_env_tls = NULL;
-#endif
 
-#ifdef OS_ENABLE_HW_BOUND_CHECK
 #ifndef BH_PLATFORM_WINDOWS
+
+#ifdef OS_ENABLE_HW_BOUND_CHECK
 static void
-runtime_signal_handler(void *sig_addr)
+hw_bound_check_sig_handler(void *sig_addr)
 {
     WASMModuleInstance *module_inst;
     WASMMemoryInstance *memory_inst;
@@ -200,7 +200,38 @@ runtime_signal_handler(void *sig_addr)
         }
     }
 }
-#else
+#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
+
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+static void
+interrupt_block_insn_sig_handler()
+{
+    WASMJmpBuf *jmpbuf_node;
+
+    /* Check whether current thread is running wasm function */
+    if (exec_env_tls && exec_env_tls->handle == os_self_thread()
+        && exec_env_tls->canjump
+        && (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
+        os_longjmp(jmpbuf_node->jmpbuf, 1);
+    }
+}
+#endif /* end of OS_ENABLE_INTERRUPT_BLOCK_INSN */
+
+static void
+runtime_signal_handler(int sig, void *sig_addr)
+{
+#ifdef OS_ENABLE_HW_BOUND_CHECK
+    if (sig == OS_SIGSEGV || sig == OS_SIGBUS)
+        hw_bound_check_sig_handler(sig_addr);
+#endif
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    if (sig == OS_SIGUSR1)
+        interrupt_block_insn_sig_handler();
+#endif
+}
+
+#else /* else if BH_PLATFORM_WINDOWS */
+
 static LONG
 runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
 {
@@ -284,6 +315,7 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
               sig_addr);
     return EXCEPTION_CONTINUE_SEARCH;
 }
+
 #endif /* end of BH_PLATFORM_WINDOWS */
 
 static bool
@@ -311,9 +343,7 @@ runtime_signal_destroy()
 #endif
     os_thread_signal_destroy();
 }
-#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
 void
 wasm_runtime_set_exec_env_tls(WASMExecEnv *exec_env)
 {
@@ -325,20 +355,8 @@ wasm_runtime_get_exec_env_tls()
 {
     return exec_env_tls;
 }
-#endif
-
-#ifdef OS_ENABLE_BLOCK_INSN_INTERRUPT
-static void
-interrupt_block_insn_sig_handler()
-{
-    WASMJmpBuf *jmpbuf_node = exec_env_tls->jmpbuf_stack_top;
-    if (!jmpbuf_node) {
-        return;
-    }
-
-    os_longjmp(jmpbuf_node->jmpbuf, 1);
-}
-#endif /* OS_ENABLE_BLOCK_INSN_INTERRUPT */
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */
 
 static bool
 wasm_runtime_env_init()
@@ -371,12 +389,7 @@ wasm_runtime_env_init()
         goto fail5;
     }
 #endif
-#ifdef OS_ENABLE_BLOCK_INSN_INTERRUPT
-    if (!os_interrupt_block_insn_init(interrupt_block_insn_sig_handler)) {
-        goto fail6;
-    }
-#endif
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     if (!runtime_signal_init()) {
         goto fail6;
     }
@@ -431,10 +444,8 @@ fail8:
 fail7:
 #endif
 #endif
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     runtime_signal_destroy();
-#endif
 fail6:
 #endif
 #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_THREAD_MGR != 0)
@@ -494,7 +505,7 @@ wasm_runtime_destroy()
 #endif
 #endif
 
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     runtime_signal_destroy();
 #endif
 
@@ -1333,7 +1344,7 @@ wasm_runtime_init_thread_env(void)
         return false;
 #endif
 
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     if (!runtime_signal_init()) {
 #ifdef BH_PLATFORM_WINDOWS
         os_thread_env_destroy();
@@ -1348,7 +1359,7 @@ wasm_runtime_init_thread_env(void)
 void
 wasm_runtime_destroy_thread_env(void)
 {
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     runtime_signal_destroy();
 #endif
 
@@ -1365,11 +1376,9 @@ wasm_runtime_thread_env_inited(void)
         return false;
 #endif
 
-#if WASM_ENABLE_AOT != 0
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     if (!os_thread_signal_inited())
         return false;
-#endif
 #endif
     return true;
 }
@@ -2346,6 +2355,13 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
             (WASMModuleInstanceCommon *)module_inst);
     }
 #endif
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    if (exec_env) {
+        /* Kill the blocking threads after exception was spreaded and
+           atomic waiting nodes were notified */
+        wasm_cluster_kill_all_except_self(exec_env->cluster, exec_env);
+    }
+#endif
 #else
     (void)exec_env;
 #endif

+ 1 - 1
core/iwasm/common/wasm_runtime_common.h

@@ -435,7 +435,7 @@ typedef struct WASMSignalInfo {
 } WASMSignalInfo;
 #endif
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
 /* Set exec_env of thread local storage */
 void
 wasm_runtime_set_exec_env_tls(WASMExecEnv *exec_env);

+ 36 - 6
core/iwasm/interpreter/wasm_runtime.c

@@ -2264,10 +2264,16 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
         return;
     }
 
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 0;
+#endif
     wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
-
     wasm_runtime_set_exec_env_tls(exec_env);
+
     if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+        exec_env->canjump = 1;
+#endif
 #ifndef BH_PLATFORM_WINDOWS
         wasm_interp_call_wasm(module_inst, exec_env, function, argc, argv);
 #else
@@ -2293,6 +2299,10 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
         ret = false;
     }
 
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 0;
+#endif
+
     /* Note: can't check wasm_get_exception(module_inst) here, there may be
      * exception which is not caught by hardware (e.g. uninitialized elements),
      * then the stack-frame is already freed inside wasm_interp_call_wasm */
@@ -2316,11 +2326,15 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
         os_sigreturn();
         os_signal_unmask();
     }
+
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 1;
+#endif
     (void)jmpbuf_node_pop;
 }
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
-#ifndef OS_ENABLE_BLOCK_INSN_INTERRUPT
+#ifndef OS_ENABLE_INTERRUPT_BLOCK_INSN
 
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #define interp_call_wasm call_wasm_with_hw_bound_check
@@ -2328,7 +2342,7 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
 #define interp_call_wasm wasm_interp_call_wasm
 #endif
 
-#else /* else of OS_ENABLE_BLOCK_INSN_INTERRUPT */
+#else /* else of OS_ENABLE_INTERRUPT_BLOCK_INSN */
 
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #define call_wasm_block_insn_interrupt call_wasm_with_hw_bound_check
@@ -2341,21 +2355,37 @@ interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
                  WASMFunctionInstance *function, unsigned argc, uint32 argv[])
 {
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
+    bool ret;
+
+    exec_env->canjump = 0;
     wasm_runtime_set_exec_env_tls(exec_env);
+    wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
 
     if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
-        wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
+        exec_env->canjump = 1;
         call_wasm_block_insn_interrupt(module_inst, exec_env, function, argc,
                                        argv);
+        ret = !wasm_get_exception(module_inst) ? true : false;
+    }
+    else {
+        /* Exception has been set in signal handler before calling longjmp */
+        ret = false;
     }
 
+    exec_env->canjump = 0;
     jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
     bh_assert(&jmpbuf_node == jmpbuf_node_pop);
     if (!exec_env->jmpbuf_stack_top) {
         wasm_runtime_set_exec_env_tls(NULL);
     }
+    if (!ret) {
+        os_sigreturn();
+        os_signal_unmask();
+    }
+    exec_env->canjump = 1;
+    (void)jmpbuf_node_pop;
 }
-#endif /* end of OS_ENABLE_BLOCK_INSN_INTERRUPT */
+#endif /* end of OS_ENABLE_INTERRUPT_BLOCK_INSN */
 
 bool
 wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
@@ -2380,7 +2410,7 @@ wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst,
     WASMExecEnv *exec_env = NULL, *existing_exec_env = NULL;
     bool ret;
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     existing_exec_env = exec_env = wasm_runtime_get_exec_env_tls();
 #elif WASM_ENABLE_THREAD_MGR != 0
     existing_exec_env = exec_env =

+ 10 - 0
core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c

@@ -499,6 +499,10 @@ pthread_start_routine(void *arg)
     ThreadInfoNode *info_node = routine_args->info_node;
     uint32 argv[1];
 
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+    os_thread_set_interruptible(false);
+#endif
+
     parent_exec_env = info_node->parent_exec_env;
     os_mutex_lock(&parent_exec_env->wait_lock);
     info_node->exec_env = exec_env;
@@ -518,10 +522,16 @@ pthread_start_routine(void *arg)
     wasm_exec_env_set_thread_info(exec_env);
     argv[0] = routine_args->arg;
 
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+    os_thread_set_interruptible(true);
+#endif
     if (!wasm_runtime_call_indirect(exec_env, routine_args->elem_index, 1,
                                     argv)) {
         /* Exception has already been spread during throwing */
     }
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+    os_thread_set_interruptible(false);
+#endif
 
     /* destroy pthread key values */
     call_key_destructor(exec_env);

+ 26 - 7
core/iwasm/libraries/thread-mgr/thread_manager.c

@@ -522,7 +522,7 @@ thread_manager_start_routine(void *arg)
     exec_env->handle = os_self_thread();
     ret = exec_env->thread_start_routine(exec_env);
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     if (exec_env->suspend_flags.flags & 0x08)
         ret = exec_env->thread_ret_value;
 #endif
@@ -821,7 +821,7 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
 {
     WASMCluster *cluster;
 
-#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_BLOCK_INSN_INTERRUPT)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     if (exec_env->jmpbuf_stack_top) {
         /* Store the return value in exec_env */
         exec_env->thread_ret_value = retval;
@@ -969,6 +969,30 @@ wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
     os_mutex_unlock(&cluster->lock);
 }
 
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+static void
+kill_thread_visitor(void *node, void *user_data)
+{
+    WASMExecEnv *curr_exec_env = (WASMExecEnv *)node;
+    WASMExecEnv *exec_env = (WASMExecEnv *)user_data;
+
+    if (curr_exec_env == exec_env)
+        return;
+
+    bh_assert(curr_exec_env->handle);
+    os_thread_kill(curr_exec_env->handle);
+}
+
+void
+wasm_cluster_kill_all_except_self(WASMCluster *cluster, WASMExecEnv *exec_env)
+{
+    os_mutex_lock(&cluster->lock);
+    traverse_list(&cluster->exec_env_list, kill_thread_visitor,
+                  (void *)exec_env);
+    os_mutex_unlock(&cluster->lock);
+}
+#endif
+
 bool
 wasm_cluster_register_destroy_callback(void (*callback)(WASMCluster *))
 {
@@ -1059,11 +1083,6 @@ set_exception_visitor(void *node, void *user_data)
                     sizeof(curr_wasm_inst->cur_exception),
                     wasm_inst->cur_exception, sizeof(wasm_inst->cur_exception));
 
-#ifdef OS_ENABLE_BLOCK_INSN_INTERRUPT
-        bh_assert(curr_exec_env->handle);
-        os_thread_kill(curr_exec_env->handle);
-#endif
-
         /* Terminate the thread so it can exit from dead loops */
         set_thread_cancel_flags(curr_exec_env);
     }

+ 5 - 0
core/iwasm/libraries/thread-mgr/thread_manager.h

@@ -125,6 +125,11 @@ void
 wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
                                       WASMExecEnv *exec_env);
 
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+void
+wasm_cluster_kill_all_except_self(WASMCluster *cluster, WASMExecEnv *exec_env);
+#endif
+
 bool
 wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env);
 

+ 22 - 13
core/shared/platform/android/platform_internal.h

@@ -63,14 +63,6 @@ typedef sem_t korp_sem;
 
 #define bh_socket_t int
 
-#if WASM_DISABLE_BLOCK_INSN_INTERRUPT == 0 && WASM_ENABLE_THREAD_MGR != 0
-#define OS_ENABLE_BLOCK_INSN_INTERRUPT
-
-typedef void (*os_block_insn_sig_handler)();
-bool
-os_interrupt_block_insn_init(os_block_insn_sig_handler handler);
-#endif
-
 #if WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
@@ -82,7 +74,20 @@ os_interrupt_block_insn_init(os_block_insn_sig_handler handler);
 
 #define os_getpagesize getpagesize
 
-typedef void (*os_signal_handler)(void *sig_addr);
+#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
+#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
+
+#if WASM_ENABLE_INTERRUPT_BLOCK_INSN != 0 && WASM_ENABLE_THREAD_MGR != 0
+#define OS_ENABLE_INTERRUPT_BLOCK_INSN
+#endif
+
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+
+#define OS_SIGSEGV SIGSEGV
+#define OS_SIGBUS SIGBUS
+#define OS_SIGUSR1 SIGUSR1
+
+typedef void (*os_signal_handler)(int sig, void *sig_addr);
 
 int
 os_thread_signal_init(os_signal_handler handler);
@@ -98,15 +103,19 @@ os_signal_unmask();
 
 void
 os_sigreturn();
-#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
-#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
-#if defined(OS_ENABLE_BLOCK_INSN_INTERRUPT) || defined(OS_ENABLE_HW_BOUND_CHECK)
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+void
+os_thread_set_interruptible(bool flag);
+#endif
+
 #include <setjmp.h>
 typedef jmp_buf korp_jmpbuf;
 #define os_setjmp setjmp
 #define os_longjmp longjmp
-#endif
+
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */
 
 typedef long int __syscall_slong_t;
 

+ 82 - 40
core/shared/platform/common/posix/posix_thread.c

@@ -12,12 +12,12 @@
 typedef struct {
     thread_start_routine_t start;
     void *arg;
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     os_signal_handler signal_handler;
 #endif
 } thread_wrapper_arg;
 
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
 /* The signal handler passed to os_thread_signal_init() */
 static os_thread_local_attribute os_signal_handler signal_handler;
 #endif
@@ -28,7 +28,7 @@ os_thread_wrapper(void *arg)
     thread_wrapper_arg *targ = arg;
     thread_start_routine_t start_func = targ->start;
     void *thread_arg = targ->arg;
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     os_signal_handler handler = targ->signal_handler;
 #endif
 
@@ -36,12 +36,12 @@ os_thread_wrapper(void *arg)
     os_printf("THREAD CREATED %jx\n", (uintmax_t)(uintptr_t)pthread_self());
 #endif
     BH_FREE(targ);
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     if (os_thread_signal_init(handler) != 0)
         return NULL;
 #endif
     start_func(thread_arg);
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     os_thread_signal_destroy();
 #endif
     return NULL;
@@ -75,7 +75,7 @@ os_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
 
     targ->start = start;
     targ->arg = arg;
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     targ->signal_handler = signal_handler;
 #endif
 
@@ -340,7 +340,7 @@ os_thread_detach(korp_tid thread)
 void
 os_thread_exit(void *retval)
 {
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     os_thread_signal_destroy();
 #endif
     return pthread_exit(retval);
@@ -420,26 +420,7 @@ os_thread_get_stack_boundary()
     return addr;
 }
 
-#ifdef OS_ENABLE_BLOCK_INSN_INTERRUPT
-bool
-os_interrupt_block_insn_init(os_block_insn_sig_handler handler)
-{
-    struct sigaction act;
-    memset(&act, 0, sizeof(act));
-    act.sa_handler = handler;
-    sigfillset(&act.sa_mask);
-    if (sigaction(SIGUSR1, &act, NULL) < 0) {
-        os_printf("failed to set signal handler\n");
-        return false;
-    }
-
-    return true;
-}
-#endif /* OS_ENABLE_BLOCK_INSN_INTERRUPT */
-
-#ifdef OS_ENABLE_HW_BOUND_CHECK
-
-#define SIG_ALT_STACK_SIZE (32 * 1024)
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
 
 /**
  * Whether thread signal enviornment is initialized:
@@ -448,7 +429,10 @@ os_interrupt_block_insn_init(os_block_insn_sig_handler handler)
  */
 static os_thread_local_attribute bool thread_signal_inited = false;
 
-#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+
+#define SIG_ALT_STACK_SIZE (32 * 1024)
+
 /* The signal alternate stack base addr */
 static os_thread_local_attribute uint8 *sigalt_stack_base_addr;
 
@@ -512,7 +496,8 @@ destroy_stack_guard_pages()
     os_mprotect(stack_min_addr, page_size * guard_page_count,
                 MMAP_PROT_READ | MMAP_PROT_WRITE);
 }
-#endif /* end of WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 */
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) && \
+          WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 */
 
 static void
 mask_signals(int how)
@@ -520,13 +505,23 @@ mask_signals(int how)
     sigset_t set;
 
     sigemptyset(&set);
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
     sigaddset(&set, SIGSEGV);
     sigaddset(&set, SIGBUS);
+#endif
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+    sigaddset(&set, SIGUSR1);
+#endif
     pthread_sigmask(how, &set, NULL);
 }
 
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
 static os_thread_local_attribute struct sigaction prev_sig_act_SIGSEGV;
 static os_thread_local_attribute struct sigaction prev_sig_act_SIGBUS;
+#endif
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+static os_thread_local_attribute struct sigaction prev_sig_act_SIGUSR1;
+#endif
 
 static void
 signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext)
@@ -537,14 +532,27 @@ signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext)
     mask_signals(SIG_BLOCK);
 
     /* Try to handle signal with the registered signal handler */
-    if (signal_handler && (sig_num == SIGSEGV || sig_num == SIGBUS)) {
-        signal_handler(sig_addr);
+    if (signal_handler) {
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
+        if (sig_num == SIGSEGV || sig_num == SIGBUS)
+            signal_handler(sig_num, sig_addr);
+#endif
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+        if (sig_num == SIGUSR1)
+            signal_handler(sig_num, sig_addr);
+#endif
     }
 
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
     if (sig_num == SIGSEGV)
         prev_sig_act = &prev_sig_act_SIGSEGV;
     else if (sig_num == SIGBUS)
         prev_sig_act = &prev_sig_act_SIGBUS;
+#endif
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+    if (sig_num == SIGUSR1)
+        prev_sig_act = &prev_sig_act_SIGUSR1;
+#endif
 
     /* Forward the signal to next handler if found */
     if (prev_sig_act && (prev_sig_act->sa_flags & SA_SIGINFO)) {
@@ -558,12 +566,19 @@ signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext)
     /* Output signal info and then crash if signal is unhandled */
     else {
         switch (sig_num) {
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
             case SIGSEGV:
                 os_printf("unhandled SIGSEGV, si_addr: %p\n", sig_addr);
                 break;
             case SIGBUS:
                 os_printf("unhandled SIGBUS, si_addr: %p\n", sig_addr);
                 break;
+#endif
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+            case SIGUSR1:
+                os_printf("unhandled SIGUSR1, si_addr: %p\n", sig_addr);
+                break;
+#endif
             default:
                 os_printf("unhandle signal %d, si_addr: %p\n", sig_num,
                           sig_addr);
@@ -578,7 +593,7 @@ int
 os_thread_signal_init(os_signal_handler handler)
 {
     struct sigaction sig_act;
-#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
     stack_t sigalt_stack_info;
     uint32 map_size = SIG_ALT_STACK_SIZE;
     uint8 *map_addr;
@@ -587,7 +602,7 @@ os_thread_signal_init(os_signal_handler handler)
     if (thread_signal_inited)
         return 0;
 
-#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
     if (!init_stack_guard_pages()) {
         os_printf("Failed to init stack guard pages\n");
         return -1;
@@ -611,23 +626,36 @@ os_thread_signal_init(os_signal_handler handler)
     }
 #endif
 
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
     memset(&prev_sig_act_SIGSEGV, 0, sizeof(struct sigaction));
     memset(&prev_sig_act_SIGBUS, 0, sizeof(struct sigaction));
+#endif
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+    memset(&prev_sig_act_SIGUSR1, 0, sizeof(struct sigaction));
+#endif
 
     /* Install signal hanlder */
     sig_act.sa_sigaction = signal_callback;
     sig_act.sa_flags = SA_SIGINFO | SA_NODEFER;
-#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
     sig_act.sa_flags |= SA_ONSTACK;
 #endif
     sigemptyset(&sig_act.sa_mask);
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
     if (sigaction(SIGSEGV, &sig_act, &prev_sig_act_SIGSEGV) != 0
         || sigaction(SIGBUS, &sig_act, &prev_sig_act_SIGBUS) != 0) {
         os_printf("Failed to register signal handler\n");
         goto fail3;
     }
+#endif
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+    if (sigaction(SIGUSR1, &sig_act, &prev_sig_act_SIGUSR1) != 0) {
+        os_printf("Failed to register signal handler\n");
+        goto fail3;
+    }
+#endif
 
-#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
     sigalt_stack_base_addr = map_addr;
 #endif
     signal_handler = handler;
@@ -635,7 +663,7 @@ os_thread_signal_init(os_signal_handler handler)
     return 0;
 
 fail3:
-#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
     memset(&sigalt_stack_info, 0, sizeof(stack_t));
     sigalt_stack_info.ss_flags = SS_DISABLE;
     sigalt_stack_info.ss_size = map_size;
@@ -651,14 +679,14 @@ fail1:
 void
 os_thread_signal_destroy()
 {
-#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
     stack_t sigalt_stack_info;
 #endif
 
     if (!thread_signal_inited)
         return;
 
-#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
     /* Disable signal alternate stack */
     memset(&sigalt_stack_info, 0, sizeof(stack_t));
     sigalt_stack_info.ss_flags = SS_DISABLE;
@@ -688,7 +716,7 @@ os_signal_unmask()
 void
 os_sigreturn()
 {
-#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
 #if defined(__APPLE__)
 #define UC_RESET_ALT_STACK 0x80000000
     extern int __sigreturn(void *, int);
@@ -699,4 +727,18 @@ os_sigreturn()
 #endif
 #endif
 }
-#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
+
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+void
+os_thread_set_interruptible(bool flag)
+{
+    sigset_t set;
+    int how = flag ? SIG_UNBLOCK : SIG_BLOCK;
+
+    sigemptyset(&set);
+    sigaddset(&set, SIGUSR1);
+    pthread_sigmask(how, &set, NULL);
+}
+#endif
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */

+ 22 - 13
core/shared/platform/darwin/platform_internal.h

@@ -66,14 +66,6 @@ typedef sem_t korp_sem;
 
 #define bh_socket_t int
 
-#if WASM_DISABLE_BLOCK_INSN_INTERRUPT == 0
-#define OS_ENABLE_BLOCK_INSN_INTERRUPT
-
-typedef void (*os_block_insn_sig_handler)();
-bool
-os_interrupt_block_insn_init(os_block_insn_sig_handler handler);
-#endif /* WASM_DISABLE_BLOCK_INSN_INTERRUPT */
-
 #if WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
@@ -85,7 +77,20 @@ os_interrupt_block_insn_init(os_block_insn_sig_handler handler);
 
 #define os_getpagesize getpagesize
 
-typedef void (*os_signal_handler)(void *sig_addr);
+#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
+#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
+
+#if WASM_ENABLE_INTERRUPT_BLOCK_INSN != 0 && WASM_ENABLE_THREAD_MGR != 0
+#define OS_ENABLE_INTERRUPT_BLOCK_INSN
+#endif
+
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+
+#define OS_SIGSEGV SIGSEGV
+#define OS_SIGBUS SIGBUS
+#define OS_SIGUSR1 SIGUSR1
+
+typedef void (*os_signal_handler)(int sig, void *sig_addr);
 
 int
 os_thread_signal_init(os_signal_handler handler);
@@ -101,15 +106,19 @@ os_signal_unmask();
 
 void
 os_sigreturn();
-#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
-#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
-#if defined(OS_ENABLE_BLOCK_INSN_INTERRUPT) || defined(OS_ENABLE_HW_BOUND_CHECK)
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+void
+os_thread_set_interruptible(bool flag);
+#endif
+
 #include <setjmp.h>
 typedef jmp_buf korp_jmpbuf;
 #define os_setjmp setjmp
 #define os_longjmp longjmp
-#endif
+
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */
 
 #ifdef __cplusplus
 }

+ 22 - 13
core/shared/platform/freebsd/platform_internal.h

@@ -65,14 +65,6 @@ typedef sem_t korp_sem;
 
 #define bh_socket_t int
 
-#if WASM_DISABLE_BLOCK_INSN_INTERRUPT == 0
-#define OS_ENABLE_BLOCK_INSN_INTERRUPT
-
-typedef void (*os_block_insn_sig_handler)();
-bool
-os_interrupt_block_insn_init(os_block_insn_sig_handler handler);
-#endif /* WASM_DISABLE_BLOCK_INSN_INTERRUPT */
-
 #if WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
@@ -84,7 +76,20 @@ os_interrupt_block_insn_init(os_block_insn_sig_handler handler);
 
 #define os_getpagesize getpagesize
 
-typedef void (*os_signal_handler)(void *sig_addr);
+#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
+#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
+
+#if WASM_ENABLE_INTERRUPT_BLOCK_INSN != 0 && WASM_ENABLE_THREAD_MGR != 0
+#define OS_ENABLE_INTERRUPT_BLOCK_INSN
+#endif
+
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+
+#define OS_SIGSEGV SIGSEGV
+#define OS_SIGBUS SIGBUS
+#define OS_SIGUSR1 SIGUSR1
+
+typedef void (*os_signal_handler)(int sig, void *sig_addr);
 
 int
 os_thread_signal_init(os_signal_handler handler);
@@ -100,15 +105,19 @@ os_signal_unmask();
 
 void
 os_sigreturn();
-#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
-#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
-#if defined(OS_ENABLE_BLOCK_INSN_INTERRUPT) || defined(OS_ENABLE_HW_BOUND_CHECK)
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+void
+os_thread_set_interruptible(bool flag);
+#endif
+
 #include <setjmp.h>
 typedef jmp_buf korp_jmpbuf;
 #define os_setjmp setjmp
 #define os_longjmp longjmp
-#endif
+
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */
 
 #ifdef __cplusplus
 }

+ 22 - 13
core/shared/platform/linux/platform_internal.h

@@ -63,14 +63,6 @@ typedef sem_t korp_sem;
 
 #define bh_socket_t int
 
-#if WASM_DISABLE_BLOCK_INSN_INTERRUPT == 0
-#define OS_ENABLE_BLOCK_INSN_INTERRUPT
-
-typedef void (*os_block_insn_sig_handler)();
-bool
-os_interrupt_block_insn_init(os_block_insn_sig_handler handler);
-#endif /* WASM_DISABLE_BLOCK_INSN_INTERRUPT */
-
 #if WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
@@ -82,7 +74,20 @@ os_interrupt_block_insn_init(os_block_insn_sig_handler handler);
 
 #define os_getpagesize getpagesize
 
-typedef void (*os_signal_handler)(void *sig_addr);
+#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
+#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
+
+#if WASM_ENABLE_INTERRUPT_BLOCK_INSN != 0 && WASM_ENABLE_THREAD_MGR != 0
+#define OS_ENABLE_INTERRUPT_BLOCK_INSN
+#endif
+
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+
+#define OS_SIGSEGV SIGSEGV
+#define OS_SIGBUS SIGBUS
+#define OS_SIGUSR1 SIGUSR1
+
+typedef void (*os_signal_handler)(int sig, void *sig_addr);
 
 int
 os_thread_signal_init(os_signal_handler handler);
@@ -98,15 +103,19 @@ os_signal_unmask();
 
 void
 os_sigreturn();
-#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
-#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
-#if defined(OS_ENABLE_BLOCK_INSN_INTERRUPT) || defined(OS_ENABLE_HW_BOUND_CHECK)
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+void
+os_thread_set_interruptible(bool flag);
+#endif
+
 #include <setjmp.h>
 typedef jmp_buf korp_jmpbuf;
 #define os_setjmp setjmp
 #define os_longjmp longjmp
-#endif
+
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */
 
 #ifdef __cplusplus
 }

+ 25 - 15
core/shared/platform/vxworks/platform_internal.h

@@ -60,17 +60,10 @@ typedef sem_t korp_sem;
 
 #define os_thread_local_attribute __thread
 
-#if WASM_DISABLE_BLOCK_INSN_INTERRUPT == 0
-#define OS_ENABLE_BLOCK_INSN_INTERRUPT
-
-typedef void (*os_block_insn_sig_handler)();
-bool
-os_interrupt_block_insn_init(os_block_insn_sig_handler handler);
-#endif /* WASM_DISABLE_BLOCK_INSN_INTERRUPT */
-
 #if WASM_DISABLE_HW_BOUND_CHECK == 0
-#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
-    || defined(BUILD_TARGET_AARCH64)
+#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
+    || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
+    || defined(BUILD_TARGET_RISCV64_LP64)
 
 #define OS_ENABLE_HW_BOUND_CHECK
 
@@ -78,7 +71,20 @@ os_interrupt_block_insn_init(os_block_insn_sig_handler handler);
 
 #define os_getpagesize getpagesize
 
-typedef void (*os_signal_handler)(void *sig_addr);
+#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
+#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
+
+#if WASM_ENABLE_INTERRUPT_BLOCK_INSN != 0 && WASM_ENABLE_THREAD_MGR != 0
+#define OS_ENABLE_INTERRUPT_BLOCK_INSN
+#endif
+
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+
+#define OS_SIGSEGV SIGSEGV
+#define OS_SIGBUS SIGBUS
+#define OS_SIGUSR1 SIGUSR1
+
+typedef void (*os_signal_handler)(int sig, void *sig_addr);
 
 int
 os_thread_signal_init(os_signal_handler handler);
@@ -94,15 +100,19 @@ os_signal_unmask();
 
 void
 os_sigreturn();
-#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64 */
-#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
 
-#if defined(OS_ENABLE_BLOCK_INSN_INTERRUPT) || defined(OS_ENABLE_HW_BOUND_CHECK)
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+void
+os_thread_set_interruptible(bool flag);
+#endif
+
 #include <setjmp.h>
 typedef jmp_buf korp_jmpbuf;
 #define os_setjmp setjmp
 #define os_longjmp longjmp
-#endif
+
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */
 
 #ifdef __cplusplus
 }