From 983234e70442501418e65ef75545fe288a3f0f7b Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 13 Jan 2023 20:07:20 +0900 Subject: [PATCH 1/2] Experiment the new proposed abi of thread-spawn --- libc-bottom-half/sources/__wasilibc_real.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libc-bottom-half/sources/__wasilibc_real.c b/libc-bottom-half/sources/__wasilibc_real.c index d2e6b71c6..fa499b98e 100644 --- a/libc-bottom-half/sources/__wasilibc_real.c +++ b/libc-bottom-half/sources/__wasilibc_real.c @@ -660,12 +660,23 @@ __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") + __import_name__("thread-spawn") )); int32_t __wasi_thread_spawn(void* start_arg) { - return __imported_wasi_thread_spawn((int32_t) start_arg); + 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) { + return -(int)error_or_tid.u.error; + } + return error_or_tid.u.tid; } #endif From 39aeeb7856edcc011e2f40f90f5902a4d8e173d3 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Mon, 16 Jan 2023 14:51:14 +0900 Subject: [PATCH 2/2] wasi-threads: Handle error 0 properly --- libc-bottom-half/headers/public/wasi/api.h | 6 ++++-- libc-bottom-half/sources/__wasilibc_real.c | 8 +++++--- libc-top-half/musl/src/thread/pthread_create.c | 14 +++++++++++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/libc-bottom-half/headers/public/wasi/api.h b/libc-bottom-half/headers/public/wasi/api.h index 45a6506e2..f2cfbe7a1 100644 --- a/libc-bottom-half/headers/public/wasi/api.h +++ b/libc-bottom-half/headers/public/wasi/api.h @@ -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 diff --git a/libc-bottom-half/sources/__wasilibc_real.c b/libc-bottom-half/sources/__wasilibc_real.c index fa499b98e..6f8bbdadd 100644 --- a/libc-bottom-half/sources/__wasilibc_real.c +++ b/libc-bottom-half/sources/__wasilibc_real.c @@ -665,7 +665,7 @@ void __imported_wasi_thread_spawn(int32_t arg0, int32_t arg1) __attribute__(( __import_name__("thread-spawn") )); -int32_t __wasi_thread_spawn(void* start_arg) { +uint8_t __wasi_thread_spawn(void *start_arg, uint8_t *error, uint32_t *tid) { struct { uint8_t is_error; union { @@ -675,8 +675,10 @@ int32_t __wasi_thread_spawn(void* start_arg) { } error_or_tid; __imported_wasi_thread_spawn((int32_t) start_arg, (int32_t)(intptr_t) &error_or_tid); if (error_or_tid.is_error) { - return -(int)error_or_tid.u.error; + *error = error_or_tid.u.error; + return 1; } - return error_or_tid.u.tid; + *tid = error_or_tid.u.tid; + return 0; } #endif diff --git a/libc-top-half/musl/src/thread/pthread_create.c b/libc-top-half/musl/src/thread/pthread_create.c index 676e2ccf9..a5bcd3fca 100644 --- a/libc-top-half/musl/src/thread/pthread_create.c +++ b/libc-top-half/musl/src/thread/pthread_create.c @@ -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 @@ -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 @@ -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