wasm_exec_env.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_exec_env.h"
  6. #include "wasm_runtime_common.h"
  7. #if WASM_ENABLE_THREAD_MGR != 0
  8. #include "../libraries/thread-mgr/thread_manager.h"
  9. #endif
  10. WASMExecEnv *
  11. wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
  12. uint32 stack_size)
  13. {
  14. uint64 total_size = offsetof(WASMExecEnv, wasm_stack.s.bottom)
  15. + (uint64)stack_size;
  16. WASMExecEnv *exec_env;
  17. if (total_size >= UINT32_MAX
  18. || !(exec_env = wasm_runtime_malloc((uint32)total_size)))
  19. return NULL;
  20. memset(exec_env, 0, (uint32)total_size);
  21. #if WASM_ENABLE_AOT != 0
  22. if (!(exec_env->argv_buf = wasm_runtime_malloc(sizeof(uint32) * 64))) {
  23. goto fail1;
  24. }
  25. #endif
  26. #if WASM_ENABLE_THREAD_MGR != 0
  27. if (os_mutex_init(&exec_env->wait_lock) != 0)
  28. goto fail2;
  29. if (os_cond_init(&exec_env->wait_cond) != 0)
  30. goto fail3;
  31. #endif
  32. exec_env->module_inst = module_inst;
  33. exec_env->wasm_stack_size = stack_size;
  34. exec_env->wasm_stack.s.top_boundary =
  35. exec_env->wasm_stack.s.bottom + stack_size;
  36. exec_env->wasm_stack.s.top = exec_env->wasm_stack.s.bottom;
  37. return exec_env;
  38. #if WASM_ENABLE_THREAD_MGR != 0
  39. fail3:
  40. os_mutex_destroy(&exec_env->wait_lock);
  41. fail2:
  42. #endif
  43. #if WASM_ENABLE_AOT != 0
  44. wasm_runtime_free(exec_env->argv_buf);
  45. fail1:
  46. #endif
  47. wasm_runtime_free(exec_env);
  48. return NULL;
  49. }
  50. void
  51. wasm_exec_env_destroy_internal(WASMExecEnv *exec_env)
  52. {
  53. #ifdef OS_ENABLE_HW_BOUND_CHECK
  54. WASMJmpBuf *jmpbuf = exec_env->jmpbuf_stack_top;
  55. WASMJmpBuf *jmpbuf_prev;
  56. while (jmpbuf) {
  57. jmpbuf_prev = jmpbuf->prev;
  58. wasm_runtime_free(jmpbuf);
  59. jmpbuf = jmpbuf_prev;
  60. }
  61. #endif
  62. #if WASM_ENABLE_THREAD_MGR != 0
  63. os_mutex_destroy(&exec_env->wait_lock);
  64. os_cond_destroy(&exec_env->wait_cond);
  65. #endif
  66. #if WASM_ENABLE_AOT != 0
  67. wasm_runtime_free(exec_env->argv_buf);
  68. #endif
  69. wasm_runtime_free(exec_env);
  70. }
  71. WASMExecEnv *
  72. wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst,
  73. uint32 stack_size)
  74. {
  75. WASMExecEnv *exec_env =
  76. wasm_exec_env_create_internal(module_inst, stack_size);
  77. if (!exec_env)
  78. return NULL;
  79. /* Set the aux_stack_boundary to 0 */
  80. exec_env->aux_stack_boundary = 0;
  81. #if WASM_ENABLE_THREAD_MGR != 0
  82. WASMCluster *cluster;
  83. /* Create a new cluster for this exec_env */
  84. cluster = wasm_cluster_create(exec_env);
  85. if (!cluster) {
  86. wasm_exec_env_destroy_internal(exec_env);
  87. return NULL;
  88. }
  89. #endif
  90. return exec_env;
  91. }
  92. void
  93. wasm_exec_env_destroy(WASMExecEnv *exec_env)
  94. {
  95. #if WASM_ENABLE_THREAD_MGR != 0
  96. /* Terminate all sub-threads */
  97. WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
  98. if (cluster) {
  99. wasm_cluster_terminate_all_except_self(cluster, exec_env);
  100. wasm_cluster_del_exec_env(cluster, exec_env);
  101. }
  102. #endif
  103. wasm_exec_env_destroy_internal(exec_env);
  104. }
  105. WASMModuleInstanceCommon *
  106. wasm_exec_env_get_module_inst(WASMExecEnv *exec_env)
  107. {
  108. return exec_env->module_inst;
  109. }
  110. void
  111. wasm_exec_env_set_thread_info(WASMExecEnv *exec_env)
  112. {
  113. exec_env->handle = os_self_thread();
  114. exec_env->native_stack_boundary = os_thread_get_stack_boundary()
  115. + RESERVED_BYTES_TO_NATIVE_STACK_BOUNDARY;
  116. }
  117. #if WASM_ENABLE_THREAD_MGR != 0
  118. void *
  119. wasm_exec_env_get_thread_arg(WASMExecEnv *exec_env)
  120. {
  121. return exec_env->thread_arg;
  122. }
  123. void
  124. wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg)
  125. {
  126. exec_env->thread_arg = thread_arg;
  127. }
  128. #endif
  129. #ifdef OS_ENABLE_HW_BOUND_CHECK
  130. void
  131. wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf)
  132. {
  133. jmpbuf->prev = exec_env->jmpbuf_stack_top;
  134. exec_env->jmpbuf_stack_top = jmpbuf;
  135. }
  136. WASMJmpBuf *
  137. wasm_exec_env_pop_jmpbuf(WASMExecEnv *exec_env)
  138. {
  139. WASMJmpBuf *stack_top = exec_env->jmpbuf_stack_top;
  140. if (stack_top) {
  141. exec_env->jmpbuf_stack_top = stack_top->prev;
  142. return stack_top;
  143. }
  144. return NULL;
  145. }
  146. #endif