Skip to content

Commit 241060c

Browse files
authored
threads: implement pthread_create (#325)
* threads: implement `pthread_create` As described in the [`wasi-threads`] proposal, this change implements `pthread_create` using the new `wasi_thread_spawn(void *arg)` API. As described there, `wasi-libc` exports the thread entry point with the expected name, `wasi_thread_start`, and then unwraps the passed argument `struct` to invoke the user function with the user argument `struct`. [`wasi-threads`]: WebAssembly/wasi-threads#5 Previously, the TID was only passed to the child thread entry point; the parent thread was forced to wait until the child thread set the TID in the pthread structure. With this change, the TID will be passed not only to the child thread but also returned to the parent thread, so that either side can make progress. The `i32.store` becomes an `i32.atomic.store` to avoid concurrent writes.
1 parent f2a618f commit 241060c

File tree

6 files changed

+155
-2
lines changed

6 files changed

+155
-2
lines changed

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ LIBC_TOP_HALF_MUSL_SOURCES += \
203203
thread/pthread_condattr_init.c \
204204
thread/pthread_condattr_setclock.c \
205205
thread/pthread_condattr_setpshared.c \
206+
thread/pthread_create.c \
206207
thread/pthread_mutex_consistent.c \
207208
thread/pthread_mutex_destroy.c \
208209
thread/pthread_mutex_init.c \
@@ -229,6 +230,7 @@ LIBC_TOP_HALF_MUSL_SOURCES += \
229230
thread/pthread_rwlockattr_destroy.c \
230231
thread/pthread_rwlockattr_init.c \
231232
thread/pthread_rwlockattr_setpshared.c \
233+
thread/pthread_setcancelstate.c \
232234
thread/pthread_testcancel.c \
233235
thread/sem_destroy.c \
234236
thread/sem_getvalue.c \
@@ -237,7 +239,6 @@ LIBC_TOP_HALF_MUSL_SOURCES += \
237239
thread/sem_timedwait.c \
238240
thread/sem_trywait.c \
239241
thread/sem_wait.c \
240-
thread/pthread_setcancelstate.c \
241242
)
242243
endif
243244

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ __EINVAL
1111
__ENOMEM
1212
__SIG_ERR
1313
__SIG_IGN
14+
__acquire_ptc
1415
__aio_close
1516
__asctime_r
1617
__assert_fail
@@ -41,6 +42,7 @@ __des_setkey
4142
__do_cleanup_pop
4243
__do_cleanup_push
4344
__do_des
45+
__do_orphaned_stdio_locks
4446
__duplocale
4547
__env_rm_add
4648
__exp2f_data
@@ -182,6 +184,8 @@ __private_cond_signal
182184
__progname
183185
__progname_full
184186
__pthread_cond_timedwait
187+
__pthread_create
188+
__pthread_exit
185189
__pthread_mutex_lock
186190
__pthread_mutex_timedlock
187191
__pthread_mutex_trylock
@@ -196,11 +200,15 @@ __pthread_rwlock_unlock
196200
__pthread_rwlock_wrlock
197201
__pthread_setcancelstate
198202
__pthread_testcancel
203+
__pthread_tsd_main
204+
__pthread_tsd_run_dtors
205+
__pthread_tsd_size
199206
__putenv
200207
__qsort_r
201208
__rand48_step
202209
__random_lockptr
203210
__reallocarray
211+
__release_ptc
204212
__rem_pio2
205213
__rem_pio2_large
206214
__rem_pio2f
@@ -257,6 +265,9 @@ __tanl
257265
__testcancel
258266
__timedwait
259267
__timedwait_cp
268+
__tl_lock
269+
__tl_sync
270+
__tl_unlock
260271
__tm_to_secs
261272
__tm_to_tzname
262273
__tolower_l
@@ -322,6 +333,7 @@ __wasi_sock_accept
322333
__wasi_sock_recv
323334
__wasi_sock_send
324335
__wasi_sock_shutdown
336+
__wasi_thread_spawn
325337
__wasilibc_access
326338
__wasilibc_cwd
327339
__wasilibc_cwd_lock
@@ -948,6 +960,8 @@ pthread_condattr_destroy
948960
pthread_condattr_init
949961
pthread_condattr_setclock
950962
pthread_condattr_setpshared
963+
pthread_create
964+
pthread_exit
951965
pthread_mutex_consistent
952966
pthread_mutex_destroy
953967
pthread_mutex_getprioceiling
@@ -1212,6 +1226,7 @@ vswprintf
12121226
vswscanf
12131227
vwprintf
12141228
vwscanf
1229+
wasi_thread_start
12151230
wcpcpy
12161231
wcpncpy
12171232
wcrtomb

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
__addtf3
2+
__copy_tls
3+
__default_guardsize
4+
__default_stacksize
25
__divtf3
36
__eqtf2
47
__extenddftf2
@@ -56,6 +59,7 @@ __imported_wasi_snapshot_preview1_sock_accept
5659
__imported_wasi_snapshot_preview1_sock_recv
5760
__imported_wasi_snapshot_preview1_sock_send
5861
__imported_wasi_snapshot_preview1_sock_shutdown
62+
__imported_wasi_snapshot_preview2_thread_spawn
5963
__letf2
6064
__lock
6165
__lockfile
@@ -64,6 +68,7 @@ __main_argc_argv
6468
__netf2
6569
__stack_pointer
6670
__subtf3
71+
__thread_list_lock
6772
__tls_base
6873
__trunctfdf2
6974
__trunctfsf2

libc-bottom-half/headers/public/wasi/api.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,6 +2089,25 @@ __wasi_errno_t __wasi_sock_shutdown(
20892089
) __attribute__((__warn_unused_result__));
20902090
/** @} */
20912091

2092+
#ifdef _REENTRANT
2093+
/**
2094+
* Request a new thread to be created by the host.
2095+
*
2096+
* The host will create a new instance of the current module sharing its
2097+
* memory, find an exported entry function--`wasi_thread_start`--, and call the
2098+
* entry function with `start_arg` in the new thread.
2099+
*
2100+
* @see https://github.com/WebAssembly/wasi-threads/#readme
2101+
*/
2102+
__wasi_errno_t __wasi_thread_spawn(
2103+
/**
2104+
* A pointer to an opaque struct to be passed to the module's entry
2105+
* function.
2106+
*/
2107+
void *start_arg
2108+
) __attribute__((__warn_unused_result__));
2109+
#endif
2110+
20922111
#ifdef __cplusplus
20932112
}
20942113
#endif

libc-bottom-half/sources/__wasilibc_real.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,3 +659,14 @@ __wasi_errno_t __wasi_sock_shutdown(
659659
return (uint16_t) ret;
660660
}
661661

662+
#ifdef _REENTRANT
663+
int32_t __imported_wasi_snapshot_preview2_thread_spawn(int32_t arg0) __attribute__((
664+
__import_module__("wasi_snapshot_preview2"),
665+
__import_name__("thread_spawn")
666+
));
667+
668+
__wasi_errno_t __wasi_thread_spawn(void* start_arg) {
669+
int32_t ret = __imported_wasi_snapshot_preview2_thread_spawn((int32_t) start_arg);
670+
return (uint16_t) ret;
671+
}
672+
#endif

0 commit comments

Comments
 (0)