Skip to content

Commit 8fc6413

Browse files
authored
feat(wasi-threads): Add example of exception propagation (#1812)
1 parent 929d594 commit 8fc6413

3 files changed

Lines changed: 118 additions & 1 deletion

File tree

samples/wasi-threads/README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,24 @@
1-
# "WASI threads" sample introduction
1+
# "WASI threads" sample introduction
2+
3+
Currently, since the `wasi-sdk` does not have thread support in the latest release, make sure to have [wasi-libc](https://github.com/WebAssembly/wasi-libc) installed. Build it with threads enabled, e.g.
4+
5+
```shell
6+
make \
7+
AR=/opt/wasi-sdk/bin/llvm-ar \
8+
NM=/opt/wasi-sdk/bin/llvm-nm \
9+
CC=/opt/wasi-sdk/bin/clang \
10+
THREAD_MODEL=posix
11+
```
12+
13+
Build and run the samples
14+
15+
```shell
16+
$ mkdir build
17+
$ cd build
18+
$ cmake -DWASI_SYSROOT=/path/to/wasi-libc/sysroot ..
19+
$ make
20+
...
21+
$ ./iwasm wasm-apps/no_pthread.wasm
22+
...
23+
$ ./iwasm wasm-apps/exception_propagation.wasm
24+
```

samples/wasi-threads/wasm-apps/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
33

4+
if (APPLE)
5+
set (HAVE_FLAG_SEARCH_PATHS_FIRST 0)
6+
set (CMAKE_C_LINK_FLAGS "")
7+
set (CMAKE_CXX_LINK_FLAGS "")
8+
endif ()
9+
410
if (NOT DEFINED WASI_SDK_DIR)
511
set (WASI_SDK_DIR "/opt/wasi-sdk")
612
endif ()
@@ -27,3 +33,4 @@ function (compile_sample SOURCE_FILE)
2733
endfunction ()
2834

2935
compile_sample(no_pthread.c)
36+
compile_sample(exception_propagation.c)
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright (C) 2022 Amazon.com Inc. or its affiliates. All rights reserved.
3+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
*/
5+
#ifndef __wasi__
6+
#error This example only compiles to WASM/WASI target
7+
#endif
8+
9+
#include <stdlib.h>
10+
#include <stdio.h>
11+
#include <assert.h>
12+
#include <wasi/api.h>
13+
#include <semaphore.h>
14+
#include <stdbool.h>
15+
#include <unistd.h>
16+
17+
#define TIMEOUT_SECONDS 10
18+
#define NUM_THREADS 3
19+
static sem_t sem;
20+
21+
void
22+
run_long_task()
23+
{
24+
// Busy waiting to be interruptible by exception
25+
for (int i = 0; i < TIMEOUT_SECONDS; i++)
26+
sleep(1);
27+
}
28+
29+
__attribute__((export_name("wasi_thread_start"))) void
30+
wasi_thread_start(int thread_id, int *start_arg)
31+
{
32+
bool has_to_throw_exception = (bool)start_arg;
33+
34+
if (has_to_throw_exception) {
35+
// Wait for all other threads (including main thread) to be ready
36+
printf("Waiting before throwing exception\n");
37+
for (int i = 0; i < NUM_THREADS; i++)
38+
sem_wait(&sem);
39+
40+
printf("Throwing exception\n");
41+
__builtin_trap();
42+
}
43+
else {
44+
printf("Thread running\n");
45+
46+
sem_post(&sem);
47+
run_long_task(); // Wait to be interrupted by exception
48+
assert(false && "Unreachable");
49+
}
50+
}
51+
52+
int
53+
main(int argc, char **argv)
54+
{
55+
int thread_id = -1;
56+
if (sem_init(&sem, 0, 0) != 0) {
57+
printf("Failed to init semaphore\n");
58+
return EXIT_FAILURE;
59+
}
60+
61+
// Create a thread that throws an exception
62+
thread_id = __wasi_thread_spawn((void *)true);
63+
if (thread_id < 0) {
64+
printf("Failed to create thread: %d\n", thread_id);
65+
return EXIT_FAILURE;
66+
}
67+
68+
// Create two additional threads to test exception propagation
69+
thread_id = __wasi_thread_spawn((void *)false);
70+
if (thread_id < 0) {
71+
printf("Failed to create thread: %d\n", thread_id);
72+
return EXIT_FAILURE;
73+
}
74+
thread_id = __wasi_thread_spawn((void *)false);
75+
if (thread_id < 0) {
76+
printf("Failed to create thread: %d\n", thread_id);
77+
return EXIT_FAILURE;
78+
}
79+
80+
printf("Main thread running\n");
81+
82+
sem_post(&sem);
83+
run_long_task(); // Wait to be interrupted by exception
84+
assert(false && "Unreachable");
85+
86+
return EXIT_SUCCESS;
87+
}

0 commit comments

Comments
 (0)