]> git.proxmox.com Git - wasi-libc.git/blame - libc-top-half/musl/src/thread/wasm32/wasi_thread_start.s
Fix races around pthread exit and join (#409)
[wasi-libc.git] / libc-top-half / musl / src / thread / wasm32 / wasi_thread_start.s
CommitLineData
35fee1d9
YT
1 .text
2
3 .export_name wasi_thread_start, wasi_thread_start
4
5 .globaltype __stack_pointer, i32
6 .globaltype __tls_base, i32
7 .functype __wasi_thread_start_C (i32, i32) -> ()
8
9 .hidden wasi_thread_start
10 .globl wasi_thread_start
11 .type wasi_thread_start,@function
12
13wasi_thread_start:
14 .functype wasi_thread_start (i32, i32) -> ()
15
16 # Set up the minimum C environment.
17 # Note: offsetof(start_arg, stack) == 0
18 local.get 1 # start_arg
19 i32.load 0 # stack
20 global.set __stack_pointer
21
22 local.get 1 # start_arg
23 i32.load 4 # tls_base
24 global.set __tls_base
25
26 # Make the C function do the rest of work.
27 local.get 0 # tid
28 local.get 1 # start_arg
29 call __wasi_thread_start_C
30
aecd368c
YT
31 # Unlock thread list. (as CLONE_CHILD_CLEARTID would do for Linux)
32 #
33 # Note: once we unlock the thread list, our "map_base" can be freed
34 # by a joining thread. It's safe as we are in ASM and no longer use
35 # our C stack or pthread_t. It's impossible to do this safely in C
36 # because there is no way to tell the C compiler not to use C stack.
37 i32.const __thread_list_lock
38 i32.const 0
39 i32.atomic.store 0
40 # As an optimization, we can check tl_lock_waiters here.
41 # But for now, simply wake up unconditionally as
42 # CLONE_CHILD_CLEARTID does.
43 i32.const __thread_list_lock
44 i32.const 1
45 memory.atomic.notify 0
46 drop
47
35fee1d9 48 end_function