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