diff --git a/samples/terminate/CMakeLists.txt b/samples/terminate/CMakeLists.txt index d9b5a053d..246b835dd 100644 --- a/samples/terminate/CMakeLists.txt +++ b/samples/terminate/CMakeLists.txt @@ -45,6 +45,7 @@ if (NOT CMAKE_BUILD_TYPE) endif () set (WAMR_BUILD_LIBC_WASI 1) +set (WAMR_BUILD_LIB_WASI_THREADS 1) set (WAMR_BUILD_THREAD_MGR 1) set (WAMR_BUILD_INTERP 1) set (WAMR_BUILD_AOT 1) diff --git a/samples/terminate/src/main.c b/samples/terminate/src/main.c index 2dca37f68..4885b0b11 100644 --- a/samples/terminate/src/main.c +++ b/samples/terminate/src/main.c @@ -21,7 +21,7 @@ print_usage(void) } static void * -runner(void *vp) +runner_with_sigleton_exec_env(void *vp) { wasm_module_inst_t inst = vp; bool ok = wasm_runtime_init_thread_env(); @@ -31,6 +31,22 @@ runner(void *vp) return inst; } +static void * +runner_with_spawn_exec_env(void *vp) +{ + wasm_exec_env_t env = vp; + wasm_module_inst_t inst = wasm_runtime_get_module_inst(env); + wasm_function_inst_t func; + bool ok = wasm_runtime_init_thread_env(); + assert(ok); + func = wasm_runtime_lookup_function(inst, "block_forever", NULL); + assert(func != NULL); + wasm_runtime_call_wasm(env, func, 0, NULL); + wasm_runtime_destroy_spawned_exec_env(env); + wasm_runtime_destroy_thread_env(); + return inst; +} + int main(int argc, char *argv_main[]) { @@ -108,6 +124,9 @@ main(int argc, char *argv_main[]) pipe_fds[0], -1, -1); for (i = 0; i < N; i++) { + bool use_wasm_runtime_spawn_exec_env = i / 2 == 0; + wasm_exec_env_t env; + module_inst[i] = wasm_runtime_instantiate(module, stack_size, heap_size, error_buf, sizeof(error_buf)); @@ -119,17 +138,33 @@ main(int argc, char *argv_main[]) /* Note: ensure that module inst has an exec env so that * it can receive the termination request. */ - wasm_runtime_get_exec_env_singleton(module_inst[i]); + env = wasm_runtime_get_exec_env_singleton(module_inst[i]); + assert(env != NULL); + if (use_wasm_runtime_spawn_exec_env) { + env = wasm_runtime_spawn_exec_env(env); + assert(env != NULL); + } if ((i % 2) == 0) { printf("terminating thread %u before starting\n", i); wasm_runtime_terminate(module_inst[i]); } - printf("starting thread %u\n", i); - ret = pthread_create(&th[i], NULL, runner, module_inst[i]); - if (ret != 0) { - goto fail; + if (use_wasm_runtime_spawn_exec_env) { + printf("starting thread %u (spawn_exec_env)\n", i); + ret = pthread_create(&th[i], NULL, runner_with_spawn_exec_env, env); + if (ret != 0) { + wasm_runtime_destroy_spawned_exec_env(env); + goto fail; + } + } + else { + printf("starting thread %u (singleton exec_env)\n", i); + ret = pthread_create(&th[i], NULL, runner_with_sigleton_exec_env, + module_inst[i]); + if (ret != 0) { + goto fail; + } } } @@ -148,6 +183,7 @@ main(int argc, char *argv_main[]) void *status; ret = pthread_join(th[i], &status); if (ret != 0) { + printf("pthread_join failed for thread %u\n", i); goto fail; } } diff --git a/samples/terminate/wasm-apps/testapp.wat b/samples/terminate/wasm-apps/testapp.wat index 0b75a7c62..349535da7 100644 --- a/samples/terminate/wasm-apps/testapp.wat +++ b/samples/terminate/wasm-apps/testapp.wat @@ -3,7 +3,7 @@ (module (func $fd_read (import "wasi_snapshot_preview1" "fd_read") (param i32 i32 i32 i32) (result i32)) - (func (export "_start") + (func $block_forever (export "block_forever") ;; read from FD 0 i32.const 100 ;; iov_base i32.const 200 ;; buffer @@ -18,5 +18,36 @@ call $fd_read unreachable ) + (func (export "_start") + call $block_forever + ) + + ;; a dumb malloc/free implementation + (func (export "malloc") (param i32) (result i32) + local.get 0 + i32.const 65535 + i32.add + i32.const 65536 + i32.div_u + memory.grow + local.set 0 + local.get 0 + i32.const -1 + i32.eq + if + i32.const 0 + return + end + local.get 0 + i32.const 65536 + i32.mul + ) + (func (export "free") (param i32)) + (memory (export "memory") 1) + + ;; fake globals to make wasm_set_aux_stack happy + (global (export "__heap_base") i32 (i32.const 0x10000)) + (global (export "__data_end") i32 (i32.const 0x10000)) + (global (mut i32) (i32.const 0x10000)) )