thread_manager.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #ifndef _THREAD_MANAGER_H
  6. #define _THREAD_MANAGER_H
  7. #include "bh_common.h"
  8. #include "bh_log.h"
  9. #include "wasm_export.h"
  10. #include "../interpreter/wasm.h"
  11. #include "../common/wasm_runtime_common.h"
  12. #ifdef __cplusplus
  13. extern "C" {
  14. #endif
  15. #if WASM_ENABLE_DEBUG_INTERP != 0
  16. typedef struct WASMDebugInstance WASMDebugInstance;
  17. #endif
  18. struct WASMCluster {
  19. struct WASMCluster *next;
  20. korp_mutex lock;
  21. bh_list exec_env_list;
  22. #if WASM_ENABLE_HEAP_AUX_STACK_ALLOCATION == 0
  23. /* The aux stack of a module with shared memory will be
  24. divided into several segments. This array store the
  25. stack top of different segments */
  26. uint64 *stack_tops;
  27. /* Record which segments are occupied */
  28. bool *stack_segment_occupied;
  29. #endif
  30. /* Size of every stack segment */
  31. uint32 stack_size;
  32. /* When has_exception == true, this cluster should refuse any spawn thread
  33. * requests, this flag can be cleared by calling
  34. * wasm_runtime_clear_exception on instances of any threads of this cluster
  35. */
  36. bool has_exception;
  37. /* When processing is true, this cluster should refuse any spawn thread
  38. * requests. This is a short-lived state, must be cleared immediately once
  39. * the processing finished.
  40. * This is used to avoid dead lock when one thread waiting another thread
  41. * with lock, see wasm_cluster_wait_for_all and wasm_cluster_terminate_all
  42. */
  43. bool processing;
  44. #if WASM_ENABLE_DEBUG_INTERP != 0
  45. WASMDebugInstance *debug_inst;
  46. #endif
  47. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  48. /* When an exception occurs in a thread, the stack frames of that thread are
  49. * saved into the cluster
  50. */
  51. Vector exception_frames;
  52. #endif
  53. };
  54. void
  55. wasm_cluster_set_max_thread_num(uint32 num);
  56. bool
  57. thread_manager_init();
  58. void
  59. thread_manager_destroy();
  60. /* Create cluster */
  61. WASMCluster *
  62. wasm_cluster_create(WASMExecEnv *exec_env);
  63. /* Destroy cluster */
  64. void
  65. wasm_cluster_destroy(WASMCluster *cluster);
  66. /* Get the cluster of the current exec_env */
  67. WASMCluster *
  68. wasm_exec_env_get_cluster(WASMExecEnv *exec_env);
  69. /* Forward registered functions to a new thread */
  70. bool
  71. wasm_cluster_dup_c_api_imports(WASMModuleInstanceCommon *module_inst_dst,
  72. const WASMModuleInstanceCommon *module_inst_src);
  73. int32
  74. wasm_cluster_create_thread(WASMExecEnv *exec_env,
  75. wasm_module_inst_t module_inst,
  76. bool is_aux_stack_allocated, uint64 aux_stack_start,
  77. uint32 aux_stack_size,
  78. void *(*thread_routine)(void *), void *arg);
  79. int32
  80. wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val);
  81. int32
  82. wasm_cluster_detach_thread(WASMExecEnv *exec_env);
  83. int32
  84. wasm_cluster_cancel_thread(WASMExecEnv *exec_env);
  85. void
  86. wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval);
  87. bool
  88. wasm_cluster_register_destroy_callback(void (*callback)(WASMCluster *));
  89. void
  90. wasm_cluster_cancel_all_callbacks();
  91. void
  92. wasm_cluster_suspend_all(WASMCluster *cluster);
  93. void
  94. wasm_cluster_suspend_all_except_self(WASMCluster *cluster,
  95. WASMExecEnv *exec_env);
  96. void
  97. wasm_cluster_suspend_thread(WASMExecEnv *exec_env);
  98. void
  99. wasm_cluster_resume_thread(WASMExecEnv *exec_env);
  100. void
  101. wasm_cluster_resume_all(WASMCluster *cluster);
  102. void
  103. wasm_cluster_terminate_all(WASMCluster *cluster);
  104. void
  105. wasm_cluster_terminate_all_except_self(WASMCluster *cluster,
  106. WASMExecEnv *exec_env);
  107. void
  108. wasm_cluster_wait_for_all(WASMCluster *cluster);
  109. void
  110. wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
  111. WASMExecEnv *exec_env);
  112. bool
  113. wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env);
  114. WASMExecEnv *
  115. wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst);
  116. void
  117. wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception);
  118. WASMExecEnv *
  119. wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env);
  120. void
  121. wasm_cluster_destroy_spawned_exec_env(WASMExecEnv *exec_env);
  122. void
  123. wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
  124. void *custom_data);
  125. void
  126. wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key,
  127. void *ctx);
  128. bool
  129. wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env);
  130. #if WASM_ENABLE_DEBUG_INTERP != 0
  131. #define WAMR_SIG_TRAP (5)
  132. #define WAMR_SIG_STOP (19)
  133. #define WAMR_SIG_TERM (15)
  134. #define WAMR_SIG_SINGSTEP (0x1ff)
  135. #define STATUS_RUNNING (0)
  136. #define STATUS_STOP (1)
  137. #define STATUS_EXIT (2)
  138. #define STATUS_STEP (3)
  139. #define IS_WAMR_TERM_SIG(signo) ((signo) == WAMR_SIG_TERM)
  140. #define IS_WAMR_STOP_SIG(signo) \
  141. ((signo) == WAMR_SIG_STOP || (signo) == WAMR_SIG_TRAP)
  142. struct WASMCurrentEnvStatus {
  143. uint32 signal_flag;
  144. uint16 step_count;
  145. uint16 running_status;
  146. };
  147. WASMCurrentEnvStatus *
  148. wasm_cluster_create_exenv_status();
  149. void
  150. wasm_cluster_destroy_exenv_status(WASMCurrentEnvStatus *status);
  151. void
  152. wasm_cluster_send_signal_all(WASMCluster *cluster, uint32 signo);
  153. /* This function must be called with exec_env->wait_lock locked, otherwise we
  154. * may miss the signal from debugger thread, see
  155. * https://github.com/bytecodealliance/wasm-micro-runtime/issues/1860 */
  156. void
  157. wasm_cluster_thread_waiting_run(WASMExecEnv *exec_env);
  158. void
  159. wasm_cluster_wait_thread_status(WASMExecEnv *exec_env, uint32 *status);
  160. void
  161. wasm_cluster_thread_exited(WASMExecEnv *exec_env);
  162. void
  163. wasm_cluster_thread_continue(WASMExecEnv *exec_env);
  164. void
  165. wasm_cluster_thread_send_signal(WASMExecEnv *exec_env, uint32 signo);
  166. void
  167. wasm_cluster_thread_step(WASMExecEnv *exec_env);
  168. void
  169. wasm_cluster_set_debug_inst(WASMCluster *cluster, WASMDebugInstance *inst);
  170. #endif /* end of WASM_ENABLE_DEBUG_INTERP != 0 */
  171. void
  172. wasm_cluster_traverse_lock(WASMExecEnv *exec_env);
  173. void
  174. wasm_cluster_traverse_unlock(WASMExecEnv *exec_env);
  175. bool
  176. wasm_cluster_allocate_aux_stack(WASMExecEnv *exec_env, uint64 *p_start,
  177. uint32 *p_size);
  178. bool
  179. wasm_cluster_free_aux_stack(WASMExecEnv *exec_env, uint64 start);
  180. #ifdef __cplusplus
  181. }
  182. #endif
  183. #endif /* end of _THREAD_MANAGER_H */