Skip to content

Commit 2ec89b3

Browse files
12101111haraldh
authored andcommitted
threads: implement init of TLS and stack pointer (WebAssembly#342)
* threads: implement init of TLS and stack pointer * fix: rename wasi_snapshot_preview2_thread_spawn to wasi_thread_spawn Signed-off-by: Harald Hoyer <[email protected]> * fix: change signature of wasi_thread_start Signed-off-by: Harald Hoyer <[email protected]> * fix: pthread_exit for WASI Can't use `exit()` because it is too high level. Have to unlock the thread list. Signed-off-by: Harald Hoyer <[email protected]> * fix: initialize struct pthread for the main thread Signed-off-by: Harald Hoyer <[email protected]> * fix: store the aligned stack minus `struct start_args` Signed-off-by: Harald Hoyer <[email protected]> Signed-off-by: Harald Hoyer <[email protected]> Co-authored-by: Harald Hoyer <[email protected]>
1 parent 550e0d4 commit 2ec89b3

File tree

11 files changed

+154
-39
lines changed

11 files changed

+154
-39
lines changed

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,16 @@ LIBC_TOP_HALF_MUSL_SOURCES = \
220220
ifeq ($(THREAD_MODEL), posix)
221221
LIBC_TOP_HALF_MUSL_SOURCES += \
222222
$(addprefix $(LIBC_TOP_HALF_MUSL_SRC_DIR)/, \
223+
env/__init_tls.c \
224+
stdio/__lockfile.c \
223225
thread/__lock.c \
224226
thread/__wait.c \
225227
thread/__timedwait.c \
228+
thread/default_attr.c \
229+
thread/pthread_attr_destroy.c \
230+
thread/pthread_attr_init.c \
231+
thread/pthread_attr_setstack.c \
232+
thread/pthread_attr_setstacksize.c \
226233
thread/pthread_cleanup_push.c \
227234
thread/pthread_cond_broadcast.c \
228235
thread/pthread_cond_destroy.c \
@@ -263,6 +270,7 @@ LIBC_TOP_HALF_MUSL_SOURCES += \
263270
thread/pthread_rwlockattr_init.c \
264271
thread/pthread_rwlockattr_setpshared.c \
265272
thread/pthread_setcancelstate.c \
273+
thread/pthread_self.c \
266274
thread/pthread_testcancel.c \
267275
thread/sem_destroy.c \
268276
thread/sem_getvalue.c \

expected/wasm32-wasi/posix/defined-symbols.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ __wasi_futex_wake_all
411411
__wasi_getcwd
412412
__wasi_http_request
413413
__wasi_http_status
414+
__wasi_init_tp
414415
__wasi_path_create_directory
415416
__wasi_path_filestat_get
416417
__wasi_path_filestat_set_times
@@ -531,6 +532,7 @@ __wasilibc_nocwd_utimensat
531532
__wasilibc_open_nomode
532533
__wasilibc_pgrp
533534
__wasilibc_populate_preopens_init
535+
__wasilibc_pthread_self
534536
__wasilibc_register_preopened_fd
535537
__wasilibc_rename_newat
536538
__wasilibc_rename_oldat

expected/wasm32-wasi/posix/undefined-symbols.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,5 @@ __tls_size
150150
__trunctfdf2
151151
__trunctfsf2
152152
__unordtf2
153-
__wasilibc_pthread_self
154153
__wasm_call_ctors
155154
__wasm_init_tls
156-
main

libc-bottom-half/crt/crt1-command.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#ifdef _REENTRANT
22
#include <stdatomic.h>
3+
extern void __wasi_init_tp(void);
34
#endif
45
#include <wasi/api.h>
56
extern void __wasm_call_ctors(void);
@@ -29,6 +30,10 @@ void _start(void) {
2930
started = 1;
3031
#endif
3132

33+
#ifdef _REENTRANT
34+
__wasi_init_tp();
35+
#endif
36+
3237
// The linker synthesizes this to call constructors.
3338
__wasm_call_ctors();
3439

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
static inline uintptr_t __get_tp(void) {
2-
#if _REENTRANT
3-
int val;
4-
__asm__("global.get __wasilibc_pthread_self\n"
5-
"local.set %0"
6-
: "=r"(val));
7-
return val;
8-
#else
9-
return 0;
10-
#endif
1+
extern _Thread_local struct __pthread __wasilibc_pthread_self;
2+
3+
static inline uintptr_t __get_tp() {
4+
return (uintptr_t)&__wasilibc_pthread_self;
115
}

libc-top-half/musl/src/env/__init_tls.c

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
#ifdef __wasilibc_unmodified_upstream
12
#define SYSCALL_NO_TLS 1
23
#include <elf.h>
4+
#endif
35
#include <limits.h>
6+
#ifdef __wasilibc_unmodified_upstream
47
#include <sys/mman.h>
8+
#endif
59
#include <string.h>
610
#include <stddef.h>
711
#include "pthread_impl.h"
@@ -15,20 +19,22 @@
1519

1620
volatile int __thread_list_lock;
1721

22+
#ifndef __wasilibc_unmodified_upstream
23+
void __wasi_init_tp() {
24+
__init_tp((void *)__get_tp());
25+
}
26+
#endif
27+
1828
int __init_tp(void *p)
1929
{
2030
pthread_t td = p;
2131
td->self = td;
32+
#ifdef __wasilibc_unmodified_upstream
2233
int r = __set_thread_area(TP_ADJ(p));
2334
if (r < 0) return -1;
2435
if (!r) libc.can_do_threads = 1;
2536
td->detach_state = DT_JOINABLE;
26-
#ifdef __wasilibc_unmodified_upstream
2737
td->tid = __syscall(SYS_set_tid_address, &__thread_list_lock);
28-
#else
29-
td->tid = 0;
30-
r = __wasi_thread_id(&td->tid);
31-
if (r != 0) return r;
3238
#endif
3339
td->locale = &libc.global_locale;
3440
td->robust_list.head = &td->robust_list.head;
@@ -37,6 +43,8 @@ int __init_tp(void *p)
3743
return 0;
3844
}
3945

46+
#ifdef __wasilibc_unmodified_upstream
47+
4048
static struct builtin_tls {
4149
char c;
4250
struct pthread pt;
@@ -45,9 +53,15 @@ static struct builtin_tls {
4553
#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
4654

4755
static struct tls_module main_tls;
56+
#endif
57+
58+
#ifndef __wasilibc_unmodified_upstream
59+
extern void __wasm_init_tls(void*);
60+
#endif
4861

4962
void *__copy_tls(unsigned char *mem)
5063
{
64+
#ifdef __wasilibc_unmodified_upstream
5165
pthread_t td;
5266
struct tls_module *p;
5367
size_t i;
@@ -79,9 +93,24 @@ void *__copy_tls(unsigned char *mem)
7993
dtv[0] = libc.tls_cnt;
8094
td->dtv = dtv;
8195
return td;
96+
#else
97+
size_t tls_align = __builtin_wasm_tls_align();
98+
volatile void* tls_base = __builtin_wasm_tls_base();
99+
mem += tls_align;
100+
mem -= (uintptr_t)mem & (tls_align-1);
101+
__wasm_init_tls(mem);
102+
__asm__("local.get %0\n"
103+
"global.set __tls_base\n"
104+
:: "r"(tls_base));
105+
return mem;
106+
#endif
82107
}
83108

109+
<<<<<<< HEAD
84110

111+
=======
112+
#ifdef __wasilibc_unmodified_upstream
113+
>>>>>>> a00bf32 (threads: implement init of TLS and stack pointer (#342))
85114
#if ULONG_MAX == 0xffffffff
86115
typedef Elf32_Phdr Phdr;
87116
#else
@@ -164,3 +193,9 @@ void __init_tls(size_t *aux)
164193
if (__init_tp(__copy_tls(mem)) < 0)
165194
a_crash();
166195
}
196+
<<<<<<< HEAD
197+
=======
198+
199+
weak_alias(static_init_tls, __init_tls);
200+
#endif
201+
>>>>>>> a00bf32 (threads: implement init of TLS and stack pointer (#342))

libc-top-half/musl/src/internal/libc.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ struct tls_module {
1818
};
1919

2020
struct __libc {
21-
#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
21+
#ifdef __wasilibc_unmodified_upstream
2222
char can_do_threads;
23+
#endif
24+
#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
2325
char threaded;
2426
#endif
2527
#ifdef __wasilibc_unmodified_upstream // WASI doesn't currently use any code that needs "secure" mode
@@ -32,7 +34,7 @@ struct __libc {
3234
#ifdef __wasilibc_unmodified_upstream // WASI has no auxv
3335
size_t *auxv;
3436
#endif
35-
#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
37+
#ifdef __wasilibc_unmodified_upstream // WASI use different TLS implement
3638
struct tls_module *tls_head;
3739
size_t tls_size, tls_align, tls_cnt;
3840
#endif

libc-top-half/musl/src/internal/pthread_impl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ struct pthread {
2626
/* Part 1 -- these fields may be external or
2727
* internal (accessed via asm) ABI. Do not change. */
2828
struct pthread *self;
29+
#ifdef __wasilibc_unmodified_upstream
2930
#ifndef TLS_ABOVE_TP
3031
uintptr_t *dtv;
32+
#endif
3133
#endif
3234
struct pthread *prev, *next; /* non-ABI */
3335
uintptr_t sysinfo;

libc-top-half/musl/src/thread/__tls_get_addr.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
void *__tls_get_addr(tls_mod_off_t *v)
44
{
5+
#ifdef __wasilibc_unmodified_upstream
56
pthread_t self = __pthread_self();
67
return (void *)(self->dtv[v[0]] + v[1]);
8+
#else
9+
uintptr_t *dtv = __builtin_wasm_tls_base();
10+
return (void *)(dtv[v[0]] + v[1]);
11+
#endif
712
}

0 commit comments

Comments
 (0)