main.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_export.h"
  6. #include "bh_platform.h"
  7. #include "bh_read_file.h"
  8. typedef struct thread_arg {
  9. bh_queue *queue;
  10. wasm_module_inst_t module_inst;
  11. } thread_arg;
  12. static void *
  13. thread1_callback(void *arg)
  14. {
  15. thread_arg *targ = arg;
  16. wasm_module_inst_t module_inst = targ->module_inst;
  17. bh_queue *queue = targ->queue;
  18. wasm_exec_env_t exec_env;
  19. wasm_function_inst_t my_shared_heap_malloc_func;
  20. wasm_function_inst_t my_shared_heap_free_func;
  21. uint32 i, argv[2];
  22. /* lookup wasm functions */
  23. if (!(my_shared_heap_malloc_func = wasm_runtime_lookup_function(
  24. module_inst, "my_shared_heap_malloc"))
  25. || !(my_shared_heap_free_func = wasm_runtime_lookup_function(
  26. module_inst, "my_shared_heap_free"))) {
  27. printf("Failed to lookup function.\n");
  28. }
  29. /* create exec env */
  30. if (!(exec_env = wasm_runtime_create_exec_env(module_inst, 32768))) {
  31. printf("Failed to create exec env.\n");
  32. return NULL;
  33. }
  34. /* allocate memory with wasm_runtime_shared_heap_malloc and send it
  35. to wasm app2 */
  36. for (i = 0; i < 5; i++) {
  37. uint8 *buf;
  38. uint64 offset;
  39. offset = wasm_runtime_shared_heap_malloc(module_inst, 1024 * (i + 1),
  40. (void **)&buf);
  41. if (offset == 0) {
  42. printf("Failed to allocate memory from shared heap\n");
  43. break;
  44. }
  45. snprintf(buf, 1024, "Hello, this is buf %u allocated from shared heap",
  46. i + 1);
  47. printf("wasm app1 send buf: %s\n\n", buf);
  48. if (!bh_post_msg(queue, 1, buf, 1024 * (i + 1))) {
  49. printf("Failed to post message to queue\n");
  50. wasm_runtime_shared_heap_free(module_inst, offset);
  51. break;
  52. }
  53. }
  54. /* allocate memory by calling my_shared_heap_malloc function and send it
  55. to wasm app2 */
  56. for (i = 5; i < 10; i++) {
  57. uint8 *buf;
  58. argv[0] = 1024 * (i + 1);
  59. argv[1] = i + 1;
  60. wasm_runtime_call_wasm(exec_env, my_shared_heap_malloc_func, 2, argv);
  61. if (wasm_runtime_get_exception(module_inst)) {
  62. printf("Failed to call 'my_shared_heap_malloc' function: %s\n",
  63. wasm_runtime_get_exception(module_inst));
  64. break;
  65. }
  66. if (argv[0] == 0) {
  67. printf("Failed to allocate memory from shared heap\n");
  68. break;
  69. }
  70. buf = wasm_runtime_addr_app_to_native(module_inst, argv[0]);
  71. printf("wasm app1 send buf: %s\n\n", buf);
  72. if (!bh_post_msg(queue, 1, buf, 1024 * (i + 1))) {
  73. printf("Failed to post message to queue\n");
  74. wasm_runtime_shared_heap_free(module_inst, argv[0]);
  75. break;
  76. }
  77. }
  78. wasm_runtime_destroy_exec_env(exec_env);
  79. return NULL;
  80. }
  81. static void
  82. queue_callback(void *message, void *arg)
  83. {
  84. bh_message_t msg = (bh_message_t)message;
  85. wasm_exec_env_t exec_env = arg;
  86. wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env);
  87. wasm_function_inst_t print_buf_func;
  88. uint32 argv[2];
  89. /* lookup wasm function */
  90. if (!(print_buf_func =
  91. wasm_runtime_lookup_function(module_inst, "print_buf"))) {
  92. printf("Failed to lookup function.\n");
  93. return;
  94. }
  95. char *buf = bh_message_payload(msg);
  96. printf("wasm app's native queue received buf: %s\n\n", buf);
  97. /* call wasm function */
  98. argv[0] = wasm_runtime_addr_native_to_app(module_inst, buf);
  99. wasm_runtime_call_wasm(exec_env, print_buf_func, 1, argv);
  100. if (wasm_runtime_get_exception(module_inst)) {
  101. printf("Failed to call 'print_buf' function: %s\n",
  102. wasm_runtime_get_exception(module_inst));
  103. }
  104. }
  105. static void *
  106. thread2_callback(void *arg)
  107. {
  108. thread_arg *targ = arg;
  109. bh_queue *queue = targ->queue;
  110. wasm_module_inst_t module_inst = targ->module_inst;
  111. wasm_exec_env_t exec_env;
  112. /* create exec env */
  113. if (!(exec_env = wasm_runtime_create_exec_env(module_inst, 32768))) {
  114. printf("Failed to create exec env.\n");
  115. return NULL;
  116. }
  117. /* enter queue's message loop until bh_queue_exit_loop_run
  118. is called */
  119. bh_queue_enter_loop_run(queue, queue_callback, exec_env);
  120. wasm_runtime_destroy_exec_env(exec_env);
  121. return NULL;
  122. }
  123. static char global_heap_buf[512 * 1024];
  124. int
  125. main(int argc, char **argv)
  126. {
  127. char *wasm_file1 = NULL, *wasm_file2 = NULL;
  128. uint8 *wasm_file1_buf = NULL, *wasm_file2_buf = NULL;
  129. uint32 wasm_file1_size, wasm_file2_size;
  130. wasm_module_t wasm_module1 = NULL, wasm_module2 = NULL;
  131. wasm_module_inst_t module_inst1 = NULL;
  132. wasm_module_inst_t module_inst2 = NULL;
  133. wasm_shared_heap_t shared_heap = NULL;
  134. bh_queue *queue = NULL;
  135. RuntimeInitArgs init_args;
  136. SharedHeapInitArgs heap_init_args;
  137. char error_buf[128] = { 0 };
  138. bool aot_mode = false;
  139. int ret = -1;
  140. if (argc > 1 && !strcmp(argv[1], "--aot"))
  141. aot_mode = true;
  142. if (!aot_mode)
  143. printf("Test shared heap in interpreter mode\n\n");
  144. else
  145. printf("Test shared heap in AOT mode\n\n");
  146. memset(&init_args, 0, sizeof(RuntimeInitArgs));
  147. init_args.mem_alloc_type = Alloc_With_Pool;
  148. init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
  149. init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
  150. /* init wasm runtime */
  151. if (!wasm_runtime_full_init(&init_args)) {
  152. printf("Init runtime environment failed.\n");
  153. return -1;
  154. }
  155. /* create queue */
  156. if (!(queue = bh_queue_create())) {
  157. printf("Create queue failed.\n");
  158. goto fail;
  159. }
  160. /* read wasm file */
  161. if (!aot_mode)
  162. wasm_file1 = "./wasm-apps/test1.wasm";
  163. else
  164. wasm_file1 = "./wasm-apps/test1.aot";
  165. if (!(wasm_file1_buf =
  166. bh_read_file_to_buffer(wasm_file1, &wasm_file1_size))) {
  167. printf("Open wasm file %s failed.\n", wasm_file1);
  168. goto fail;
  169. }
  170. /* load wasm file */
  171. wasm_module1 = wasm_runtime_load((uint8 *)wasm_file1_buf, wasm_file1_size,
  172. error_buf, sizeof(error_buf));
  173. if (!wasm_module1) {
  174. printf("Load wasm module failed. error: %s\n", error_buf);
  175. goto fail;
  176. }
  177. /* instantiate module */
  178. module_inst1 = wasm_runtime_instantiate(wasm_module1, 65536, 0, error_buf,
  179. sizeof(error_buf));
  180. if (!module_inst1) {
  181. printf("Instantiate wasm module failed. error: %s\n", error_buf);
  182. goto fail;
  183. }
  184. /* read wasm file */
  185. if (!aot_mode)
  186. wasm_file2 = "./wasm-apps/test2.wasm";
  187. else
  188. wasm_file2 = "./wasm-apps/test2.aot";
  189. if (!(wasm_file2_buf =
  190. bh_read_file_to_buffer(wasm_file2, &wasm_file2_size))) {
  191. printf("Open wasm file %s failed.\n", wasm_file1);
  192. goto fail;
  193. }
  194. /* load wasm file */
  195. wasm_module2 = wasm_runtime_load((uint8 *)wasm_file2_buf, wasm_file2_size,
  196. error_buf, sizeof(error_buf));
  197. if (!wasm_module2) {
  198. printf("Load wasm module failed. error: %s\n", error_buf);
  199. goto fail;
  200. }
  201. /* instantiate module */
  202. module_inst2 = wasm_runtime_instantiate(wasm_module2, 65536, 0, error_buf,
  203. sizeof(error_buf));
  204. if (!module_inst2) {
  205. printf("Instantiate wasm module failed. error: %s\n", error_buf);
  206. goto fail;
  207. }
  208. /* create shared heap */
  209. memset(&heap_init_args, 0, sizeof(heap_init_args));
  210. heap_init_args.size = 65536;
  211. shared_heap = wasm_runtime_create_shared_heap(&heap_init_args);
  212. if (!shared_heap) {
  213. printf("Create shared heap failed.\n");
  214. goto fail;
  215. }
  216. /* attach module instance 1 to the shared heap */
  217. if (!wasm_runtime_attach_shared_heap(module_inst1, shared_heap)) {
  218. printf("Attach shared heap failed.\n");
  219. goto fail;
  220. }
  221. /* attach module instance 2 to the shared heap */
  222. if (!wasm_runtime_attach_shared_heap(module_inst2, shared_heap)) {
  223. printf("Attach shared heap failed.\n");
  224. goto fail;
  225. }
  226. /* create thread 1 */
  227. thread_arg targ1 = { 0 };
  228. korp_tid tid1;
  229. targ1.queue = queue;
  230. targ1.module_inst = module_inst1;
  231. if (os_thread_create(&tid1, thread1_callback, &targ1,
  232. APP_THREAD_STACK_SIZE_DEFAULT)) {
  233. printf("Failed to create thread 1\n");
  234. goto fail;
  235. }
  236. /* create thread 2 */
  237. thread_arg targ2 = { 0 };
  238. korp_tid tid2;
  239. targ2.queue = queue;
  240. targ2.module_inst = module_inst2;
  241. if (os_thread_create(&tid2, thread2_callback, &targ2,
  242. APP_THREAD_STACK_SIZE_DEFAULT)) {
  243. printf("Failed to create thread 2\n");
  244. os_thread_join(tid1, NULL);
  245. goto fail;
  246. }
  247. /* wait until all messages are post to wasm app2 and wasm app2
  248. handles all of them, then exit the queue message loop */
  249. usleep(10000);
  250. bh_queue_exit_loop_run(queue);
  251. os_thread_join(tid1, NULL);
  252. os_thread_join(tid2, NULL);
  253. ret = 0;
  254. fail:
  255. if (module_inst2)
  256. wasm_runtime_deinstantiate(module_inst2);
  257. if (module_inst1)
  258. wasm_runtime_deinstantiate(module_inst1);
  259. if (wasm_module2)
  260. wasm_runtime_unload(wasm_module2);
  261. if (wasm_module1)
  262. wasm_runtime_unload(wasm_module1);
  263. if (wasm_file2_buf)
  264. wasm_runtime_free(wasm_file2_buf);
  265. if (wasm_file1_buf)
  266. wasm_runtime_free(wasm_file1_buf);
  267. if (queue)
  268. bh_queue_destroy(queue);
  269. wasm_runtime_destroy();
  270. return ret;
  271. }