Przeglądaj źródła

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 3 lat temu
rodzic
commit
ed98d8805d

+ 3 - 3
build-scripts/config_common.cmake

@@ -248,9 +248,9 @@ else ()
     add_definitions (-DWASM_DISABLE_STACK_HW_BOUND_CHECK=0)
     add_definitions (-DWASM_DISABLE_STACK_HW_BOUND_CHECK=0)
   endif ()
   endif ()
 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 ()
 endif ()
 if (WAMR_BUILD_SIMD EQUAL 1)
 if (WAMR_BUILD_SIMD EQUAL 1)
   if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*")
   if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*")

+ 3 - 3
core/config.h

@@ -266,11 +266,11 @@
 #define WASM_DISABLE_STACK_HW_BOUND_CHECK 0
 #define WASM_DISABLE_STACK_HW_BOUND_CHECK 0
 #endif
 #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
  * (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
 #endif
 
 
 /* Disable SIMD unless it is manualy enabled somewhere */
 /* 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;
         return false;
     }
     }
 
 
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 0;
+#endif
     wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
     wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
-
     wasm_runtime_set_exec_env_tls(exec_env);
     wasm_runtime_set_exec_env_tls(exec_env);
+
     if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
     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 */
         /* Quick call with func_ptr if the function signature is simple */
         if (!signature && param_count == 1 && types[0] == VALUE_TYPE_I32) {
         if (!signature && param_count == 1 && types[0] == VALUE_TYPE_I32) {
             if (result_count == 0) {
             if (result_count == 0) {
@@ -1321,6 +1327,10 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
         ret = false;
         ret = false;
     }
     }
 
 
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 0;
+#endif
+
     jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
     jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
     bh_assert(&jmpbuf_node == jmpbuf_node_pop);
     bh_assert(&jmpbuf_node == jmpbuf_node_pop);
     if (!exec_env->jmpbuf_stack_top) {
     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_sigreturn();
         os_signal_unmask();
         os_signal_unmask();
     }
     }
+
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 1;
+#endif
     (void)jmpbuf_node_pop;
     (void)jmpbuf_node_pop;
     return ret;
     return ret;
 }
 }
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 #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
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #define invoke_native_internal invoke_native_with_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
 #define invoke_native_internal wasm_runtime_invoke_native
 #endif
 #endif
 
 
-#else /* else of OS_ENABLE_BLOCK_INSN_INTERRUPT */
+#else /* else of OS_ENABLE_INTERRUPT_BLOCK_INSN */
 
 
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #define invoke_native_block_insn_interrupt invoke_native_with_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,
                        void *attachment, uint32 *argv, uint32 argc,
                        uint32 *argv_ret)
                        uint32 *argv_ret)
 {
 {
-    int ret = false;
+    bool ret;
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
     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);
     wasm_runtime_set_exec_env_tls(exec_env);
 
 
     if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
     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,
         ret = invoke_native_block_insn_interrupt(exec_env, func_ptr, func_type,
                                                  signature, attachment, argv,
                                                  signature, attachment, argv,
                                                  argc, argv_ret);
                                                  argc, argv_ret);
     }
     }
     else {
     else {
+        /* Exception has been set in signal handler before calling longjmp */
         ret = false;
         ret = false;
     }
     }
 
 
+    exec_env->canjump = 0;
     jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
     jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
     bh_assert(&jmpbuf_node == jmpbuf_node_pop);
     bh_assert(&jmpbuf_node == jmpbuf_node_pop);
     if (!exec_env->jmpbuf_stack_top) {
     if (!exec_env->jmpbuf_stack_top) {
         wasm_runtime_set_exec_env_tls(NULL);
         wasm_runtime_set_exec_env_tls(NULL);
     }
     }
-
+    if (!ret) {
+        os_sigreturn();
+        os_signal_unmask();
+    }
+    exec_env->canjump = 1;
+    (void)jmpbuf_node_pop;
     return ret;
     return ret;
 }
 }
-#endif /* end of OS_ENABLE_BLOCK_INSN_INTERRUPT */
+#endif /* end of OS_ENABLE_INTERRUPT_BLOCK_INSN */
 
 
 bool
 bool
 aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
 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;
     WASMExecEnv *exec_env = NULL, *existing_exec_env = NULL;
     bool ret;
     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();
     existing_exec_env = exec_env = wasm_runtime_get_exec_env_tls();
 #elif WASM_ENABLE_THREAD_MGR != 0
 #elif WASM_ENABLE_THREAD_MGR != 0
     existing_exec_env = exec_env =
     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
 #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
 void
 wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf)
 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
 #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 {
 typedef struct WASMJmpBuf {
     struct WASMJmpBuf *prev;
     struct WASMJmpBuf *prev;
     korp_jmpbuf jmpbuf;
     korp_jmpbuf jmpbuf;
@@ -120,6 +120,12 @@ typedef struct WASMExecEnv {
 
 
     /* whether current thread is detached */
     /* whether current thread is detached */
     bool 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
 #endif
 
 
 #if WASM_ENABLE_DEBUG_INTERP != 0
 #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];
     BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
 #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)
     WASMJmpBuf *jmpbuf_stack_top;
     WASMJmpBuf *jmpbuf_stack_top;
 #endif
 #endif
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #ifdef OS_ENABLE_HW_BOUND_CHECK
@@ -303,7 +309,7 @@ void
 wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg);
 wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg);
 #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)
 void
 void
 wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf);
 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;
 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
 /* The exec_env of thread local storage, set before calling function
    and used in signal handler, as we cannot get it from the argument
    and used in signal handler, as we cannot get it from the argument
    of signal handler */
    of signal handler */
 static os_thread_local_attribute WASMExecEnv *exec_env_tls = NULL;
 static os_thread_local_attribute WASMExecEnv *exec_env_tls = NULL;
-#endif
 
 
-#ifdef OS_ENABLE_HW_BOUND_CHECK
 #ifndef BH_PLATFORM_WINDOWS
 #ifndef BH_PLATFORM_WINDOWS
+
+#ifdef OS_ENABLE_HW_BOUND_CHECK
 static void
 static void
-runtime_signal_handler(void *sig_addr)
+hw_bound_check_sig_handler(void *sig_addr)
 {
 {
     WASMModuleInstance *module_inst;
     WASMModuleInstance *module_inst;
     WASMMemoryInstance *memory_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
 static LONG
 runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
 runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
 {
 {
@@ -284,6 +315,7 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
               sig_addr);
               sig_addr);
     return EXCEPTION_CONTINUE_SEARCH;
     return EXCEPTION_CONTINUE_SEARCH;
 }
 }
+
 #endif /* end of BH_PLATFORM_WINDOWS */
 #endif /* end of BH_PLATFORM_WINDOWS */
 
 
 static bool
 static bool
@@ -311,9 +343,7 @@ runtime_signal_destroy()
 #endif
 #endif
     os_thread_signal_destroy();
     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
 void
 wasm_runtime_set_exec_env_tls(WASMExecEnv *exec_env)
 wasm_runtime_set_exec_env_tls(WASMExecEnv *exec_env)
 {
 {
@@ -325,20 +355,8 @@ wasm_runtime_get_exec_env_tls()
 {
 {
     return 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
 static bool
 wasm_runtime_env_init()
 wasm_runtime_env_init()
@@ -371,12 +389,7 @@ wasm_runtime_env_init()
         goto fail5;
         goto fail5;
     }
     }
 #endif
 #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()) {
     if (!runtime_signal_init()) {
         goto fail6;
         goto fail6;
     }
     }
@@ -431,10 +444,8 @@ fail8:
 fail7:
 fail7:
 #endif
 #endif
 #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();
     runtime_signal_destroy();
-#endif
 fail6:
 fail6:
 #endif
 #endif
 #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_THREAD_MGR != 0)
 #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_THREAD_MGR != 0)
@@ -494,7 +505,7 @@ wasm_runtime_destroy()
 #endif
 #endif
 #endif
 #endif
 
 
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     runtime_signal_destroy();
     runtime_signal_destroy();
 #endif
 #endif
 
 
@@ -1333,7 +1344,7 @@ wasm_runtime_init_thread_env(void)
         return false;
         return false;
 #endif
 #endif
 
 
-#ifdef OS_ENABLE_HW_BOUND_CHECK
+#if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
     if (!runtime_signal_init()) {
     if (!runtime_signal_init()) {
 #ifdef BH_PLATFORM_WINDOWS
 #ifdef BH_PLATFORM_WINDOWS
         os_thread_env_destroy();
         os_thread_env_destroy();
@@ -1348,7 +1359,7 @@ wasm_runtime_init_thread_env(void)
 void
 void
 wasm_runtime_destroy_thread_env(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();
     runtime_signal_destroy();
 #endif
 #endif
 
 
@@ -1365,11 +1376,9 @@ wasm_runtime_thread_env_inited(void)
         return false;
         return false;
 #endif
 #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())
     if (!os_thread_signal_inited())
         return false;
         return false;
-#endif
 #endif
 #endif
     return true;
     return true;
 }
 }
@@ -2346,6 +2355,13 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
             (WASMModuleInstanceCommon *)module_inst);
             (WASMModuleInstanceCommon *)module_inst);
     }
     }
 #endif
 #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
 #else
     (void)exec_env;
     (void)exec_env;
 #endif
 #endif

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

@@ -435,7 +435,7 @@ typedef struct WASMSignalInfo {
 } WASMSignalInfo;
 } WASMSignalInfo;
 #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)
 /* Set exec_env of thread local storage */
 /* Set exec_env of thread local storage */
 void
 void
 wasm_runtime_set_exec_env_tls(WASMExecEnv *exec_env);
 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;
         return;
     }
     }
 
 
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 0;
+#endif
     wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
     wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
-
     wasm_runtime_set_exec_env_tls(exec_env);
     wasm_runtime_set_exec_env_tls(exec_env);
+
     if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
     if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+        exec_env->canjump = 1;
+#endif
 #ifndef BH_PLATFORM_WINDOWS
 #ifndef BH_PLATFORM_WINDOWS
         wasm_interp_call_wasm(module_inst, exec_env, function, argc, argv);
         wasm_interp_call_wasm(module_inst, exec_env, function, argc, argv);
 #else
 #else
@@ -2293,6 +2299,10 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
         ret = false;
         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
     /* Note: can't check wasm_get_exception(module_inst) here, there may be
      * exception which is not caught by hardware (e.g. uninitialized elements),
      * exception which is not caught by hardware (e.g. uninitialized elements),
      * then the stack-frame is already freed inside wasm_interp_call_wasm */
      * 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_sigreturn();
         os_signal_unmask();
         os_signal_unmask();
     }
     }
+
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+    exec_env->canjump = 1;
+#endif
     (void)jmpbuf_node_pop;
     (void)jmpbuf_node_pop;
 }
 }
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 #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
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #define interp_call_wasm call_wasm_with_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
 #define interp_call_wasm wasm_interp_call_wasm
 #endif
 #endif
 
 
-#else /* else of OS_ENABLE_BLOCK_INSN_INTERRUPT */
+#else /* else of OS_ENABLE_INTERRUPT_BLOCK_INSN */
 
 
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #ifdef OS_ENABLE_HW_BOUND_CHECK
 #define call_wasm_block_insn_interrupt call_wasm_with_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[])
                  WASMFunctionInstance *function, unsigned argc, uint32 argv[])
 {
 {
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
+    bool ret;
+
+    exec_env->canjump = 0;
     wasm_runtime_set_exec_env_tls(exec_env);
     wasm_runtime_set_exec_env_tls(exec_env);
+    wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
 
 
     if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
     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,
         call_wasm_block_insn_interrupt(module_inst, exec_env, function, argc,
                                        argv);
                                        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);
     jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
     bh_assert(&jmpbuf_node == jmpbuf_node_pop);
     bh_assert(&jmpbuf_node == jmpbuf_node_pop);
     if (!exec_env->jmpbuf_stack_top) {
     if (!exec_env->jmpbuf_stack_top) {
         wasm_runtime_set_exec_env_tls(NULL);
         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
 bool
 wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
 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;
     WASMExecEnv *exec_env = NULL, *existing_exec_env = NULL;
     bool ret;
     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();
     existing_exec_env = exec_env = wasm_runtime_get_exec_env_tls();
 #elif WASM_ENABLE_THREAD_MGR != 0
 #elif WASM_ENABLE_THREAD_MGR != 0
     existing_exec_env = exec_env =
     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;
     ThreadInfoNode *info_node = routine_args->info_node;
     uint32 argv[1];
     uint32 argv[1];
 
 
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+    os_thread_set_interruptible(false);
+#endif
+
     parent_exec_env = info_node->parent_exec_env;
     parent_exec_env = info_node->parent_exec_env;
     os_mutex_lock(&parent_exec_env->wait_lock);
     os_mutex_lock(&parent_exec_env->wait_lock);
     info_node->exec_env = exec_env;
     info_node->exec_env = exec_env;
@@ -518,10 +522,16 @@ pthread_start_routine(void *arg)
     wasm_exec_env_set_thread_info(exec_env);
     wasm_exec_env_set_thread_info(exec_env);
     argv[0] = routine_args->arg;
     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,
     if (!wasm_runtime_call_indirect(exec_env, routine_args->elem_index, 1,
                                     argv)) {
                                     argv)) {
         /* Exception has already been spread during throwing */
         /* Exception has already been spread during throwing */
     }
     }
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+    os_thread_set_interruptible(false);
+#endif
 
 
     /* destroy pthread key values */
     /* destroy pthread key values */
     call_key_destructor(exec_env);
     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();
     exec_env->handle = os_self_thread();
     ret = exec_env->thread_start_routine(exec_env);
     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)
     if (exec_env->suspend_flags.flags & 0x08)
         ret = exec_env->thread_ret_value;
         ret = exec_env->thread_ret_value;
 #endif
 #endif
@@ -821,7 +821,7 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
 {
 {
     WASMCluster *cluster;
     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) {
     if (exec_env->jmpbuf_stack_top) {
         /* Store the return value in exec_env */
         /* Store the return value in exec_env */
         exec_env->thread_ret_value = retval;
         exec_env->thread_ret_value = retval;
@@ -969,6 +969,30 @@ wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
     os_mutex_unlock(&cluster->lock);
     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
 bool
 wasm_cluster_register_destroy_callback(void (*callback)(WASMCluster *))
 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),
                     sizeof(curr_wasm_inst->cur_exception),
                     wasm_inst->cur_exception, sizeof(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 */
         /* Terminate the thread so it can exit from dead loops */
         set_thread_cancel_flags(curr_exec_env);
         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,
 wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
                                       WASMExecEnv *exec_env);
                                       WASMExecEnv *exec_env);
 
 
+#ifdef OS_ENABLE_INTERRUPT_BLOCK_INSN
+void
+wasm_cluster_kill_all_except_self(WASMCluster *cluster, WASMExecEnv *exec_env);
+#endif
+
 bool
 bool
 wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env);
 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
 #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 WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
     || 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
 #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
 int
 os_thread_signal_init(os_signal_handler handler);
 os_thread_signal_init(os_signal_handler handler);
@@ -98,15 +103,19 @@ os_signal_unmask();
 
 
 void
 void
 os_sigreturn();
 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>
 #include <setjmp.h>
 typedef jmp_buf korp_jmpbuf;
 typedef jmp_buf korp_jmpbuf;
 #define os_setjmp setjmp
 #define os_setjmp setjmp
 #define os_longjmp longjmp
 #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;
 typedef long int __syscall_slong_t;
 
 

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

@@ -12,12 +12,12 @@
 typedef struct {
 typedef struct {
     thread_start_routine_t start;
     thread_start_routine_t start;
     void *arg;
     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;
     os_signal_handler signal_handler;
 #endif
 #endif
 } thread_wrapper_arg;
 } 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() */
 /* The signal handler passed to os_thread_signal_init() */
 static os_thread_local_attribute os_signal_handler signal_handler;
 static os_thread_local_attribute os_signal_handler signal_handler;
 #endif
 #endif
@@ -28,7 +28,7 @@ os_thread_wrapper(void *arg)
     thread_wrapper_arg *targ = arg;
     thread_wrapper_arg *targ = arg;
     thread_start_routine_t start_func = targ->start;
     thread_start_routine_t start_func = targ->start;
     void *thread_arg = targ->arg;
     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;
     os_signal_handler handler = targ->signal_handler;
 #endif
 #endif
 
 
@@ -36,12 +36,12 @@ os_thread_wrapper(void *arg)
     os_printf("THREAD CREATED %jx\n", (uintmax_t)(uintptr_t)pthread_self());
     os_printf("THREAD CREATED %jx\n", (uintmax_t)(uintptr_t)pthread_self());
 #endif
 #endif
     BH_FREE(targ);
     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)
     if (os_thread_signal_init(handler) != 0)
         return NULL;
         return NULL;
 #endif
 #endif
     start_func(thread_arg);
     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();
     os_thread_signal_destroy();
 #endif
 #endif
     return NULL;
     return NULL;
@@ -75,7 +75,7 @@ os_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
 
 
     targ->start = start;
     targ->start = start;
     targ->arg = arg;
     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;
     targ->signal_handler = signal_handler;
 #endif
 #endif
 
 
@@ -340,7 +340,7 @@ os_thread_detach(korp_tid thread)
 void
 void
 os_thread_exit(void *retval)
 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();
     os_thread_signal_destroy();
 #endif
 #endif
     return pthread_exit(retval);
     return pthread_exit(retval);
@@ -420,26 +420,7 @@ os_thread_get_stack_boundary()
     return addr;
     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:
  * 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;
 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 */
 /* The signal alternate stack base addr */
 static os_thread_local_attribute uint8 *sigalt_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,
     os_mprotect(stack_min_addr, page_size * guard_page_count,
                 MMAP_PROT_READ | MMAP_PROT_WRITE);
                 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
 static void
 mask_signals(int how)
 mask_signals(int how)
@@ -520,13 +505,23 @@ mask_signals(int how)
     sigset_t set;
     sigset_t set;
 
 
     sigemptyset(&set);
     sigemptyset(&set);
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
     sigaddset(&set, SIGSEGV);
     sigaddset(&set, SIGSEGV);
     sigaddset(&set, SIGBUS);
     sigaddset(&set, SIGBUS);
+#endif
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+    sigaddset(&set, SIGUSR1);
+#endif
     pthread_sigmask(how, &set, NULL);
     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_SIGSEGV;
 static os_thread_local_attribute struct sigaction prev_sig_act_SIGBUS;
 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
 static void
 signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext)
 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);
     mask_signals(SIG_BLOCK);
 
 
     /* Try to handle signal with the registered signal handler */
     /* 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)
     if (sig_num == SIGSEGV)
         prev_sig_act = &prev_sig_act_SIGSEGV;
         prev_sig_act = &prev_sig_act_SIGSEGV;
     else if (sig_num == SIGBUS)
     else if (sig_num == SIGBUS)
         prev_sig_act = &prev_sig_act_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 */
     /* Forward the signal to next handler if found */
     if (prev_sig_act && (prev_sig_act->sa_flags & SA_SIGINFO)) {
     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 */
     /* Output signal info and then crash if signal is unhandled */
     else {
     else {
         switch (sig_num) {
         switch (sig_num) {
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
             case SIGSEGV:
             case SIGSEGV:
                 os_printf("unhandled SIGSEGV, si_addr: %p\n", sig_addr);
                 os_printf("unhandled SIGSEGV, si_addr: %p\n", sig_addr);
                 break;
                 break;
             case SIGBUS:
             case SIGBUS:
                 os_printf("unhandled SIGBUS, si_addr: %p\n", sig_addr);
                 os_printf("unhandled SIGBUS, si_addr: %p\n", sig_addr);
                 break;
                 break;
+#endif
+#if defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
+            case SIGUSR1:
+                os_printf("unhandled SIGUSR1, si_addr: %p\n", sig_addr);
+                break;
+#endif
             default:
             default:
                 os_printf("unhandle signal %d, si_addr: %p\n", sig_num,
                 os_printf("unhandle signal %d, si_addr: %p\n", sig_num,
                           sig_addr);
                           sig_addr);
@@ -578,7 +593,7 @@ int
 os_thread_signal_init(os_signal_handler handler)
 os_thread_signal_init(os_signal_handler handler)
 {
 {
     struct sigaction sig_act;
     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;
     stack_t sigalt_stack_info;
     uint32 map_size = SIG_ALT_STACK_SIZE;
     uint32 map_size = SIG_ALT_STACK_SIZE;
     uint8 *map_addr;
     uint8 *map_addr;
@@ -587,7 +602,7 @@ os_thread_signal_init(os_signal_handler handler)
     if (thread_signal_inited)
     if (thread_signal_inited)
         return 0;
         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()) {
     if (!init_stack_guard_pages()) {
         os_printf("Failed to init stack guard pages\n");
         os_printf("Failed to init stack guard pages\n");
         return -1;
         return -1;
@@ -611,23 +626,36 @@ os_thread_signal_init(os_signal_handler handler)
     }
     }
 #endif
 #endif
 
 
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
     memset(&prev_sig_act_SIGSEGV, 0, sizeof(struct sigaction));
     memset(&prev_sig_act_SIGSEGV, 0, sizeof(struct sigaction));
     memset(&prev_sig_act_SIGBUS, 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 */
     /* Install signal hanlder */
     sig_act.sa_sigaction = signal_callback;
     sig_act.sa_sigaction = signal_callback;
     sig_act.sa_flags = SA_SIGINFO | SA_NODEFER;
     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;
     sig_act.sa_flags |= SA_ONSTACK;
 #endif
 #endif
     sigemptyset(&sig_act.sa_mask);
     sigemptyset(&sig_act.sa_mask);
+#if defined(OS_ENABLE_HW_BOUND_CHECK)
     if (sigaction(SIGSEGV, &sig_act, &prev_sig_act_SIGSEGV) != 0
     if (sigaction(SIGSEGV, &sig_act, &prev_sig_act_SIGSEGV) != 0
         || sigaction(SIGBUS, &sig_act, &prev_sig_act_SIGBUS) != 0) {
         || sigaction(SIGBUS, &sig_act, &prev_sig_act_SIGBUS) != 0) {
         os_printf("Failed to register signal handler\n");
         os_printf("Failed to register signal handler\n");
         goto fail3;
         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;
     sigalt_stack_base_addr = map_addr;
 #endif
 #endif
     signal_handler = handler;
     signal_handler = handler;
@@ -635,7 +663,7 @@ os_thread_signal_init(os_signal_handler handler)
     return 0;
     return 0;
 
 
 fail3:
 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));
     memset(&sigalt_stack_info, 0, sizeof(stack_t));
     sigalt_stack_info.ss_flags = SS_DISABLE;
     sigalt_stack_info.ss_flags = SS_DISABLE;
     sigalt_stack_info.ss_size = map_size;
     sigalt_stack_info.ss_size = map_size;
@@ -651,14 +679,14 @@ fail1:
 void
 void
 os_thread_signal_destroy()
 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;
     stack_t sigalt_stack_info;
 #endif
 #endif
 
 
     if (!thread_signal_inited)
     if (!thread_signal_inited)
         return;
         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 */
     /* Disable signal alternate stack */
     memset(&sigalt_stack_info, 0, sizeof(stack_t));
     memset(&sigalt_stack_info, 0, sizeof(stack_t));
     sigalt_stack_info.ss_flags = SS_DISABLE;
     sigalt_stack_info.ss_flags = SS_DISABLE;
@@ -688,7 +716,7 @@ os_signal_unmask()
 void
 void
 os_sigreturn()
 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__)
 #if defined(__APPLE__)
 #define UC_RESET_ALT_STACK 0x80000000
 #define UC_RESET_ALT_STACK 0x80000000
     extern int __sigreturn(void *, int);
     extern int __sigreturn(void *, int);
@@ -699,4 +727,18 @@ os_sigreturn()
 #endif
 #endif
 #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
 #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 WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
     || 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
 #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
 int
 os_thread_signal_init(os_signal_handler handler);
 os_thread_signal_init(os_signal_handler handler);
@@ -101,15 +106,19 @@ os_signal_unmask();
 
 
 void
 void
 os_sigreturn();
 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>
 #include <setjmp.h>
 typedef jmp_buf korp_jmpbuf;
 typedef jmp_buf korp_jmpbuf;
 #define os_setjmp setjmp
 #define os_setjmp setjmp
 #define os_longjmp longjmp
 #define os_longjmp longjmp
-#endif
+
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */
 
 
 #ifdef __cplusplus
 #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
 #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 WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
     || 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
 #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
 int
 os_thread_signal_init(os_signal_handler handler);
 os_thread_signal_init(os_signal_handler handler);
@@ -100,15 +105,19 @@ os_signal_unmask();
 
 
 void
 void
 os_sigreturn();
 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>
 #include <setjmp.h>
 typedef jmp_buf korp_jmpbuf;
 typedef jmp_buf korp_jmpbuf;
 #define os_setjmp setjmp
 #define os_setjmp setjmp
 #define os_longjmp longjmp
 #define os_longjmp longjmp
-#endif
+
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */
 
 
 #ifdef __cplusplus
 #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
 #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 WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
     || 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
 #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
 int
 os_thread_signal_init(os_signal_handler handler);
 os_thread_signal_init(os_signal_handler handler);
@@ -98,15 +103,19 @@ os_signal_unmask();
 
 
 void
 void
 os_sigreturn();
 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>
 #include <setjmp.h>
 typedef jmp_buf korp_jmpbuf;
 typedef jmp_buf korp_jmpbuf;
 #define os_setjmp setjmp
 #define os_setjmp setjmp
 #define os_longjmp longjmp
 #define os_longjmp longjmp
-#endif
+
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */
 
 
 #ifdef __cplusplus
 #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
 #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 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
 #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
 #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
 int
 os_thread_signal_init(os_signal_handler handler);
 os_thread_signal_init(os_signal_handler handler);
@@ -94,15 +100,19 @@ os_signal_unmask();
 
 
 void
 void
 os_sigreturn();
 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>
 #include <setjmp.h>
 typedef jmp_buf korp_jmpbuf;
 typedef jmp_buf korp_jmpbuf;
 #define os_setjmp setjmp
 #define os_setjmp setjmp
 #define os_longjmp longjmp
 #define os_longjmp longjmp
-#endif
+
+#endif /* end of defined(OS_ENABLE_HW_BOUND_CHECK) || \
+          defined(OS_ENABLE_INTERRUPT_BLOCK_INSN) */
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }