Skip to content

Commit

Permalink
feat(wasi-threads): handle thread exit
Browse files Browse the repository at this point in the history
  • Loading branch information
eloparco committed Jan 6, 2023
1 parent 2615646 commit 6c6cd45
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 13 deletions.
5 changes: 4 additions & 1 deletion core/iwasm/common/wasm_application.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,10 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
the actual main function. Directly calling main function
may cause exception thrown. */
if ((func = wasm_runtime_lookup_wasi_start_function(module_inst))) {
return wasm_runtime_call_wasm(exec_env, func, 0, NULL);
int ret = wasm_runtime_call_wasm(exec_env, func, 0, NULL);
if (!ret && wasm_runtime_get_exception(module_inst))
wasm_cluster_spread_exception(exec_env);
return ret;
}
#endif /* end of WASM_ENABLE_LIBC_WASI */

Expand Down
1 change: 0 additions & 1 deletion core/iwasm/interpreter/wasm_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -2157,7 +2157,6 @@ wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
wasm_exec_env_set_thread_info(exec_env);

interp_call_wasm(module_inst, exec_env, function, argc, argv);
(void)clear_wasi_proc_exit_exception(module_inst);
return !wasm_get_exception(module_inst) ? true : false;
}

Expand Down
2 changes: 1 addition & 1 deletion samples/wasi-threads/wasm-apps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ function (compile_sample SOURCE_FILE)
endfunction ()

compile_sample(no_pthread.c)
compile_sample(exception_propagation.c)
compile_sample(thread_termination.c)
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,40 @@
#define NUM_THREADS 3
static sem_t sem;

#define TEST_TERMINATION_BY_TRAP 0 // Otherwise test `proc_exit` termination
#define TEST_TERMINATION_IN_MAIN_THREAD 0

void
run_long_task()
{
// Busy waiting to be interruptible by exception
// Busy waiting to be interruptible by trap or `proc_exit`
for (int i = 0; i < TIMEOUT_SECONDS; i++)
sleep(1);
}

__attribute__((export_name("wasi_thread_start"))) void
wasi_thread_start(int thread_id, int *start_arg)
{
bool has_to_throw_exception = (bool)start_arg;
bool has_to_terminate = (bool)start_arg;

if (has_to_throw_exception) {
if (has_to_terminate) {
// Wait for all other threads (including main thread) to be ready
printf("Waiting before throwing exception\n");
printf("Waiting before terminating\n");
for (int i = 0; i < NUM_THREADS; i++)
sem_wait(&sem);

printf("Throwing exception\n");
printf("Force termination\n");
#if TEST_TERMINATION_BY_TRAP == 1
__builtin_trap();
#else
__wasi_proc_exit(1);
#endif
}
else {
printf("Thread running\n");

sem_post(&sem);
run_long_task(); // Wait to be interrupted by exception
run_long_task(); // Wait to be interrupted
assert(false && "Unreachable");
}
}
Expand All @@ -58,14 +65,18 @@ main(int argc, char **argv)
return EXIT_FAILURE;
}

// Create a thread that throws an exception
// Create a thread that forces termination through trap or `proc_exit`
#if TEST_TERMINATION_IN_MAIN_THREAD == 1
thread_id = __wasi_thread_spawn((void *)false);
#else
thread_id = __wasi_thread_spawn((void *)true);
#endif
if (thread_id < 0) {
printf("Failed to create thread: %d\n", thread_id);
return EXIT_FAILURE;
}

// Create two additional threads to test exception propagation
// Create two additional threads to test termination propagation
thread_id = __wasi_thread_spawn((void *)false);
if (thread_id < 0) {
printf("Failed to create thread: %d\n", thread_id);
Expand All @@ -80,8 +91,19 @@ main(int argc, char **argv)
printf("Main thread running\n");

sem_post(&sem);
run_long_task(); // Wait to be interrupted by exception
assert(false && "Unreachable");

#if TEST_TERMINATION_IN_MAIN_THREAD == 1

printf("Force termination (main thread)\n");
#if TEST_TERMINATION_BY_TRAP == 1
__builtin_trap();
#else
__wasi_proc_exit(1);
#endif

#else
run_long_task(); // Wait to be interrupted
assert(false && "Unreachable");
#endif
return EXIT_SUCCESS;
}

0 comments on commit 6c6cd45

Please sign in to comment.