Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6e03994
Pass --generate-threading-helpers for WASIP3
TartanLlama Feb 20, 2026
776691c
Newline
TartanLlama Feb 20, 2026
1e176a0
Generate bindings
TartanLlama Feb 20, 2026
418a2cf
Locks
TartanLlama Feb 20, 2026
36a0eed
Cleanup
TartanLlama Feb 20, 2026
6e8568b
Formatting
TartanLlama Feb 20, 2026
ac45109
Rename STRONG_LOCK
TartanLlama Feb 20, 2026
1f67537
Rename STRONG_LOCK
TartanLlama Feb 20, 2026
94dd503
Change cwd locking
TartanLlama Feb 20, 2026
5d6abcf
Build fixes
TartanLlama Feb 20, 2026
cf950b7
Build fixes
TartanLlama Feb 20, 2026
4311c91
Symbol fixes
TartanLlama Feb 20, 2026
f68bf5a
Symbol fixes
TartanLlama Feb 20, 2026
73081cf
Symbol fixes
TartanLlama Feb 20, 2026
47e08ba
Disable shared builds
TartanLlama Feb 20, 2026
1210dca
Update symbols for WASIP3
TartanLlama Feb 20, 2026
7c7c296
Merge branch 'main' into sy/wasip3-locks
TartanLlama Feb 20, 2026
e7407c7
Bump wasm-component-ld
TartanLlama Feb 20, 2026
afbd65e
Merge branch 'sy/wasip3-locks' of github.com:TartanLlama/wasi-libc in…
TartanLlama Feb 20, 2026
29fb984
Undefined signal fix
TartanLlama Feb 20, 2026
28d741f
Bump wasm-component-ld
TartanLlama Feb 20, 2026
93ab9e4
Symbol fixes
TartanLlama Feb 20, 2026
bf037e9
Add __wasm_call_ctors to undefined
TartanLlama Feb 20, 2026
4bd8635
Add component-model-threading feature
TartanLlama Feb 20, 2026
a19d2cf
Fix locks
TartanLlama Feb 21, 2026
207dc0d
Fix shared linking
TartanLlama Feb 21, 2026
a6ffb7e
Retrigger CI
TartanLlama Feb 21, 2026
518371a
Change init lock
TartanLlama Feb 21, 2026
4fb6925
Disable dynamic linking
TartanLlama Feb 21, 2026
29f8f51
Reenable shared lib
TartanLlama Feb 21, 2026
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
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ endif()
if(TARGET_TRIPLE MATCHES "-threads$")
set(THREADS ON)
add_compile_options(-mthread-model posix -pthread -ftls-model=local-exec -matomics)
elseif(TARGET_TRIPLE MATCHES "-wasip3$")
set(THREADS OFF)
add_compile_options(-mthread-model posix -pthread -ftls-model=local-exec)
else()
set(THREADS OFF)
add_compile_options(-mthread-model single)
Expand Down Expand Up @@ -139,6 +142,7 @@ elseif(WASI STREQUAL "p2")
set(__wasip2__ ON)
elseif(WASI STREQUAL "p3")
set(__wasip3__ ON)
set(__wasi_cooperative_threads__ ON)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be behind a #define/guard/etc for now while we're waiting for wasi-sdk/LLVM/etc to all get updated? That way we could go ahead and land all this in wasi-libc (untested) and follow-up with testing later. My gut is that it shouldn't be too hard to support building with/without coop threads within wasi-libc itself, but if that's too difficult to support then it's fine to wait for a build of LLVM with support for coop threds.

else()
message(FATAL_ERROR "Unknown WASI version: ${WASI}")
endif()
Expand Down
2 changes: 1 addition & 1 deletion cmake/wasm-component-ld.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ if (NOT WASM_COMPONENT_LD_EXECUTABLE)
ba_download(
wasm-component-ld
"https://github.com/bytecodealliance/wasm-component-ld"
"v0.5.19"
"v0.5.21"
)
ExternalProject_Get_Property(wasm-component-ld SOURCE_DIR)
set(WASM_COMPONENT_LD_EXECUTABLE "${SOURCE_DIR}/wasm-component-ld")
Expand Down
2 changes: 2 additions & 0 deletions expected/wasm32-wasip1-threads/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ __ftello
__ftello_unlocked
__funcs_on_exit
__funcs_on_quick_exit
__futexwait
__futimesat
__fwritable
__fwritex
Expand Down Expand Up @@ -308,6 +309,7 @@ __unlockfile
__uselocale
__utc
__wait
__wake
__wasi_args_get
__wasi_args_sizes_get
__wasi_clock_res_get
Expand Down
18 changes: 18 additions & 0 deletions expected/wasm32-wasip3/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ __ENOMEM
__SIG_ERR
__SIG_IGN
__acquire_ptc
__aio_close
__asctime_r
__assert_fail
__at_quick_exit_lockptr
__atexit_lockptr
__c_dot_utf8
__c_dot_utf8_locale
__c_locale
Expand All @@ -22,6 +25,7 @@ __clock_gettime
__clock_nanosleep
__component_type_object_force_link_wasip3
__component_type_object_force_link_wasip3_public_use_in_this_compilation_unit
__copy_tls
__cos
__cosdf
__cosl
Expand Down Expand Up @@ -143,7 +147,11 @@ __libc_calloc
__libc_free
__libc_malloc
__loc_is_allocated
__locale_lock
__locale_lockptr
__localtime_r
__lock
__lockfile
__log2_data
__log2f_data
__log_data
Expand Down Expand Up @@ -208,6 +216,7 @@ __pthread_tsd_size
__putenv
__qsort_r
__rand48_step
__random_lockptr
__reallocarray
__release_ptc
__rem_pio2
Expand Down Expand Up @@ -235,6 +244,7 @@ __stdin_used
__stdio_close
__stdio_exit
__stdio_exit_needed
__stdio_ofl_lockptr
__stdio_read
__stdio_seek
__stdio_write
Expand Down Expand Up @@ -266,6 +276,7 @@ __tan
__tandf
__tanl
__testcancel
__thread_list_lock
__tl_lock
__tl_unlock
__tm_to_secs
Expand All @@ -285,15 +296,22 @@ __tre_mem_new_impl
__tsearch_balance
__uflow
__unlist_locked_file
__unlock
__unlockfile
__uselocale
__utc
__waitlist_wait_on
__waitlist_wake_all
__waitlist_wake_one
__wasi_init_tp
__wasi_sockets_services_db
__wasilibc_access
__wasilibc_add_file
__wasilibc_add_tcp_socket
__wasilibc_add_udp_socket
__wasilibc_cwd
__wasilibc_cwd_lock
__wasilibc_cwd_unlock
__wasilibc_deinitialize_environ
__wasilibc_dttoif
__wasilibc_ensure_environ
Expand Down
5 changes: 5 additions & 0 deletions expected/wasm32-wasip3/predefined-macros.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1734,6 +1734,8 @@
#define SEEK_SET 0
#define SEGSIZE 512
#define SEM_FAILED ((sem_t *)0)
#define SEM_NSEMS_MAX 256
#define SEM_VALUE_MAX 0x7fffffff
#define SERVFAIL ns_r_servfail
#define SHORTBITS (sizeof(short) * 8)
#define SHRT_MAX 0x7fff
Expand Down Expand Up @@ -2429,6 +2431,7 @@
#define _POSIX_VERSION 200809L
#define _PTHREAD_H
#define _PTRDIFF_T
#define _REENTRANT 1
#define _REGEX_H
#define _SCHED_H
#define _SC_2_CHAR_TERM 95
Expand Down Expand Up @@ -3133,6 +3136,7 @@
#define __va_copy(d,s) __builtin_va_copy(d, s)
#define __wasi__ 1
#define __wasi_api_h
#define __wasi_cooperative_threads__
#define __wasi_libc_busywait_h
#define __wasi_libc_environ_h
#define __wasi_libc_find_relpath_h
Expand Down Expand Up @@ -3206,6 +3210,7 @@
#define __wasm32 1
#define __wasm32__ 1
#define __wasm__ 1
#define __wasm_atomics__ 1
#define _tolower(a) ((a)|0x20)
#define _toupper(a) ((a)&0x5f)
#define acos(x) __tg_real_complex(acos, (x))
Expand Down
2 changes: 2 additions & 0 deletions expected/wasm32-wasip3/undefined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ __thread_yield
__thread_yield_cancellable
__thread_yield_to_suspended
__thread_yield_to_suspended_cancellable
__tls_align
__trunctfdf2
__trunctfsf2
__unordtf2
Expand Down Expand Up @@ -143,6 +144,7 @@ __wasm_import_terminal_output_terminal_output_drop
__wasm_import_terminal_stderr_get_terminal_stderr
__wasm_import_terminal_stdin_get_terminal_stdin
__wasm_import_terminal_stdout_get_terminal_stdout
__wasm_init_tls
filesystem_future_result_void_error_code__cancel_read
filesystem_future_result_void_error_code__cancel_write
filesystem_future_result_void_error_code__drop_readable
Expand Down
9 changes: 8 additions & 1 deletion libc-bottom-half/cloudlibc/src/libc/sched/sched_yield.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@
#include <sched.h>

int sched_yield(void) {
#ifdef __wasip1__
#ifdef __wasi_cooperative_threads__
#ifdef __wasip3__
wasip3_thread_yield();
return 0;
#else
#error "Unknown WASI version"
#endif
#elif defined(__wasip1__)
__wasi_errno_t error = __wasi_sched_yield();
if (error != 0) {
errno = error;
Expand Down
1 change: 1 addition & 0 deletions libc-bottom-half/headers/public/wasi/version.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#cmakedefine __wasip1__
#cmakedefine __wasip2__
#cmakedefine __wasip3__
#cmakedefine __wasi_cooperative_threads__

#cmakedefine __wasi_sdk_major__ @__wasi_sdk_major__@
#cmakedefine __wasi_sdk_version__ "@__wasi_sdk_version__@"
Expand Down
7 changes: 4 additions & 3 deletions libc-bottom-half/sources/getcwd.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
char *__wasilibc_cwd = "/";

#ifdef _REENTRANT
static volatile int lock[1];
void __wasilibc_cwd_lock(void) { LOCK(lock); }
void __wasilibc_cwd_unlock(void) { UNLOCK(lock); }
static __lock_t lock[1];
// Critical section contains no yield points, so we can use weak locks.
void __wasilibc_cwd_lock(void) { WEAK_LOCK(lock); }
void __wasilibc_cwd_unlock(void) { WEAK_UNLOCK(lock); }
#else
#define __wasilibc_cwd_lock() (void)0
#define __wasilibc_cwd_unlock() (void)0
Expand Down
12 changes: 6 additions & 6 deletions libc-bottom-half/sources/preopens.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
#include <wasi/file_utils.h>
#endif

/// Access to the the above preopen must be protected in the presence of
/// threads.
#ifdef _REENTRANT
static __lock_t lock[1];
#endif

#if defined(__wasip1__)
typedef struct {
__wasi_fd_t fd;
Expand Down Expand Up @@ -96,12 +102,6 @@ static preopen *preopens;
static size_t num_preopens;
static size_t preopen_capacity;

/// Access to the the above preopen must be protected in the presence of
/// threads.
#ifdef _REENTRANT
static volatile int lock[1];
#endif

#ifdef NDEBUG
#define assert_invariants() // assertions disabled
#else
Expand Down
9 changes: 9 additions & 0 deletions libc-top-half/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,15 @@ else()
)
endif()

# Cooperative threading lock/waiting primitives
if (WASI STREQUAL "p3")
list(APPEND top_half_sources
musl/src/stdio/__lockfile.c
musl/src/thread/coop-threads/__lock.c
musl/src/thread/coop-threads/__wait.c
)
endif()

add_object_library(top-half ${top_half_sources})
foreach(obj top-half-shared top-half-static)
target_link_libraries(${obj} PUBLIC musl-top-half-interface)
Expand Down
10 changes: 9 additions & 1 deletion libc-top-half/musl/src/env/__init_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "libc.h"
#include "atomic.h"
#include "syscall.h"
#include <wasi/api.h>

#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
volatile int __thread_list_lock;
Expand Down Expand Up @@ -97,7 +98,14 @@ int __init_tp(void *p)
td->stack = bounds.base;
td->stack_size = bounds.size;
td->guard_size = 0;
#ifdef _REENTRANT
#ifdef __wasi_cooperative_threads__
td->detach_state = DT_JOINABLE;
#ifdef __wasip3__
td->tid = wasip3_thread_index();
#else
#error "Unknown WASI version"
#endif
#elif defined(_REENTRANT)
td->detach_state = DT_JOINABLE;
/*
* Initialize the TID to a value which doesn't conflict with
Expand Down
16 changes: 9 additions & 7 deletions libc-top-half/musl/src/exit/at_quick_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,30 @@
static void (*funcs[COUNT])(void);
static int count;
#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
static volatile int lock[1];
volatile int *const __at_quick_exit_lockptr = lock;
// All locks here can be weak, because the locking is only needed to protect against
// concurrent manipulation of the handler table, which hits no context switch points.
static __lock_t lock[1];
__lock_t *const __at_quick_exit_lockptr = lock;
#endif

void __funcs_on_quick_exit()
{
void (*func)(void);
LOCK(lock);
WEAK_LOCK(lock);
while (count > 0) {
func = funcs[--count];
UNLOCK(lock);
WEAK_UNLOCK(lock);
func();
LOCK(lock);
WEAK_LOCK(lock);
}
}

int at_quick_exit(void (*func)(void))
{
int r = 0;
LOCK(lock);
WEAK_LOCK(lock);
if (count == 32) r = -1;
else funcs[count++] = func;
UNLOCK(lock);
WEAK_UNLOCK(lock);
return r;
}
20 changes: 12 additions & 8 deletions libc-top-half/musl/src/exit/atexit.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,24 @@ static struct fl
static int slot;

#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
static volatile int lock[1];
volatile int *const __atexit_lockptr = lock;
#include "lock.h"

// All locks here can be weak, because the locking is only needed to protect against
// concurrent manipulation of the handler table, which hits no context switch points.
static __lock_t lock[1];
__lock_t *const __atexit_lockptr = lock;
#endif

void __funcs_on_exit()
{
void (*func)(void *), *arg;
LOCK(lock);
WEAK_LOCK(lock);
for (; head; head=head->next, slot=COUNT) while(slot-->0) {
func = head->f[slot];
arg = head->a[slot];
UNLOCK(lock);
WEAK_UNLOCK(lock);
func(arg);
LOCK(lock);
WEAK_LOCK(lock);
}
}

Expand All @@ -45,7 +49,7 @@ void __cxa_finalize(void *dso)

int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
{
LOCK(lock);
WEAK_LOCK(lock);

/* Defer initialization of head so it can be in BSS */
if (!head) head = &builtin;
Expand All @@ -54,7 +58,7 @@ int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
if (slot==COUNT) {
struct fl *new_fl = calloc(sizeof(struct fl), 1);
if (!new_fl) {
UNLOCK(lock);
WEAK_UNLOCK(lock);
return -1;
}
new_fl->next = head;
Expand All @@ -67,7 +71,7 @@ int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
head->a[slot] = arg;
slot++;

UNLOCK(lock);
WEAK_UNLOCK(lock);
return 0;
}

Expand Down
3 changes: 2 additions & 1 deletion libc-top-half/musl/src/internal/locale_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ struct __locale_map {
};

#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
extern hidden volatile int __locale_lock[1];
#include "lock.h"
extern hidden __lock_t __locale_lock[1];
#endif

extern hidden const struct __locale_map __c_dot_utf8;
Expand Down
Loading
Loading