1+ #include <assert.h>
2+ #include <wasi/api.h>
3+
4+ const int64_t SECOND = 1000 * 1000 * 1000 ;
5+
6+ typedef struct {
7+ int th_ready ;
8+ int th_continue ;
9+ int th_done ;
10+ int failed ;
11+ int tid ;
12+ int value ;
13+ } shared_t ;
14+
15+ __attribute__((export_name ("wasi_thread_start" ))) void
16+ wasi_thread_start (int thread_id , int * start_arg )
17+ {
18+ shared_t * data = (shared_t * )start_arg ;
19+
20+ data -> th_ready = 1 ;
21+ __builtin_wasm_memory_atomic_notify (& data -> th_ready , 1 );
22+
23+ // so we can have all the threads alive at the same time
24+ if (__builtin_wasm_memory_atomic_wait32 (& data -> th_continue , 0 , SECOND ) == 2 ) {
25+ data -> failed = 1 ;
26+ return ;
27+ }
28+
29+ assert (data -> value == 52 );
30+
31+ data -> value += 8 ;
32+ data -> tid = thread_id ;
33+
34+ data -> th_done = 1 ;
35+ __builtin_wasm_memory_atomic_notify (& data -> th_done , 1 );
36+ }
37+
38+ int
39+ main (int argc , char * * argv )
40+ {
41+ shared_t data [3 ] = { 0 };
42+ int data_count = sizeof (data ) / sizeof (data [0 ]);
43+ int i , j ;
44+
45+ for (i = 0 ; i < data_count ; i ++ ) {
46+ data [i ].value = 52 ;
47+ assert (__wasi_thread_spawn (& data [i ]) == 0 );
48+ assert (__builtin_wasm_memory_atomic_wait32 (& data [i ].th_ready , 0 ,
49+ SECOND )
50+ != 2 ); // not a timeout
51+ }
52+
53+ for (i = 0 ; i < data_count ; i ++ ) {
54+ __builtin_wasm_memory_atomic_notify (& data [i ].th_continue , 1 );
55+ }
56+
57+ for (i = 0 ; i < data_count ; i ++ ) {
58+ assert (__builtin_wasm_memory_atomic_wait32 (& data [i ].th_done , 0 ,
59+ SECOND )
60+ != 2 ); // not a timeout
61+ assert (data [i ].value == 60 );
62+
63+ for (j = i + 1 ; j < data_count ; j ++ ) {
64+ assert (data [i ].tid != data [j ].tid );
65+ }
66+ }
67+
68+ return 0 ;
69+ }
0 commit comments