From 494d4c5cf096794812a38ed520cfd42fc33dd2ae Mon Sep 17 00:00:00 2001 From: yowl Date: Sat, 5 Jul 2025 07:42:34 -0500 Subject: [PATCH 01/17] Add packages and CI for multithreaded debug config. --- docs/workflow/building/coreclr/nativeaot.md | 20 ++ eng/native/configurecompiler.cmake | 4 + eng/native/gen-buildsys.cmd | 5 + eng/pipelines/common/platform-matrix.yml | 38 ++++ .../libraries/helix-queues-setup.yml | 2 +- eng/pipelines/runtimelab.yml | 19 ++ .../runtimelab-post-build-steps.yml | 16 +- .../Microsoft.NETCore.Native.targets | 2 + src/coreclr/nativeaot/CMakeLists.txt | 6 + .../nativeaot/Runtime/unix/PalRedhawkUnix.cpp | 2 + .../nativeaot/Runtime/wasm/PalRedhawkWasm.cpp | 175 ++++++++++++++++++ .../nativeaot/Runtime/wasm/PalRedhawkWasm.h | 5 +- .../src/System.Private.CoreLib.csproj | 7 + .../src/System/Threading/Monitor.NativeAot.cs | 2 + .../PortableThreadPool.NativeAot.Browser.cs | 19 ++ .../Threading/ThreadPool.NativeAot.Browser.cs | 11 ++ .../pkg/projects/nativeaot-packages.proj | 3 +- .../Browser/Interop.Runtime.NativeAOT.cs | 24 +++ src/mono/browser/runtime/loader/polyfills.ts | 3 +- src/native/external/zlib-ng.cmake | 5 + src/tests/Common/dirs.proj | 8 + src/tests/build.proj | 1 + .../SmokeTests/HelloWasm/HelloWasm.cs | 2 + .../SmokeTests/HelloWasm/HelloWasm.csproj | 1 + 24 files changed, 373 insertions(+), 7 deletions(-) create mode 100644 src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/PortableThreadPool.NativeAot.Browser.cs create mode 100644 src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.NativeAot.Browser.cs diff --git a/docs/workflow/building/coreclr/nativeaot.md b/docs/workflow/building/coreclr/nativeaot.md index bb3d2817da0c..caed73753f5f 100644 --- a/docs/workflow/building/coreclr/nativeaot.md +++ b/docs/workflow/building/coreclr/nativeaot.md @@ -76,6 +76,26 @@ You should now be able to publish the project for Wasm: `dotnet publish -r brows Once you build the repo, you can use the produced binaries in one of four ways specified below ("Using built binaries", "Building packages", "Convenience Visual Studio "repro" project", "Running tests"). +## Building for Multithreaded packages + +This is a work in progress and far from functional. Currentlty there exists just enough infrastucture to build packages for mutlithreaded runtime and libs, but they are not functional in the sense that they support multithreaded programs yet. To build the WASI packages: +``` +build clr.aot+libs+nativeaot.packages -c Debug -a wasm -os wasi -cmakeargs -DCLR_CMAKE_TARGET_OS_SUBGROUP=multithread '/p:WasmEnableThreads=true' +``` +To build the browser multithreaded packages: +``` +build clr.aot+libs+nativeaot.packages -c Debug -a wasm -os browser -cmakeargs -DCLR_CMAKE_TARGET_OS_SUBGROUP=multithread '/p:WasmEnableThreads=true' +``` +To build the runtime tests for WASI +``` +src\tests\build nativeaot Debug wasm tree nativeaot wasi /p:LibrariesConfiguration=debug /p:TestWrapperTargetsWindows=true /p:WasmEnableThreads=true +``` +To build the runtime tests for browser +``` +src\tests\build nativeaot Debug wasm tree nativeaot browser /p:LibrariesConfiguration=debug /p:TestWrapperTargetsWindows=true /p:WasmEnableThreads=true +``` + + ### Using built binaries In this workflow, you have a project file that you want to `dotnet publish`, but you want to use your own build of the compiler/runtime/framework. You need to be using a daily build of the .NET SDK downloaded from the dotnet/sdk repo. It's typically enough to just download the daily build ZIP file, unpack it, and make sure the unpacked directory is the first thing in your PATH. Don't forget to add a NuGet.config as specified by the dotnet/sdk repo- you'll hit restore issues otherwise. diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index b4aaa7fedbf5..d99e6c4bacf5 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -148,6 +148,10 @@ elseif (CLR_CMAKE_HOST_UNIX) add_compile_options(-Wno-alloca) add_compile_options(-Wno-implicit-int-float-conversion) endif() + + if (CLR_CMAKE_TARGET_OS_SUBGROUP STREQUAL multithread AND CLR_CMAKE_HOST_BROWSER) + add_compile_options(-pthread) + endif(CLR_CMAKE_TARGET_OS_SUBGROUP STREQUAL multithread AND CLR_CMAKE_HOST_BROWSER) endif(MSVC) if (CLR_CMAKE_ENABLE_SANITIZERS) diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd index b78a073c8c11..b52efd372156 100644 --- a/eng/native/gen-buildsys.cmd +++ b/eng/native/gen-buildsys.cmd @@ -65,6 +65,11 @@ if /i "%__Arch%" == "wasm" ( set "WASI_SDK_PATH=!WASI_SDK_PATH:\=/!" if not "!WASI_SDK_PATH:~-1!" == "/" set "WASI_SDK_PATH=!WASI_SDK_PATH!/" set __CmakeGenerator=Ninja + if defined __CMakeArgs ( + if not "!__CMakeArgs:multithread=!" == "!__CMakeArgs!" ( + set __ExtraCmakeParams=%__ExtraCmakeParams% -D_WASI_EMULATED_PTHREAD + ) + ) set __ExtraCmakeParams=%__ExtraCmakeParams% -DCLR_CMAKE_TARGET_OS=wasi -DCLR_CMAKE_TARGET_ARCH=wasm "-DWASI_SDK_PREFIX=!WASI_SDK_PATH!" "-DCMAKE_TOOLCHAIN_FILE=!WASI_SDK_PATH!/share/cmake/wasi-sdk-p2.cmake" "-DCMAKE_SYSROOT=!WASI_SDK_PATH!share/wasi-sysroot" "-DCMAKE_CROSSCOMPILING_EMULATOR=node --experimental-wasm-bigint --experimental-wasi-unstable-preview1" ) ) else ( diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index c0d705a4cf6f..699c0cef3959 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -500,6 +500,44 @@ jobs: buildConfig: ${{ parameters.buildConfig }} ${{ insert }}: ${{ parameters.jobParameters }} +- ${{ if containsValue(parameters.platforms, 'wasi_multithread_wasm_win') }}: + - template: xplat-setup.yml + parameters: + jobTemplate: ${{ parameters.jobTemplate }} + helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} + variables: ${{ parameters.variables }} + osGroup: wasi + osSubgroup: multithread + archType: wasm + targetRid: wasi-wasm + platform: wasi_multithread_wasm_win + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} + jobParameters: + hostedOs: windows + runtimeFlavor: ${{ parameters.runtimeFlavor }} + stagedBuild: ${{ parameters.stagedBuild }} + buildConfig: ${{ parameters.buildConfig }} + ${{ insert }}: ${{ parameters.jobParameters }} + +- ${{ if containsValue(parameters.platforms, 'browser_multithread_wasm_win') }}: + - template: xplat-setup.yml + parameters: + jobTemplate: ${{ parameters.jobTemplate }} + helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} + variables: ${{ parameters.variables }} + osGroup: browser + osSubgroup: multithread + archType: wasm + targetRid: browser-wasm + platform: browser_multithread_wasm_win + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} + jobParameters: + hostedOs: windows + runtimeFlavor: ${{ parameters.runtimeFlavor }} + stagedBuild: ${{ parameters.stagedBuild }} + buildConfig: ${{ parameters.buildConfig }} + ${{ insert }}: ${{ parameters.jobParameters }} + # WebAssembly Linux for NAOT-LLVM # Use a different name to differentiate from upstream as we need the -sanitizer image to get build tools that are not present in the stock browser_wasm image. diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 46f897e80b25..49c46621806b 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -175,7 +175,7 @@ jobs: - (Ubuntu.2204.Amd64)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-webassembly # Browser WebAssembly windows - - ${{ if in(parameters.platform, 'browser_wasm_win', 'wasi_wasm_win') }}: + - ${{ if in(parameters.platform, 'browser_wasm_win', 'wasi_wasm_win', 'browser_multithread_wasm_win', 'wasi_multithread_wasm_win') }}: - (Windows.Amd64.Server2022.Open)windows.amd64.server2022.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2022-helix-webassembly - (Windows.Server2025.Amd64.Open)windows.server2025.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2025-helix-webassembly-amd64 diff --git a/eng/pipelines/runtimelab.yml b/eng/pipelines/runtimelab.yml index 29e389806642..9ea034695f99 100644 --- a/eng/pipelines/runtimelab.yml +++ b/eng/pipelines/runtimelab.yml @@ -71,6 +71,25 @@ extends: parameters: librariesConfiguration: Debug + # + # Build and test Wasm Debug multithreaded libraries and Debug runtime + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + buildConfig: debug + platforms: + - browser_multithread_wasm_win + - wasi_multithread_wasm_win + jobParameters: + timeoutInMinutes: 300 + buildArgs: -s clr.aot+libs -c debug -rc $(_BuildConfig) -cmakeargs -DCLR_CMAKE_TARGET_OS_SUBGROUP=multithread '/p:WasmEnableThreads=true' + postBuildSteps: + - template: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml + parameters: + librariesConfiguration: Debug + # # Build and test with Debug libraries and Checked runtime # diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml index 24c039f8865d..3687e683097e 100644 --- a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -31,8 +31,17 @@ steps: displayName: Set up ILC emulation environment - ${{ if eq(parameters.archType, 'wasm') }}: - - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.osGroup }} $(crossArg) $(_officialBuildParameter) ci tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} - displayName: Build runtime tests + - ${{ if eq(parameters.platform, 'browser_multithread_wasm_win') }}: + - script: | + $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} $(crossArg) $(_officialBuildParameter) ci browser tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} /p:WasmEnableThreads=true + displayName: Build WebAssembly browser Mutlithread runtime tests + - ${{ elseif eq(parameters.platform, 'wasi_multithread_wasm_win') }}: + - script: | + $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} $(crossArg) $(_officialBuildParameter) ci wasi tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} /p:WasmEnableThreads=true + displayName: Build WebAssembly wasi Mutlithread runtime tests + - ${{ else }}: + - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.osGroup }} $(crossArg) $(_officialBuildParameter) ci tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} + displayName: Build runtime tests - ${{ else }}: - ${{ if eq(parameters.osGroup, 'windows') }}: - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} $(crossArg) $(_officialBuildParameter) ci tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} @@ -49,7 +58,7 @@ steps: displayName: Run runtime tests # Don't compile/run the libraries tests with emulated ILC to save CI time/resources. - - ${{ if and(eq(parameters.archType, 'wasm'), eq(parameters.nameSuffix, '')) }}: + - ${{ if and(and(eq(parameters.archType, 'wasm'), eq(parameters.nameSuffix, '')), not(in(parameters.platform, 'browser_multithread_wasm_win', 'wasi_multithread_wasm_win'))) }}: - script: $(Build.SourcesDirectory)/build$(scriptExt) libs.tests -test -a ${{ parameters.archType }} -os ${{ parameters.osGroup }} -lc ${{ parameters.librariesConfiguration }} -rc $(buildConfigUpper) /p:TestNativeAot=true /p:RunSmokeTestsOnly=true displayName: Build and run WebAssembly libraries tests @@ -61,3 +70,4 @@ steps: - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml parameters: name: ${{ parameters.platform }}${{ parameters.nameSuffix }} + \ No newline at end of file diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index d1ea61f025f9..bde4444d5e23 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -438,6 +438,7 @@ The .NET Foundation licenses this file to you under the MIT license. $(CompileWasmArgs) -g3 $(CompileWasmArgs) -mnontrapping-fptoint $(CompileWasmArgs) -fwasm-exceptions + $(CompileWasmArgs) -pthread -matomics -mbulk-memory @@ -608,6 +609,7 @@ The .NET Foundation licenses this file to you under the MIT license. + diff --git a/src/coreclr/nativeaot/CMakeLists.txt b/src/coreclr/nativeaot/CMakeLists.txt index aff6c47180c9..babf87150dde 100644 --- a/src/coreclr/nativeaot/CMakeLists.txt +++ b/src/coreclr/nativeaot/CMakeLists.txt @@ -32,6 +32,12 @@ if(CLR_CMAKE_TARGET_OS STREQUAL wasi) add_definitions(-DTARGET_UNIX) endif(CLR_CMAKE_TARGET_OS STREQUAL wasi) +if((CLR_CMAKE_TARGET_OS STREQUAL wasi OR CLR_CMAKE_TARGET_OS STREQUAL emscripten) + AND CLR_CMAKE_TARGET_OS_SUBGROUP STREQUAL multithread) + add_definitions(-DFEATURE_WASM_MANAGED_THREADS) +endif((CLR_CMAKE_TARGET_OS STREQUAL wasi OR CLR_CMAKE_TARGET_OS STREQUAL emscripten) + AND CLR_CMAKE_TARGET_OS_SUBGROUP STREQUAL multithread) + if(CLR_CMAKE_TARGET_ANDROID) add_definitions(-DFEATURE_EMULATED_TLS) endif() diff --git a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp index 5456ed029459..3448494fbce8 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp @@ -1151,6 +1151,8 @@ REDHAWK_PALEXPORT bool PalGetMaximumStackBounds(_Out_ void** ppStackLowOut, _Out { #if defined(HOST_WASM) && !defined(FEATURE_WASM_MANAGED_THREADS) PalGetMaximumStackBounds_SingleThreadedWasm(&pStackLowOut, &pStackHighOut); +#elif defined(HOST_WASM) && defined(FEATURE_WASM_MANAGED_THREADS) + PalGetMaximumStackBounds_MultiThreadedWasm(&pStackLowOut, &pStackHighOut); #elif defined(__APPLE__) // This is a Mac specific method pStackHighOut = pthread_get_stackaddr_np(pthread_self()); diff --git a/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.cpp b/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.cpp index a210ddaa4245..60b2a2b0400d 100644 --- a/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.cpp +++ b/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.cpp @@ -191,6 +191,181 @@ extern "C" int __cxa_thread_atexit(Dtor dtor, void* obj, void*) #endif // TARGET_WASI #endif // !FEATURE_WASM_MANAGED_THREADS +// TODO-LLVM: For now, a copy of the single threaded implementation. +#ifdef FEATURE_WASM_MANAGED_THREADS +int __cxa_thread_atexit(void (*func)(), void *obj, void *dso_symbol) +{ + return 0; +} + +// +// Note that we return the native stack bounds here, not shadow stack ones. Currently this functionality is mainly +// used for RuntimeHelpers.TryEnsureSufficientExecutionStack, and we do use the native stack in codegen, so this +// is an acceptable approximation. +// +extern "C" unsigned char __stack_low; +extern "C" unsigned char __stack_high; +void PalGetMaximumStackBounds_MultiThreadedWasm(void** ppStackLowOut, void** ppStackHighOut) +{ + // See https://github.com/emscripten-core/emscripten/pull/18057 and https://reviews.llvm.org/D135910. + unsigned char* pStackLow = &__stack_low; + unsigned char* pStackHigh = &__stack_high; + + // Sanity check that we have the expected memory layout. + ASSERT((pStackHigh - pStackLow) >= 64 * 1024); + if (pStackLow >= pStackHigh) + { + PalPrintFatalError("\nFatal error. Unexpected stack layout.\n"); + RhFailFast(); + } + + *ppStackLowOut = pStackLow; + *ppStackHighOut = pStackHigh; +} + +#ifdef TARGET_WASI +// TODO-LLVM: No-op stubs, maybe when threads are implemented in WASI, we wont have to provide all of these. +int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *) +{ + return 0; +} + +int pthread_mutexattr_init(pthread_mutexattr_t *) +{ + return 0; +} + +int pthread_mutexattr_settype(pthread_mutexattr_t *, int) +{ + return 0; +} + +int pthread_mutex_destroy(pthread_mutex_t *) +{ + return 0; +} + +int pthread_mutexattr_destroy(pthread_mutexattr_t *) +{ + return 0; +} + +int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *) +{ + return 0; +} + +int pthread_cond_destroy(pthread_cond_t *) +{ + return 0; +} + +int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *) +{ + return 0; +} + +int pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, const struct timespec *) +{ + return 0; +} + +int pthread_condattr_init(pthread_condattr_t *) +{ + return 0; +} + +int pthread_mutex_lock(pthread_mutex_t *) +{ + return 0; +} + +int pthread_mutex_unlock(pthread_mutex_t *) +{ + return 0; +} + +pthread_t pthread_self(void) +{ + return (pthread_t)0; +} + +int pthread_equal(pthread_t, pthread_t) +{ + return 1; +} + +int pthread_attr_init(pthread_attr_t *) +{ + return 0; +} + +int pthread_attr_destroy(pthread_attr_t *) +{ + return 0; +} + +int pthread_condattr_destroy(pthread_condattr_t *) +{ + return 0; +} + +int pthread_cond_broadcast(pthread_cond_t *) +{ + return 0; +} + +int pthread_attr_setdetachstate(pthread_attr_t *, int) +{ + return 0; +} + +using Dtor = void(*)(void*); + +// TODO=LLVM: This is a copy of the single threaded implementation. +extern "C" int __cxa_thread_atexit(Dtor dtor, void* obj, void*) +{ + struct DtorList + { + Dtor dtor; + void* obj; + DtorList* next; + }; + + struct DtorsManager + { + DtorList* m_dtors = nullptr; + + ~DtorsManager() + { + while (DtorList* head = m_dtors) + { + m_dtors = head->next; + head->dtor(head->obj); + free(head); + } + } + }; + + // The linked list of "thread-local" destructors to run. + static DtorsManager s_dtorsManager; + + DtorList* head = static_cast(malloc(sizeof(DtorList))); + if (head == nullptr) + { + return -1; + } + + head->dtor = dtor; + head->obj = obj; + head->next = s_dtorsManager.m_dtors; + s_dtorsManager.m_dtors = head; + + return 0; +} +#endif // TARGET_WASI +#endif // FEATURE_WASM_MANAGED_THREADS + // Recall that WASM's model is extremely simple: we have one linear memory, which can only be grown, in chunks // of 64K pages. Thus, "mmap"/"munmap" fundamentally cannot be faithfully recreated and the Unix emulators we // layer on top of (Emscripten/WASI libc) reflect this by not supporting the scenario. Fortunately, the current diff --git a/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.h b/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.h index 3030a582b58a..ff75454e6aba 100644 --- a/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.h +++ b/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.h @@ -1,6 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#ifndef FEATURE_WASM_MANAGED_THREADS +#ifdef FEATURE_WASM_MANAGED_THREADS +int __cxa_thread_atexit(void (*func)(), void *obj, void *dso_symbol); +void PalGetMaximumStackBounds_MultiThreadedWasm(void** ppStackLowOut, void** ppStackHighOut); +#else void PalGetMaximumStackBounds_SingleThreadedWasm(void** ppStackLowOut, void** ppStackHighOut); #endif // !FEATURE_WASM_MANAGED_THREADS diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 7f09dfcc7608..36ba9d7bac4a 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -35,6 +35,11 @@ true true + + true + true + $(DefineConstants);FEATURE_WASM_MANAGED_THREADS + $(DefineConstants);FEATURE_WASM_PERFTRACING true @@ -347,6 +352,8 @@ + + diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Monitor.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Monitor.NativeAot.cs index 4c90bbaa42ad..9c33774f1619 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Monitor.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Monitor.NativeAot.cs @@ -143,7 +143,9 @@ public static bool IsEntered(object obj) #region Public Wait/Pulse methods +#if !FEATURE_WASM_MANAGED_THREADS [UnsupportedOSPlatform("browser")] +#endif public static bool Wait(object obj, int millisecondsTimeout) { return GetCondition(obj).Wait(millisecondsTimeout, obj); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/PortableThreadPool.NativeAot.Browser.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/PortableThreadPool.NativeAot.Browser.cs new file mode 100644 index 000000000000..cc3f606fe627 --- /dev/null +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/PortableThreadPool.NativeAot.Browser.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Threading; + +internal sealed partial class PortableThreadPool +{ + private static partial class WorkerThread + { + private static bool IsIOPending => false; + } + + private struct CpuUtilizationReader + { +#pragma warning disable CA1822 + public double CurrentUtilization => 0.0; // FIXME: can we do better +#pragma warning restore CA1822 + } +} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.NativeAot.Browser.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.NativeAot.Browser.cs new file mode 100644 index 000000000000..ca2656955006 --- /dev/null +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.NativeAot.Browser.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Threading; + +public static partial class ThreadPool +{ + // Indicates whether the thread pool should yield the thread from the dispatch loop to the runtime periodically so that + // the runtime may use the thread for processing other work + internal static bool YieldFromDispatchLoop => true; +} diff --git a/src/installer/pkg/projects/nativeaot-packages.proj b/src/installer/pkg/projects/nativeaot-packages.proj index 8a640a9c08c0..0a1404df62c1 100644 --- a/src/installer/pkg/projects/nativeaot-packages.proj +++ b/src/installer/pkg/projects/nativeaot-packages.proj @@ -4,7 +4,8 @@ - + + diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.NativeAOT.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.NativeAOT.cs index 3d2fdaae538d..7f33ff8ae73c 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.NativeAOT.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.NativeAOT.cs @@ -28,6 +28,30 @@ internal static unsafe partial class Runtime [LibraryImport(JSLibrary, EntryPoint = "mono_wasm_cancel_promise", StringMarshalling = StringMarshalling.Utf16)] public static unsafe partial void CancelPromise(IntPtr gcHandle); +#if FEATURE_WASM_MANAGED_THREADS + // Required by JavaScript/JSFunctionBinding.cs + [LibraryImport(JSLibrary, EntryPoint = "mono_wasm_invoke_js_function_send")] + public static unsafe partial void InvokeJSFunctionSend(nint targetNativeTID, nint functionHandle, nint data); + [LibraryImport(JSLibrary, EntryPoint = "mono_wasm_invoke_jsimport_MT")] + public static unsafe partial void InvokeJSImportSync(nint signature, nint args); + [LibraryImport(JSLibrary, EntryPoint = "mono_wasm_invoke_jsimport_sync_send")] + public static unsafe partial void InvokeJSImportSyncSend(nint targetNativeTID, nint signature, nint args); + [LibraryImport(JSLibrary, EntryPoint = "mono_wasm_invoke_jsimport_async_post")] + public static unsafe partial void InvokeJSImportAsyncPost(nint targetNativeTID, nint signature, nint args); + [LibraryImport(JSLibrary, EntryPoint = "mono_wasm_resolve_or_reject_promise_post")] + public static unsafe partial void ResolveOrRejectPromisePost(nint targetNativeTID, nint data); + [LibraryImport(JSLibrary, EntryPoint = "mono_wasm_install_js_worker_interop_wrapper")] + public static unsafe partial void InstallWebWorkerInterop(nint proxyContextGCHandle, void* beforeSyncJSImport, void* afterSyncJSImport, void* pumpHandler); + // Required by JavaScript/JSProxyContext.cs + [LibraryImport(JSLibrary, EntryPoint = "mono_wasm_release_cs_owned_object_post")] + internal static unsafe partial void ReleaseCSOwnedObjectPost(nint targetNativeTID, nint jsHandle); + [LibraryImport(JSLibrary, EntryPoint = "mono_wasm_uninstall_js_worker_interop")] + public static unsafe partial void UninstallWebWorkerInterop(); + // Required by JavaScript/CancelablePromise.cs + [LibraryImport(JSLibrary, EntryPoint = "mono_wasm_cancel_promise_post")] + public static unsafe partial void CancelPromisePost(nint targetNativeTID, nint taskHolderGCHandle); +#endif + #region Not used by NativeAOT public static IntPtr RegisterGCRoot(void* start, int bytesSize, IntPtr name) => throw new NotImplementedException(); public static void DeregisterGCRoot(IntPtr handle) => throw new NotImplementedException(); diff --git a/src/mono/browser/runtime/loader/polyfills.ts b/src/mono/browser/runtime/loader/polyfills.ts index 181323b0fe0a..4b230101a57f 100644 --- a/src/mono/browser/runtime/loader/polyfills.ts +++ b/src/mono/browser/runtime/loader/polyfills.ts @@ -22,7 +22,8 @@ export function verifyEnvironment () { mono_assert(ENVIRONMENT_IS_SHELL || typeof globalThis.URL === "function", "This browser/engine doesn't support URL API. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); mono_assert(typeof globalThis.BigInt64Array === "function", "This browser/engine doesn't support BigInt64Array API. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); if (WasmEnableThreads) { - mono_assert(!ENVIRONMENT_IS_SHELL && !ENVIRONMENT_IS_NODE, "This build of dotnet is multi-threaded, it doesn't support shell environments like V8 or NodeJS. See also https://aka.ms/dotnet-wasm-features"); + // TODO-LLVM: Comment this check out for now so we can run at least some tests. + //mono_assert(!ENVIRONMENT_IS_SHELL && !ENVIRONMENT_IS_NODE, "This build of dotnet is multi-threaded, it doesn't support shell environments like V8 or NodeJS. See also https://aka.ms/dotnet-wasm-features"); mono_assert(globalThis.SharedArrayBuffer !== undefined, "SharedArrayBuffer is not enabled on this page. Please use a modern browser and set Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy http headers. See also https://aka.ms/dotnet-wasm-features"); mono_assert(typeof globalThis.EventTarget === "function", "This browser/engine doesn't support EventTarget API. Please use a modern version. See also https://aka.ms/dotnet-wasm-features"); } diff --git a/src/native/external/zlib-ng.cmake b/src/native/external/zlib-ng.cmake index b2338d682e14..48110e65daf6 100644 --- a/src/native/external/zlib-ng.cmake +++ b/src/native/external/zlib-ng.cmake @@ -26,8 +26,13 @@ if (CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) # zlib-ng uses atomics, so we need to enable threads when requested for browser/wasi, otherwise the wasm target won't have thread support. if (CMAKE_USE_PTHREADS) + if (CLR_CMAKE_TARGET_BROWSER) add_compile_options(-pthread) add_linker_flag(-pthread) + else() + add_compile_options(-D_WASI_EMULATED_PTHREAD) + add_linker_flag(-Wl,-lwasi-emulated-pthread) + endif() endif() endif() diff --git a/src/tests/Common/dirs.proj b/src/tests/Common/dirs.proj index 7931d4bd7b7b..c16515c74594 100644 --- a/src/tests/Common/dirs.proj +++ b/src/tests/Common/dirs.proj @@ -29,6 +29,14 @@ + + + + + + + + diff --git a/src/tests/build.proj b/src/tests/build.proj index 66652353a200..baff7199bda3 100644 --- a/src/tests/build.proj +++ b/src/tests/build.proj @@ -490,6 +490,7 @@ $(GroupBuildCmd) "/p:MonoForceInterpreter=true" $(GroupBuildCmd) "/p:RunAOTCompilation=true" $(GroupBuildCmd) "/p:DevTeamProvisioning=$(DevTeamProvisioning)" + $(GroupBuildCmd) "/p:WasmEnableThreads=$(WasmEnableThreads)" diff --git a/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.cs b/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.cs index 0d8dd70eccf4..2c856609e13e 100644 --- a/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.cs +++ b/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.cs @@ -40,7 +40,9 @@ private static unsafe int Main(string[] args) TestMetaData(); TestGC(); +#if !NO_EXPLICIT_FINALIZER TestFinalization(); +#endif Add(1, 2); PrintLine("Hello from C#!"); diff --git a/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.csproj b/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.csproj index df4345c5e749..d6ddbd02905a 100644 --- a/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.csproj +++ b/src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.csproj @@ -10,6 +10,7 @@ true false true + $(DefineConstants);NO_EXPLICIT_FINALIZER From 46699a7b21381c8f3bcf8c4fc0d5eefa95324536 Mon Sep 17 00:00:00 2001 From: yowl Date: Mon, 7 Jul 2025 18:20:04 -0500 Subject: [PATCH 02/17] use nameSuffix in preference to new platforms. --- eng/pipelines/common/platform-matrix.yml | 40 +------------------ .../libraries/helix-queues-setup.yml | 2 +- eng/pipelines/runtimelab.yml | 6 ++- .../runtimelab-post-build-steps.yml | 6 +-- 4 files changed, 10 insertions(+), 44 deletions(-) diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index 699c0cef3959..968f92e7a5b1 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -489,6 +489,7 @@ jobs: helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} variables: ${{ parameters.variables }} osGroup: wasi + osSubGroup: ${{ parameters.osSubGroup }} archType: wasm targetRid: wasi-wasm platform: wasi_wasm_win @@ -500,44 +501,6 @@ jobs: buildConfig: ${{ parameters.buildConfig }} ${{ insert }}: ${{ parameters.jobParameters }} -- ${{ if containsValue(parameters.platforms, 'wasi_multithread_wasm_win') }}: - - template: xplat-setup.yml - parameters: - jobTemplate: ${{ parameters.jobTemplate }} - helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} - variables: ${{ parameters.variables }} - osGroup: wasi - osSubgroup: multithread - archType: wasm - targetRid: wasi-wasm - platform: wasi_multithread_wasm_win - shouldContinueOnError: ${{ parameters.shouldContinueOnError }} - jobParameters: - hostedOs: windows - runtimeFlavor: ${{ parameters.runtimeFlavor }} - stagedBuild: ${{ parameters.stagedBuild }} - buildConfig: ${{ parameters.buildConfig }} - ${{ insert }}: ${{ parameters.jobParameters }} - -- ${{ if containsValue(parameters.platforms, 'browser_multithread_wasm_win') }}: - - template: xplat-setup.yml - parameters: - jobTemplate: ${{ parameters.jobTemplate }} - helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} - variables: ${{ parameters.variables }} - osGroup: browser - osSubgroup: multithread - archType: wasm - targetRid: browser-wasm - platform: browser_multithread_wasm_win - shouldContinueOnError: ${{ parameters.shouldContinueOnError }} - jobParameters: - hostedOs: windows - runtimeFlavor: ${{ parameters.runtimeFlavor }} - stagedBuild: ${{ parameters.stagedBuild }} - buildConfig: ${{ parameters.buildConfig }} - ${{ insert }}: ${{ parameters.jobParameters }} - # WebAssembly Linux for NAOT-LLVM # Use a different name to differentiate from upstream as we need the -sanitizer image to get build tools that are not present in the stock browser_wasm image. @@ -649,6 +612,7 @@ jobs: helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} variables: ${{ parameters.variables }} osGroup: browser + osSubGroup: ${{ parameters.osSubGroup }} archType: wasm targetRid: browser-wasm platform: browser_wasm_win diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 49c46621806b..46f897e80b25 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -175,7 +175,7 @@ jobs: - (Ubuntu.2204.Amd64)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-webassembly # Browser WebAssembly windows - - ${{ if in(parameters.platform, 'browser_wasm_win', 'wasi_wasm_win', 'browser_multithread_wasm_win', 'wasi_multithread_wasm_win') }}: + - ${{ if in(parameters.platform, 'browser_wasm_win', 'wasi_wasm_win') }}: - (Windows.Amd64.Server2022.Open)windows.amd64.server2022.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2022-helix-webassembly - (Windows.Server2025.Amd64.Open)windows.server2025.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2025-helix-webassembly-amd64 diff --git a/eng/pipelines/runtimelab.yml b/eng/pipelines/runtimelab.yml index 9ea034695f99..864f62ea8139 100644 --- a/eng/pipelines/runtimelab.yml +++ b/eng/pipelines/runtimelab.yml @@ -79,12 +79,14 @@ extends: jobTemplate: /eng/pipelines/common/global-build-job.yml helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml buildConfig: debug + osSubgroup: multithread platforms: - - browser_multithread_wasm_win - - wasi_multithread_wasm_win + - browser_wasm_win + - wasi_wasm_win jobParameters: timeoutInMinutes: 300 buildArgs: -s clr.aot+libs -c debug -rc $(_BuildConfig) -cmakeargs -DCLR_CMAKE_TARGET_OS_SUBGROUP=multithread '/p:WasmEnableThreads=true' + nameSuffix: Multithreaded postBuildSteps: - template: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml parameters: diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml index 3687e683097e..163009b209e6 100644 --- a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -31,11 +31,11 @@ steps: displayName: Set up ILC emulation environment - ${{ if eq(parameters.archType, 'wasm') }}: - - ${{ if eq(parameters.platform, 'browser_multithread_wasm_win') }}: + - ${{ if and(eq(parameters.platform, 'browser_wasm_win'), eq(parameters.nameSuffix, 'Multithreaded')) }}: - script: | $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} $(crossArg) $(_officialBuildParameter) ci browser tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} /p:WasmEnableThreads=true displayName: Build WebAssembly browser Mutlithread runtime tests - - ${{ elseif eq(parameters.platform, 'wasi_multithread_wasm_win') }}: + - ${{ elseif and(eq(parameters.platform, 'wasi_wasm_win'), eq(parameters.nameSuffix, 'Multithreaded')) }}: - script: | $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} $(crossArg) $(_officialBuildParameter) ci wasi tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} /p:WasmEnableThreads=true displayName: Build WebAssembly wasi Mutlithread runtime tests @@ -58,7 +58,7 @@ steps: displayName: Run runtime tests # Don't compile/run the libraries tests with emulated ILC to save CI time/resources. - - ${{ if and(and(eq(parameters.archType, 'wasm'), eq(parameters.nameSuffix, '')), not(in(parameters.platform, 'browser_multithread_wasm_win', 'wasi_multithread_wasm_win'))) }}: + - ${{ if and(and(eq(parameters.archType, 'wasm'), eq(parameters.nameSuffix, '')), not(eq(parameters.nameSuffix, 'Multithreaded'))) }}: - script: $(Build.SourcesDirectory)/build$(scriptExt) libs.tests -test -a ${{ parameters.archType }} -os ${{ parameters.osGroup }} -lc ${{ parameters.librariesConfiguration }} -rc $(buildConfigUpper) /p:TestNativeAot=true /p:RunSmokeTestsOnly=true displayName: Build and run WebAssembly libraries tests From 7fc1d344478aa93fdb08761c8d7e1c217036913e Mon Sep 17 00:00:00 2001 From: yowl Date: Mon, 7 Jul 2025 20:38:50 -0500 Subject: [PATCH 03/17] Dont emulate for Multithreaded --- eng/pipelines/runtimelab/runtimelab-post-build-steps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml index 163009b209e6..863e44c9c1a4 100644 --- a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -26,7 +26,7 @@ steps: # Build coreclr native test output outside of official build - ${{ if ne(parameters.isOfficialBuild, true) }}: - - ${{ if and(eq(parameters.archType, 'wasm'), ne(parameters.nameSuffix, '')) }}: + - ${{ if and(eq(parameters.archType, 'wasm'), and(ne(parameters.nameSuffix, '')), ne(parameters.nameSuffix, 'Multithreaded'))) }}: - script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/set-ilc-emulation-environment.ps1 -Arch $(hostedTargetArch) displayName: Set up ILC emulation environment From e8e2de44be95d73697f5ff1cfffd4c63eb6cbea8 Mon Sep 17 00:00:00 2001 From: yowl Date: Mon, 7 Jul 2025 20:44:38 -0500 Subject: [PATCH 04/17] balance brackets --- eng/pipelines/runtimelab/runtimelab-post-build-steps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml index 863e44c9c1a4..95a2edcd3181 100644 --- a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -26,7 +26,7 @@ steps: # Build coreclr native test output outside of official build - ${{ if ne(parameters.isOfficialBuild, true) }}: - - ${{ if and(eq(parameters.archType, 'wasm'), and(ne(parameters.nameSuffix, '')), ne(parameters.nameSuffix, 'Multithreaded'))) }}: + - ${{ if and(eq(parameters.archType, 'wasm'), and(ne(parameters.nameSuffix, ''), ne(parameters.nameSuffix, 'Multithreaded'))) }}: - script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/set-ilc-emulation-environment.ps1 -Arch $(hostedTargetArch) displayName: Set up ILC emulation environment From 301c77544b24bbb7e6f48b5495f1977c736cc64e Mon Sep 17 00:00:00 2001 From: yowl Date: Wed, 9 Jul 2025 16:35:46 -0500 Subject: [PATCH 05/17] pass WasmEnableThreads to build the packages to get the right name --- eng/pipelines/runtimelab/runtimelab-post-build-steps.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml index 95a2edcd3181..60e7b3e0acaa 100644 --- a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -17,8 +17,12 @@ steps: displayName: Build the ILC and RyuJit cross-compilers # Build target packages (note: target libs already built). - - script: $(Build.SourcesDirectory)/build$(scriptExt) nativeaot.packages -os ${{ parameters.osGroup }} -a wasm -c $(buildConfigUpper) $(_officialBuildParameter) -ci - displayName: Build target packages + - ${{ if ne(parameters.nameSuffix, 'Multithreaded') }}: + - script: $(Build.SourcesDirectory)/build$(scriptExt) nativeaot.packages -os ${{ parameters.osGroup }} -a wasm -c $(buildConfigUpper) $(_officialBuildParameter) -ci + displayName: Build target packages + - ${{ else }}: + - script: $(Build.SourcesDirectory)/build$(scriptExt) nativeaot.packages -os ${{ parameters.osGroup }} -a wasm -c $(buildConfigUpper) $(_officialBuildParameter) -ci /p:WasmEnableThreads=true + displayName: Build target multithread packages # Build host packages. - script: $(Build.SourcesDirectory)/build$(scriptExt) libs+nativeaot.packages -a $(hostedTargetArch) -c $(buildConfigUpper) -cross $(_officialBuildParameter) -ci From 456f60087e285912dde282d2f8ff826605194627 Mon Sep 17 00:00:00 2001 From: yowl Date: Wed, 9 Jul 2025 17:52:32 -0500 Subject: [PATCH 06/17] set DCLR_CMAKE_TARGET_OS_SUBGROUP in runtime.proj --- docs/workflow/building/coreclr/nativeaot.md | 4 ++-- src/coreclr/runtime.proj | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/workflow/building/coreclr/nativeaot.md b/docs/workflow/building/coreclr/nativeaot.md index caed73753f5f..25a963346143 100644 --- a/docs/workflow/building/coreclr/nativeaot.md +++ b/docs/workflow/building/coreclr/nativeaot.md @@ -80,11 +80,11 @@ Once you build the repo, you can use the produced binaries in one of four ways s This is a work in progress and far from functional. Currentlty there exists just enough infrastucture to build packages for mutlithreaded runtime and libs, but they are not functional in the sense that they support multithreaded programs yet. To build the WASI packages: ``` -build clr.aot+libs+nativeaot.packages -c Debug -a wasm -os wasi -cmakeargs -DCLR_CMAKE_TARGET_OS_SUBGROUP=multithread '/p:WasmEnableThreads=true' +build clr.aot+libs+nativeaot.packages -c Debug -a wasm -os wasi -cmakeargs '/p:WasmEnableThreads=true' ``` To build the browser multithreaded packages: ``` -build clr.aot+libs+nativeaot.packages -c Debug -a wasm -os browser -cmakeargs -DCLR_CMAKE_TARGET_OS_SUBGROUP=multithread '/p:WasmEnableThreads=true' +build clr.aot+libs+nativeaot.packages -c Debug -a wasm -os browser -cmakeargs '/p:WasmEnableThreads=true' ``` To build the runtime tests for WASI ``` diff --git a/src/coreclr/runtime.proj b/src/coreclr/runtime.proj index 0e0bff962b16..332787073e58 100644 --- a/src/coreclr/runtime.proj +++ b/src/coreclr/runtime.proj @@ -94,6 +94,10 @@ <_CoreClrBuildArg Include="-cmakeargs "-DCLR_CMAKE_ESRP_CLIENT=$(DotNetEsrpToolPath)"" /> + + <_CoreClrBuildArg Include="-cmakeargs "-DCLR_CMAKE_TARGET_OS_SUBGROUP=multithread"" /> + + <_CoreClrBuildScript Condition="$([MSBuild]::IsOsPlatform(Windows))">build-runtime.cmd <_CoreClrBuildScript Condition="!$([MSBuild]::IsOsPlatform(Windows))">build-runtime.sh From 4099b10aca3cd57ea548d0016407d86c8e5932b4 Mon Sep 17 00:00:00 2001 From: yowl Date: Wed, 9 Jul 2025 19:01:28 -0500 Subject: [PATCH 07/17] Remove CLR_CMAKE_TARGET_OS_SUBGROUP from yml --- eng/pipelines/runtimelab.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/runtimelab.yml b/eng/pipelines/runtimelab.yml index 864f62ea8139..fa7a3ef8051f 100644 --- a/eng/pipelines/runtimelab.yml +++ b/eng/pipelines/runtimelab.yml @@ -85,7 +85,7 @@ extends: - wasi_wasm_win jobParameters: timeoutInMinutes: 300 - buildArgs: -s clr.aot+libs -c debug -rc $(_BuildConfig) -cmakeargs -DCLR_CMAKE_TARGET_OS_SUBGROUP=multithread '/p:WasmEnableThreads=true' + buildArgs: -s clr.aot+libs -c debug -rc $(_BuildConfig) -cmakeargs '/p:WasmEnableThreads=true' nameSuffix: Multithreaded postBuildSteps: - template: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml From c3ed4431fc2f60dcfe7ff9c173f3dcb9ebf67cfb Mon Sep 17 00:00:00 2001 From: yowl Date: Fri, 11 Jul 2025 16:42:14 -0500 Subject: [PATCH 08/17] disable PackagingTests for multithread --- src/tests/Common/dirs.proj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/Common/dirs.proj b/src/tests/Common/dirs.proj index c16515c74594..c9c2c68cc33c 100644 --- a/src/tests/Common/dirs.proj +++ b/src/tests/Common/dirs.proj @@ -37,6 +37,8 @@ + + From 326146617fa1c48196162bcc275fbbaa327b470a Mon Sep 17 00:00:00 2001 From: yowl Date: Sun, 13 Jul 2025 08:41:19 -0500 Subject: [PATCH 09/17] remove cmakeargs arg from yml and docs. --- docs/workflow/building/coreclr/nativeaot.md | 4 ++-- eng/pipelines/runtimelab.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/workflow/building/coreclr/nativeaot.md b/docs/workflow/building/coreclr/nativeaot.md index 25a963346143..8642acef81a4 100644 --- a/docs/workflow/building/coreclr/nativeaot.md +++ b/docs/workflow/building/coreclr/nativeaot.md @@ -80,11 +80,11 @@ Once you build the repo, you can use the produced binaries in one of four ways s This is a work in progress and far from functional. Currentlty there exists just enough infrastucture to build packages for mutlithreaded runtime and libs, but they are not functional in the sense that they support multithreaded programs yet. To build the WASI packages: ``` -build clr.aot+libs+nativeaot.packages -c Debug -a wasm -os wasi -cmakeargs '/p:WasmEnableThreads=true' +build clr.aot+libs+nativeaot.packages -c Debug -a wasm -os wasi '/p:WasmEnableThreads=true' ``` To build the browser multithreaded packages: ``` -build clr.aot+libs+nativeaot.packages -c Debug -a wasm -os browser -cmakeargs '/p:WasmEnableThreads=true' +build clr.aot+libs+nativeaot.packages -c Debug -a wasm -os browser '/p:WasmEnableThreads=true' ``` To build the runtime tests for WASI ``` diff --git a/eng/pipelines/runtimelab.yml b/eng/pipelines/runtimelab.yml index fa7a3ef8051f..5feeba231692 100644 --- a/eng/pipelines/runtimelab.yml +++ b/eng/pipelines/runtimelab.yml @@ -85,7 +85,7 @@ extends: - wasi_wasm_win jobParameters: timeoutInMinutes: 300 - buildArgs: -s clr.aot+libs -c debug -rc $(_BuildConfig) -cmakeargs '/p:WasmEnableThreads=true' + buildArgs: -s clr.aot+libs -c debug -rc $(_BuildConfig) '/p:WasmEnableThreads=true' nameSuffix: Multithreaded postBuildSteps: - template: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml From 900df40a0821d2037b2848974efbfa8ba3e262ea Mon Sep 17 00:00:00 2001 From: yowl Date: Sun, 13 Jul 2025 14:25:26 -0500 Subject: [PATCH 10/17] add wasmEnableThreadsArg --- eng/pipelines/runtimelab.yml | 1 + .../runtimelab/runtimelab-post-build-steps.yml | 14 +++----------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/eng/pipelines/runtimelab.yml b/eng/pipelines/runtimelab.yml index 5feeba231692..e74e189e3deb 100644 --- a/eng/pipelines/runtimelab.yml +++ b/eng/pipelines/runtimelab.yml @@ -91,6 +91,7 @@ extends: - template: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml parameters: librariesConfiguration: Debug + wasmEnableThreadsArg: /p:WasmEnableThreads=true # # Build and test with Debug libraries and Checked runtime diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml index 60e7b3e0acaa..e22889bd1a36 100644 --- a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -8,6 +8,7 @@ parameters: runtimeVariant: '' isOfficialBuild: false librariesConfiguration: Debug + wasmEnableThreadsArgg: '' steps: # For NativeAOT-LLVM, we have just built the Wasm-targeting native artifacts (the runtime and libraries). @@ -35,17 +36,8 @@ steps: displayName: Set up ILC emulation environment - ${{ if eq(parameters.archType, 'wasm') }}: - - ${{ if and(eq(parameters.platform, 'browser_wasm_win'), eq(parameters.nameSuffix, 'Multithreaded')) }}: - - script: | - $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} $(crossArg) $(_officialBuildParameter) ci browser tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} /p:WasmEnableThreads=true - displayName: Build WebAssembly browser Mutlithread runtime tests - - ${{ elseif and(eq(parameters.platform, 'wasi_wasm_win'), eq(parameters.nameSuffix, 'Multithreaded')) }}: - - script: | - $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} $(crossArg) $(_officialBuildParameter) ci wasi tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} /p:WasmEnableThreads=true - displayName: Build WebAssembly wasi Mutlithread runtime tests - - ${{ else }}: - - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.osGroup }} $(crossArg) $(_officialBuildParameter) ci tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} - displayName: Build runtime tests + - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.osGroup }} $(crossArg) $(_officialBuildParameter) ci tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} ${{ parameters.wasmEnableThreadsArg }} + displayName: Build runtime tests - ${{ else }}: - ${{ if eq(parameters.osGroup, 'windows') }}: - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} $(crossArg) $(_officialBuildParameter) ci tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} From 8ccf2ecb7f35ae14fce388487bb41bc7d569a0e4 Mon Sep 17 00:00:00 2001 From: yowl Date: Sun, 13 Jul 2025 18:16:46 -0500 Subject: [PATCH 11/17] Remove PalGetMaximumStackBounds_MultiThreadedWasm and add pthread_attr_getstack --- .../nativeaot/Runtime/unix/PalRedhawkUnix.cpp | 4 +- .../nativeaot/Runtime/wasm/PalRedhawkWasm.cpp | 39 +++++++++++-------- .../nativeaot/Runtime/wasm/PalRedhawkWasm.h | 1 - 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp index 3448494fbce8..6a5ec54e7bd6 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp @@ -1151,8 +1151,6 @@ REDHAWK_PALEXPORT bool PalGetMaximumStackBounds(_Out_ void** ppStackLowOut, _Out { #if defined(HOST_WASM) && !defined(FEATURE_WASM_MANAGED_THREADS) PalGetMaximumStackBounds_SingleThreadedWasm(&pStackLowOut, &pStackHighOut); -#elif defined(HOST_WASM) && defined(FEATURE_WASM_MANAGED_THREADS) - PalGetMaximumStackBounds_MultiThreadedWasm(&pStackLowOut, &pStackHighOut); #elif defined(__APPLE__) // This is a Mac specific method pStackHighOut = pthread_get_stackaddr_np(pthread_self()); @@ -1171,6 +1169,8 @@ REDHAWK_PALEXPORT bool PalGetMaximumStackBounds(_Out_ void** ppStackLowOut, _Out status = pthread_attr_get_np(thread, &attr); #elif HAVE_PTHREAD_GETATTR_NP status = pthread_getattr_np(thread, &attr); +#elif defined(HOST_WASM) && defined(FEATURE_WASM_MANAGED_THREADS) + // We dont have a pthread_getattr_np, but so far we don't need it. #else #error Dont know how to get thread attributes on this platform! #endif diff --git a/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.cpp b/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.cpp index 60b2a2b0400d..c13efd9b3e21 100644 --- a/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.cpp +++ b/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.cpp @@ -205,23 +205,6 @@ int __cxa_thread_atexit(void (*func)(), void *obj, void *dso_symbol) // extern "C" unsigned char __stack_low; extern "C" unsigned char __stack_high; -void PalGetMaximumStackBounds_MultiThreadedWasm(void** ppStackLowOut, void** ppStackHighOut) -{ - // See https://github.com/emscripten-core/emscripten/pull/18057 and https://reviews.llvm.org/D135910. - unsigned char* pStackLow = &__stack_low; - unsigned char* pStackHigh = &__stack_high; - - // Sanity check that we have the expected memory layout. - ASSERT((pStackHigh - pStackLow) >= 64 * 1024); - if (pStackLow >= pStackHigh) - { - PalPrintFatalError("\nFatal error. Unexpected stack layout.\n"); - RhFailFast(); - } - - *ppStackLowOut = pStackLow; - *ppStackHighOut = pStackHigh; -} #ifdef TARGET_WASI // TODO-LLVM: No-op stubs, maybe when threads are implemented in WASI, we wont have to provide all of these. @@ -297,6 +280,28 @@ int pthread_equal(pthread_t, pthread_t) int pthread_attr_init(pthread_attr_t *) { + // See https://github.com/emscripten-core/emscripten/pull/18057 and https://reviews.llvm.org/D135910. + unsigned char* pStackLow = &__stack_low; + unsigned char* pStackHigh = &__stack_high; + + // Sanity check that we have the expected memory layout. + ASSERT((pStackHigh - pStackLow) >= 64 * 1024); + if (pStackLow >= pStackHigh) + { + PalPrintFatalError("\nFatal error. Unexpected stack layout.\n"); + RhFailFast(); + } + + return 0; +} + +int pthread_attr_getstack(pthread_attr_t *, void **stackaddr, size_t *stacksize) +{ + unsigned char* pStackLow = &__stack_low; + unsigned char* pStackHigh = &__stack_high; + + *stackaddr = pStackLow; + *stacksize = pStackHigh - pStackLow; return 0; } diff --git a/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.h b/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.h index ff75454e6aba..acbe691e955f 100644 --- a/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.h +++ b/src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.h @@ -3,7 +3,6 @@ #ifdef FEATURE_WASM_MANAGED_THREADS int __cxa_thread_atexit(void (*func)(), void *obj, void *dso_symbol); -void PalGetMaximumStackBounds_MultiThreadedWasm(void** ppStackLowOut, void** ppStackHighOut); #else void PalGetMaximumStackBounds_SingleThreadedWasm(void** ppStackLowOut, void** ppStackHighOut); #endif // !FEATURE_WASM_MANAGED_THREADS From d494b8e74ad922a8ec378e93c264589d7ad551f5 Mon Sep 17 00:00:00 2001 From: yowl Date: Mon, 14 Jul 2025 18:41:51 -0500 Subject: [PATCH 12/17] revert --- src/native/external/zlib-ng.cmake | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/native/external/zlib-ng.cmake b/src/native/external/zlib-ng.cmake index 48110e65daf6..8e16a15f7a05 100644 --- a/src/native/external/zlib-ng.cmake +++ b/src/native/external/zlib-ng.cmake @@ -29,9 +29,6 @@ if (CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) if (CLR_CMAKE_TARGET_BROWSER) add_compile_options(-pthread) add_linker_flag(-pthread) - else() - add_compile_options(-D_WASI_EMULATED_PTHREAD) - add_linker_flag(-Wl,-lwasi-emulated-pthread) endif() endif() endif() From 06f4e2d454f41504ef96b28618dfaf02ae8f4b59 Mon Sep 17 00:00:00 2001 From: yowl Date: Tue, 15 Jul 2025 18:12:22 -0500 Subject: [PATCH 13/17] Update eng/pipelines/runtimelab/runtimelab-post-build-steps.yml Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> --- eng/pipelines/runtimelab/runtimelab-post-build-steps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml index e22889bd1a36..0c03faed24f1 100644 --- a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -8,7 +8,7 @@ parameters: runtimeVariant: '' isOfficialBuild: false librariesConfiguration: Debug - wasmEnableThreadsArgg: '' + wasmEnableThreadsArg: '' steps: # For NativeAOT-LLVM, we have just built the Wasm-targeting native artifacts (the runtime and libraries). From 2672e7542285f4eb78af11ffd0480f9d06c00383 Mon Sep 17 00:00:00 2001 From: yowl Date: Tue, 15 Jul 2025 19:09:56 -0500 Subject: [PATCH 14/17] address feedback for running tests. --- .../runtimelab-post-build-steps.yml | 24 +++++++++---------- src/tests/Common/dirs.proj | 15 +++++------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml index e22889bd1a36..593ba46c7d9d 100644 --- a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -8,7 +8,7 @@ parameters: runtimeVariant: '' isOfficialBuild: false librariesConfiguration: Debug - wasmEnableThreadsArgg: '' + wasmEnableThreadsArg: '' steps: # For NativeAOT-LLVM, we have just built the Wasm-targeting native artifacts (the runtime and libraries). @@ -18,12 +18,8 @@ steps: displayName: Build the ILC and RyuJit cross-compilers # Build target packages (note: target libs already built). - - ${{ if ne(parameters.nameSuffix, 'Multithreaded') }}: - - script: $(Build.SourcesDirectory)/build$(scriptExt) nativeaot.packages -os ${{ parameters.osGroup }} -a wasm -c $(buildConfigUpper) $(_officialBuildParameter) -ci - displayName: Build target packages - - ${{ else }}: - - script: $(Build.SourcesDirectory)/build$(scriptExt) nativeaot.packages -os ${{ parameters.osGroup }} -a wasm -c $(buildConfigUpper) $(_officialBuildParameter) -ci /p:WasmEnableThreads=true - displayName: Build target multithread packages + - script: $(Build.SourcesDirectory)/build$(scriptExt) nativeaot.packages -os ${{ parameters.osGroup }} -a wasm -c $(buildConfigUpper) $(_officialBuildParameter) -ci $(wasmEnableThreadsArg) + displayName: Build target packages # Build host packages. - script: $(Build.SourcesDirectory)/build$(scriptExt) libs+nativeaot.packages -a $(hostedTargetArch) -c $(buildConfigUpper) -cross $(_officialBuildParameter) -ci @@ -31,13 +27,14 @@ steps: # Build coreclr native test output outside of official build - ${{ if ne(parameters.isOfficialBuild, true) }}: - - ${{ if and(eq(parameters.archType, 'wasm'), and(ne(parameters.nameSuffix, ''), ne(parameters.nameSuffix, 'Multithreaded'))) }}: + - ${{ if and(eq(parameters.archType, 'wasm'), and(eq(parameters.wasmEnableThreadsArg, ''))) }}: - script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/set-ilc-emulation-environment.ps1 -Arch $(hostedTargetArch) displayName: Set up ILC emulation environment - ${{ if eq(parameters.archType, 'wasm') }}: - - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.osGroup }} $(crossArg) $(_officialBuildParameter) ci tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} ${{ parameters.wasmEnableThreadsArg }} - displayName: Build runtime tests + - ${{ if not(and(eq(parameters.osGroup, 'browser'), ne(parameters.wasmEnableThreadsArg, ''))) }}: + - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.osGroup }} $(crossArg) $(_officialBuildParameter) ci tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} ${{ parameters.wasmEnableThreadsArg }} + displayName: Build runtime tests - ${{ else }}: - ${{ if eq(parameters.osGroup, 'windows') }}: - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} $(crossArg) $(_officialBuildParameter) ci tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }} @@ -50,11 +47,12 @@ steps: - script: $(Build.SourcesDirectory)/src/tests/run$(scriptExt) runnativeaottests $(buildConfigUpper) ${{ parameters.archType }} ${{ parameters.osGroup }} displayName: Run runtime tests - ${{ else }}: - - script: $(Build.SourcesDirectory)/src/tests/run$(scriptExt) --runnativeaottests $(buildConfigUpper) ${{ parameters.archType }} ${{ parameters.osGroup }} - displayName: Run runtime tests + - ${{ if not(and(eq(parameters.osGroup, 'browser'), ne(parameters.wasmEnableThreadsArg, ''))) }}: + - script: $(Build.SourcesDirectory)/src/tests/run$(scriptExt) --runnativeaottests $(buildConfigUpper) ${{ parameters.archType }} ${{ parameters.osGroup }} + displayName: Run runtime tests # Don't compile/run the libraries tests with emulated ILC to save CI time/resources. - - ${{ if and(and(eq(parameters.archType, 'wasm'), eq(parameters.nameSuffix, '')), not(eq(parameters.nameSuffix, 'Multithreaded'))) }}: + - ${{ if and(eq(parameters.archType, 'wasm'), eq(parameters.wasmEnableThreadsArg, '')) }}: - script: $(Build.SourcesDirectory)/build$(scriptExt) libs.tests -test -a ${{ parameters.archType }} -os ${{ parameters.osGroup }} -lc ${{ parameters.librariesConfiguration }} -rc $(buildConfigUpper) /p:TestNativeAot=true /p:RunSmokeTestsOnly=true displayName: Build and run WebAssembly libraries tests diff --git a/src/tests/Common/dirs.proj b/src/tests/Common/dirs.proj index c9c2c68cc33c..ab9ede0674d6 100644 --- a/src/tests/Common/dirs.proj +++ b/src/tests/Common/dirs.proj @@ -29,16 +29,13 @@ - + + - - - - - - - - + + + + From ddf7606572cf79a10b00d4abe3b4fe50bb25e680 Mon Sep 17 00:00:00 2001 From: yowl Date: Tue, 15 Jul 2025 20:28:30 -0500 Subject: [PATCH 15/17] remove D_WASI_EMULATED_PTHREAD --- eng/native/gen-buildsys.cmd | 5 ----- 1 file changed, 5 deletions(-) diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd index b52efd372156..b78a073c8c11 100644 --- a/eng/native/gen-buildsys.cmd +++ b/eng/native/gen-buildsys.cmd @@ -65,11 +65,6 @@ if /i "%__Arch%" == "wasm" ( set "WASI_SDK_PATH=!WASI_SDK_PATH:\=/!" if not "!WASI_SDK_PATH:~-1!" == "/" set "WASI_SDK_PATH=!WASI_SDK_PATH!/" set __CmakeGenerator=Ninja - if defined __CMakeArgs ( - if not "!__CMakeArgs:multithread=!" == "!__CMakeArgs!" ( - set __ExtraCmakeParams=%__ExtraCmakeParams% -D_WASI_EMULATED_PTHREAD - ) - ) set __ExtraCmakeParams=%__ExtraCmakeParams% -DCLR_CMAKE_TARGET_OS=wasi -DCLR_CMAKE_TARGET_ARCH=wasm "-DWASI_SDK_PREFIX=!WASI_SDK_PATH!" "-DCMAKE_TOOLCHAIN_FILE=!WASI_SDK_PATH!/share/cmake/wasi-sdk-p2.cmake" "-DCMAKE_SYSROOT=!WASI_SDK_PATH!share/wasi-sysroot" "-DCMAKE_CROSSCOMPILING_EMULATOR=node --experimental-wasm-bigint --experimental-wasi-unstable-preview1" ) ) else ( From 9f681c661bf8e8731bbb2ae43308711c0dfeed49 Mon Sep 17 00:00:00 2001 From: yowl Date: Wed, 16 Jul 2025 18:32:32 -0500 Subject: [PATCH 16/17] Add todo for zlib-ng --- src/native/external/zlib-ng.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/src/native/external/zlib-ng.cmake b/src/native/external/zlib-ng.cmake index 8e16a15f7a05..1da5b149685d 100644 --- a/src/native/external/zlib-ng.cmake +++ b/src/native/external/zlib-ng.cmake @@ -26,6 +26,7 @@ if (CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) # zlib-ng uses atomics, so we need to enable threads when requested for browser/wasi, otherwise the wasm target won't have thread support. if (CMAKE_USE_PTHREADS) + # TODO-LLVM: We can't build zlib-ng with threads enabled for browser/wasi yet, because it requires a libc with pthreads, which we don't have as we use the wasip2 libc. if (CLR_CMAKE_TARGET_BROWSER) add_compile_options(-pthread) add_linker_flag(-pthread) From 384c77e0069689f813567064999da8a57ccf0162 Mon Sep 17 00:00:00 2001 From: yowl Date: Wed, 16 Jul 2025 20:13:24 -0500 Subject: [PATCH 17/17] put back the nameSuffix check for wasm on linux arm --- eng/pipelines/runtimelab/runtimelab-post-build-steps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml index 593ba46c7d9d..7c4e635585b8 100644 --- a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -27,7 +27,7 @@ steps: # Build coreclr native test output outside of official build - ${{ if ne(parameters.isOfficialBuild, true) }}: - - ${{ if and(eq(parameters.archType, 'wasm'), and(eq(parameters.wasmEnableThreadsArg, ''))) }}: + - ${{ if and(eq(parameters.archType, 'wasm'), and(ne(parameters.nameSuffix, ''), eq(parameters.wasmEnableThreadsArg, ''))) }}: - script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/set-ilc-emulation-environment.ps1 -Arch $(hostedTargetArch) displayName: Set up ILC emulation environment