Skip to content

Commit e2507dd

Browse files
WASIp3 Cooperative Threading (#799)
Currently a draft while the LLVM patches merge and I get all of this ready for review --------- Co-authored-by: Alex Crichton <alex@alexcrichton.com>
1 parent 5442cb2 commit e2507dd

142 files changed

Lines changed: 2583 additions & 232 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ if (CMAKE_HOST_WIN32)
2626
set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
2727
endif()
2828

29+
set(TARGET_TRIPLE "wasm32-wasip1" CACHE STRING "WASI target to test")
30+
set(CMAKE_C_COMPILER_TARGET ${TARGET_TRIPLE})
31+
32+
# We're building libc, and the compiler being used may not have a wasm sysroot
33+
# for libc, so skip this check. Otherwise the `project` call below attempts a
34+
# link to see if the compiler is working and if that fails it doesn't mean it
35+
# doesn't work. Let the build keep going to see what happens.
36+
set(CMAKE_C_COMPILER_WORKS 1)
37+
2938
project(wasi-libc LANGUAGES C ASM)
3039

3140
if(NOT CMAKE_C_COMPILER_ID MATCHES Clang)
@@ -36,7 +45,6 @@ message(STATUS "Found executable for `nm`: ${CMAKE_NM}")
3645
message(STATUS "Found executable for `ar`: ${CMAKE_AR}")
3746
message(STATUS "Found executable for `ranlib`: ${CMAKE_RANLIB}")
3847

39-
set(TARGET_TRIPLE "wasm32-wasip1" CACHE STRING "WASI target to test")
4048
# Note: thin LTO here is just for experimentation. It has known issues:
4149
# - https://github.com/llvm/llvm-project/issues/91700
4250
# - https://github.com/llvm/llvm-project/issues/91711
@@ -51,6 +59,7 @@ option(BUILD_SHARED "Whether or not to build shared libraries" ON)
5159
option(CHECK_SYMBOLS "Whether or not to check the exported symbols of libc.a" OFF)
5260
set(WASI_SDK_VERSION "" CACHE STRING "Version information for wasi-sdk to embed in headers")
5361
option(ENABLE_WERROR "Whether to compile with `-Werror`" OFF)
62+
option(ENABLE_COOP_THREADS "Whether to compile with cooperative threads support" OFF)
5463

5564
if(TARGET_TRIPLE MATCHES "-threads$")
5665
set(WASI p1)
@@ -86,10 +95,10 @@ else()
8695
endif()
8796

8897
if(TARGET_TRIPLE MATCHES "-threads$")
89-
set(THREADS ON)
9098
add_compile_options(-mthread-model posix -pthread -ftls-model=local-exec -matomics)
99+
elseif(ENABLE_COOP_THREADS)
100+
add_compile_options(-mthread-model posix -pthread -ftls-model=local-exec)
91101
else()
92-
set(THREADS OFF)
93102
add_compile_options(-mthread-model single)
94103
endif()
95104

@@ -209,6 +218,28 @@ if (ENABLE_WERROR)
209218
add_compile_options(-Werror)
210219
endif()
211220

221+
# =============================================================================
222+
# Detection of a libcall thread context for wasip3
223+
224+
include(CheckSourceCompiles)
225+
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
226+
check_source_compiles(C [[
227+
#ifndef __wasm_libcall_thread_context__
228+
#error "missing define"
229+
#endif
230+
]] HAVE_WASM_LIBCALL_THREAD_CONTEXT)
231+
232+
if(ENABLE_COOP_THREADS)
233+
if(NOT WASI STREQUAL "p3")
234+
message(FATAL_ERROR "Cooperative threads are only supported on WASIp3")
235+
endif()
236+
if (NOT HAVE_WASM_LIBCALL_THREAD_CONTEXT)
237+
message(FATAL_ERROR "Cooperative threads require clang 23 or later")
238+
endif()
239+
set(__wasi_cooperative_threads__ ON)
240+
else()
241+
endif()
242+
212243
# =============================================================================
213244
# Helper functions for adding libraries.
214245

@@ -259,7 +290,7 @@ function(add_internal_shared_library name)
259290
add_library(${name} SHARED EXCLUDE_FROM_ALL ${ARGN})
260291
set_pic(${name})
261292
target_link_libraries(${name} PUBLIC musl-top-half-interface)
262-
add_dependencies(${name} sysroot-c builtins)
293+
add_dependencies(${name} sysroot-c builtins sysroot-empty-pthread)
263294
target_compile_options(${name} PRIVATE -fvisibility=default)
264295
set_target_properties(${name} PROPERTIES NO_SONAME 1)
265296
clang_format_target(${name})

cmake/check-symbols.cmake

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ add_custom_command(
2222
${CMAKE_CURRENT_LIST_DIR}/scripts/run-check-symbols.cmake
2323
)
2424

25-
if(THREADS)
26-
set(expected "${CMAKE_SOURCE_DIR}/expected/wasm32-wasip1-threads")
27-
elseif(WASI STREQUAL "p1")
28-
set(expected "${CMAKE_SOURCE_DIR}/expected/wasm32-wasip1")
25+
if(WASI STREQUAL "p1")
26+
if(TARGET_TRIPLE MATCHES "threads")
27+
set(expected "${CMAKE_SOURCE_DIR}/expected/wasm32-wasip1-threads")
28+
else()
29+
set(expected "${CMAKE_SOURCE_DIR}/expected/wasm32-wasip1")
30+
endif()
2931
elseif(WASI STREQUAL "p2")
3032
set(expected "${CMAKE_SOURCE_DIR}/expected/wasm32-wasip2")
3133
elseif(WASI STREQUAL "p3")

cmake/clang-format.cmake

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ set(formatted_sources)
2121

2222
function(clang_format_file file)
2323
if (file MATCHES "__generated" OR
24-
file MATCHES "wasip.\.c$") # Skip auto-generated files
24+
file MATCHES "wasip.\.c$" OR # Skip auto-generated files
25+
file MATCHES "\.(s|S)$") # Skip assembly files
2526
return()
2627
endif()
2728
cmake_path(ABSOLUTE_PATH file BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE src)
@@ -30,7 +31,7 @@ function(clang_format_file file)
3031
# excludes upstream projects like cloudlibc/musl, malloc implementations, etc.
3132
if (NOT EXISTS ${src}
3233
OR ${src} MATCHES "cloudlibc"
33-
OR ${src} MATCHES "libc-top-half"
34+
OR (${src} MATCHES "libc-top-half" AND NOT ${src} MATCHES "libc-top-half/musl/src/thread/coop-threads")
3435
OR ${src} MATCHES "fts/musl-fts"
3536
OR ${src} MATCHES "dlmalloc"
3637
OR ${src} MATCHES "emmalloc"

cmake/wasm-component-ld.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ if (NOT WASM_COMPONENT_LD_EXECUTABLE)
1010
ba_download(
1111
wasm-component-ld
1212
"https://github.com/bytecodealliance/wasm-component-ld"
13-
"v0.5.21"
13+
"v0.5.25"
1414
)
1515
ExternalProject_Get_Property(wasm-component-ld SOURCE_DIR)
1616
set(WASM_COMPONENT_LD_EXECUTABLE "${SOURCE_DIR}/wasm-component-ld")

expected/wasm32-wasip1-threads/defined-symbols.txt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ __SIG_ERR
1313
__SIG_IGN
1414
__acquire_ptc
1515
__aio_close
16+
__allocate_tls
1617
__asctime_r
1718
__assert_fail
18-
__at_quick_exit_lockptr
19-
__atexit_lockptr
2019
__c_dot_utf8
2120
__c_dot_utf8_locale
2221
__c_locale
@@ -81,6 +80,7 @@ __ftello
8180
__ftello_unlocked
8281
__funcs_on_exit
8382
__funcs_on_quick_exit
83+
__futexwait
8484
__futimesat
8585
__fwritable
8686
__fwritex
@@ -92,6 +92,7 @@ __getopt_msg
9292
__gmtime_r
9393
__hwcap
9494
__inet_aton
95+
__inhibit_ptc
9596
__init_ssp
9697
__init_tp
9798
__intscan
@@ -148,7 +149,6 @@ __libc_free
148149
__libc_malloc
149150
__loc_is_allocated
150151
__locale_lock
151-
__locale_lockptr
152152
__localtime_r
153153
__lock
154154
__lockfile
@@ -219,7 +219,6 @@ __pthread_tsd_size
219219
__putenv
220220
__qsort_r
221221
__rand48_step
222-
__random_lockptr
223222
__reallocarray
224223
__register_locked_file
225224
__release_ptc
@@ -248,7 +247,6 @@ __stdin_used
248247
__stdio_close
249248
__stdio_exit
250249
__stdio_exit_needed
251-
__stdio_ofl_lockptr
252250
__stdio_read
253251
__stdio_seek
254252
__stdio_write
@@ -308,6 +306,7 @@ __unlockfile
308306
__uselocale
309307
__utc
310308
__wait
309+
__wake
311310
__wasi_args_get
312311
__wasi_args_sizes_get
313312
__wasi_clock_res_get
@@ -359,7 +358,6 @@ __wasi_thread_start_C
359358
__wasilibc_access
360359
__wasilibc_cwd
361360
__wasilibc_cwd_lock
362-
__wasilibc_cwd_unlock
363361
__wasilibc_deinitialize_environ
364362
__wasilibc_dttoif
365363
__wasilibc_enable_futex_busywait_on_current_thread
@@ -946,6 +944,9 @@ modff
946944
modfl
947945
mprotect
948946
mrand48
947+
mtx_destroy
948+
mtx_init
949+
mtx_timedlock
949950
munmap
950951
nan
951952
nanf

libc-bottom-half/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@ if (WASI STREQUAL "p3")
179179
)
180180
endif()
181181

182+
if (HAVE_WASM_LIBCALL_THREAD_CONTEXT)
183+
list(APPEND bottom_half_sources
184+
sources/__libcall_thread_context.S
185+
sources/__wasm_init_task.S
186+
)
187+
endif()
188+
182189
# Don't export symbols of generated code in shared libraries, so specifically
183190
# pass `-fvisibility=hidden`.
184191
set_source_files_properties(sources/wasip2.c PROPERTIES

libc-bottom-half/cloudlibc/src/libc/sched/sched_yield.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77
#include <sched.h>
88

99
int sched_yield(void) {
10-
#ifdef __wasip1__
10+
#ifdef __wasi_cooperative_threads__
11+
#ifdef __wasip3__
12+
wasip3_thread_yield();
13+
return 0;
14+
#else
15+
#error "Unknown WASI version"
16+
#endif
17+
18+
#elif defined(__wasip1__)
1119
__wasi_errno_t error = __wasi_sched_yield();
1220
if (error != 0) {
1321
errno = error;

libc-bottom-half/cloudlibc/src/libc/unistd/pwrite.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset) {
8383
&closed);
8484
filesystem_stream_u8_drop_writable(writer);
8585

86-
// Wait for the subtask to resolve now that the writer half is closed and if
86+
// Wait for the future to resolve now that the writer half is closed and if
8787
// we failed to write bytes (0 bytes written) and the result is an error we
8888
// can return -1.
8989
filesystem_result_void_error_code_t result;

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ extern void __wasm_call_ctors(void);
99
extern int __main_void(void);
1010
extern void __wasm_call_dtors(void);
1111

12+
#ifdef __wasm_libcall_thread_context__
13+
// Force __wasm_init_task and __wasm_init_async_task to be linked in for wasip3
14+
extern void __wasm_init_task(void);
15+
extern void __wasm_init_async_task(void);
16+
__attribute__((used)) void *__wasm_init_task_ref = __wasm_init_task;
17+
__attribute__((used)) void *__wasm_init_async_task_ref = __wasm_init_async_task;
18+
#endif
19+
1220
#if defined(__wasip1__)
1321
__attribute__((export_name("_start"))) void _start(void)
1422
#elif defined(__wasip2__)

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
extern void __wasi_init_tp(void);
55
extern void __wasm_call_ctors(void);
66

7+
#ifdef __wasm_libcall_thread_context__
8+
// Force __wasm_init_task and __wasm_init_async_task to be linked in for wasip3
9+
extern void __wasm_init_task(void);
10+
extern void __wasm_init_async_task(void);
11+
__attribute__((used)) static void *__wasm_init_task_ref = __wasm_init_task;
12+
__attribute__((used)) static void *__wasm_init_async_task_ref =
13+
__wasm_init_async_task;
14+
#endif
15+
716
__attribute__((export_name("_initialize"))) void _initialize(void) {
817
#if defined(_REENTRANT)
918
static volatile atomic_int initialized = 0;

0 commit comments

Comments
 (0)