Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment the new proposed abi of thread-spawn #385

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions libc-bottom-half/headers/public/wasi/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -2099,12 +2099,14 @@ __wasi_errno_t __wasi_sock_shutdown(
*
* @see https://github.com/WebAssembly/wasi-threads/#readme
*/
int32_t __wasi_thread_spawn(
uint8_t __wasi_thread_spawn(
/**
* A pointer to an opaque struct to be passed to the module's entry
* function.
*/
void *start_arg
void *start_arg,
uint8_t *error,
uint32_t *tid
) __attribute__((__warn_unused_result__));
#endif

Expand Down
25 changes: 19 additions & 6 deletions libc-bottom-half/sources/__wasilibc_real.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,12 +660,25 @@ __wasi_errno_t __wasi_sock_shutdown(
}

#ifdef _REENTRANT
int32_t __imported_wasi_thread_spawn(int32_t arg0) __attribute__((
void __imported_wasi_thread_spawn(int32_t arg0, int32_t arg1) __attribute__((
__import_module__("wasi"),
__import_name__("thread_spawn")
));

int32_t __wasi_thread_spawn(void* start_arg) {
return __imported_wasi_thread_spawn((int32_t) start_arg);
__import_name__("thread-spawn")
));

uint8_t __wasi_thread_spawn(void *start_arg, uint8_t *error, uint32_t *tid) {
struct {
uint8_t is_error;
union {
uint8_t error;
uint32_t tid;
} u;
} error_or_tid;
__imported_wasi_thread_spawn((int32_t) start_arg, (int32_t)(intptr_t) &error_or_tid);
if (error_or_tid.is_error) {
*error = error_or_tid.u.error;
return 1;
}
*tid = error_or_tid.u.tid;
return 0;
}
#endif
14 changes: 11 additions & 3 deletions libc-top-half/musl/src/thread/pthread_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,9 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
void* new_tls_base;
size_t tls_offset;
tls_size += tls_align;
uint8_t is_error;
uint32_t tid;
uint8_t error;
#endif

#ifdef __wasilibc_unmodified_upstream
Expand Down Expand Up @@ -516,7 +519,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
* of the current module and start executing the entry function. The
* wasi-threads specification requires the module to export a
* `wasi_thread_start` function, which is invoked with `args`. */
ret = __wasi_thread_spawn((void *) args);
is_error = __wasi_thread_spawn((void *) args, &error, &tid);
#endif

#ifdef __wasilibc_unmodified_upstream
Expand All @@ -542,10 +545,15 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
* did succeed, then we store the TID atomically, since this parent thread
* is racing with the child thread to set this field; this way, whichever
* thread reaches this point first can continue without waiting. */
if (ret < 0) {
if (is_error) {
/*
* At this point EAGAIN is the only defined error in wasi-threads.
* when the list grows, maybe we should convert errno.
*/
ret = -EAGAIN;
} else {
atomic_store((atomic_int *) &(new->tid), ret);
atomic_store((atomic_int *) &(new->tid), (int)tid);
ret = 0;
}
#endif

Expand Down