Skip to content

[NativeAOT-LLVM] Wasm managed threads - build new nupkg #3060

New issue

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

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

Already on GitHub? Sign in to your account

Draft
wants to merge 59 commits into
base: feature/NativeAOT-LLVM
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
55ce15d
use same upstream macro for wasm threads
yowl Dec 7, 2024
af11ffc
Merge remote-tracking branch 'origin/feature/NativeAOT-LLVM' into FEA…
yowl Mar 23, 2025
6e8d5cf
enable threads nativeoat
yowl Mar 24, 2025
a5744ea
Merge branch 'merge-feb25' into FEATURE_WASM_MANAGED_THREADS
yowl Mar 24, 2025
3461949
packaage name
yowl Mar 30, 2025
556ce1c
revert some tests
yowl Mar 30, 2025
8fd7ae4
Merge remote-tracking branch 'origin/feature/NativeAOT-LLVM' into FEA…
yowl Apr 12, 2025
ec558b6
add multithread step
yowl Apr 12, 2025
c6ccccb
yaml
yowl Apr 12, 2025
3412fc6
yaml
yowl Apr 12, 2025
dedeba8
yaml
yowl Apr 12, 2025
b5e66ee
yaml
yowl Apr 12, 2025
7d40fc3
yaml
yowl Apr 12, 2025
a887995
Merge remote-tracking branch 'origin/feature/NativeAOT-LLVM' into FEA…
yowl May 1, 2025
0847c47
add back condition
yowl May 5, 2025
4111a2c
enable mt yml
yowl May 6, 2025
30fb4a8
yml
yowl May 6, 2025
c936248
yml
yowl May 6, 2025
58e17fc
yml
yowl May 6, 2025
e183e1d
yml
yowl May 6, 2025
b1b305a
yml
yowl May 6, 2025
3f8872c
yml
yowl May 6, 2025
e512b33
yml
yowl May 7, 2025
51fa2d4
yml
yowl May 7, 2025
b71ecfa
yml
yowl May 7, 2025
7594938
yml
yowl May 7, 2025
d6aa762
yml
yowl May 7, 2025
6cbfb26
yml
yowl May 7, 2025
1cb2f85
yml
yowl May 7, 2025
846cd32
yml
yowl May 7, 2025
533409f
yml
yowl May 7, 2025
39539a9
yml
yowl May 7, 2025
f229884
yml
yowl May 10, 2025
dfd09a3
yml
yowl May 10, 2025
ba36825
yml
yowl May 10, 2025
dcd5787
yml
yowl May 10, 2025
8283029
yml
yowl May 10, 2025
40bcb9f
yml
yowl May 10, 2025
3016317
yml
yowl May 10, 2025
cde6d6a
yml
yowl May 10, 2025
e6fa065
yml
yowl May 10, 2025
a584bcb
yml
yowl May 10, 2025
b250b25
yml
yowl May 10, 2025
c18e7d7
yml
yowl May 10, 2025
d2f3841
yml
yowl May 10, 2025
adbb8b7
yml
yowl May 10, 2025
2241d28
yml
yowl May 10, 2025
a806720
yml
yowl May 10, 2025
d9ce1aa
yml
yowl May 10, 2025
2322668
yml
yowl May 11, 2025
94dd7e8
yml
yowl May 11, 2025
fada9d5
disable failing tests
yowl May 20, 2025
1fc774f
disable failing tests
yowl May 20, 2025
df2c5e3
disable failing tests
yowl May 22, 2025
911f2e0
yml
yowl May 23, 2025
bf512aa
remove trace-source
yowl May 24, 2025
d336a2a
add browser package
yowl May 24, 2025
c566eeb
add browser package
yowl May 25, 2025
7685191
add browser package
yowl May 25, 2025
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
2 changes: 1 addition & 1 deletion eng/native/gen-buildsys.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ 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
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"
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 -D_WASI_EMULATED_PTHREAD"
)
) else (
set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCMAKE_SYSTEM_VERSION=10.0"
Expand Down
4 changes: 2 additions & 2 deletions eng/pipelines/common/global-build-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ jobs:
- script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-nodejs.ps1 $(Build.SourcesDirectory)/wasm-tools
displayName: Install NodeJS

- ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), or(eq(parameters.platform, 'wasi_wasm_win'), eq(parameters.platform, 'wasi_wasm_linux_x64_naot_llvm'))) }}:
- ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), in(parameters.platform, 'wasi_wasm_win', 'wasi_wasm_linux_x64_naot_llvm', 'wasi_multithread_wasm_win')) }}:
# Install Wasi Wasm dependencies: wasi-sdk, wasmtime
- script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-wasi-sdk.ps1 -CI -InstallDir $(Build.SourcesDirectory)/wasm-tools
displayName: Install wasi-sdk
Expand All @@ -228,7 +228,7 @@ jobs:
- script: pwsh $(Build.SourcesDirectory)/eng/pipelines/runtimelab/install-jco.ps1 $(Build.SourcesDirectory)
displayName: Install Jco

- ${{ if or(eq(parameters.platform, 'browser_wasm_win'), and(eq(parameters.platform, 'wasi_wasm_win'), not(eq(parameters.runtimeFlavor, 'coreclr')))) }}:
- ${{ if or(eq(parameters.platform, 'browser_wasm_win'), and(in(parameters.platform, 'wasi_wasm_win', 'wasi_multithread_wasm_win'), not(eq(parameters.runtimeFlavor, 'coreclr')))) }}:
# Update machine certs
- task: PowerShell@2
displayName: Update machine certs
Expand Down
38 changes: 38 additions & 0 deletions eng/pipelines/common/platform-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}

# Browser WebAssembly Linux X64 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.

Expand Down
2 changes: 1 addition & 1 deletion eng/pipelines/libraries/helix-queues-setup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ jobs:
- (Ubuntu.2204.Amd64)[email protected]/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)[email protected]/dotnet-buildtools/prereqs:windowsservercore-ltsc2022-helix-webassembly
- (Windows.Server2025.Amd64.Open)[email protected]/dotnet-buildtools/prereqs:windowsservercore-ltsc2025-helix-webassembly-amd64

Expand Down
19 changes: 19 additions & 0 deletions eng/pipelines/runtimelab.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand Down
11 changes: 11 additions & 0 deletions eng/pipelines/runtimelab/runtimelab-post-build-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ steps:
- script: |
$(Build.SourcesDirectory)/src/tests/build$(scriptExt) nativeaot $(buildConfigUpper) ${{ parameters.archType }} $(crossArg) $(_officialBuildParameter) ci wasi tree nativeaot /p:LibrariesConfiguration=${{ parameters.librariesConfiguration }}
displayName: Build WebAssembly tests
- ${{ elseif 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:FeatureWasmManagedThreads=true
displayName: Build WebAssembly browser Mutlithread 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:FeatureWasmManagedThreads=true
displayName: Build WebAssembly wasi Mutlithread tests
- ${{ elseif eq(parameters.platform, 'Browser_wasm_linux_x64_naot_llvm') }}:
- script: |
source $(Build.SourcesDirectory)/wasm-tools/emsdk/emsdk_env.sh
Expand All @@ -59,6 +67,9 @@ steps:
call $(Build.SourcesDirectory)\wasm-tools\emsdk\emsdk_env
$(Build.SourcesDirectory)/src/tests/run$(scriptExt) runnativeaottests $(buildConfigUpper) ${{ parameters.archType }} ${{ parameters.osGroup }}
displayName: Run WebAssembly tests in single file mode
- ${{ elseif in(parameters.platform, 'browser_multithread_wasm_win', 'wasi_multithread_wasm_win') }}:
- script: $(Build.SourcesDirectory)/src/tests/run$(scriptExt) runnativeaottests $(buildConfigUpper) ${{ parameters.archType }} ${{ parameters.osGroup }}
displayName: Run WebAssembly multithread tests in single file mode
- ${{ elseif eq(parameters.osGroup, 'windows') }}:
- script: $(Build.SourcesDirectory)/src/tests/run$(scriptExt) runnativeaottests $(buildConfigUpper) ${{ parameters.archType }} ${{ parameters.osGroup }}
displayName: Run tests in single file mode
Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/nativeaot/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,18 @@ endif (CLR_CMAKE_HOST_UNIX)

if(CLR_CMAKE_TARGET_OS STREQUAL wasi)
add_definitions(-DTARGET_UNIX)

if(CLR_CMAKE_TARGET_OS_SUBGROUP STREQUAL multithread)
add_definitions(-DFEATURE_WASM_MANAGED_THREADS)
endif(CLR_CMAKE_TARGET_OS_SUBGROUP STREQUAL multithread)
endif(CLR_CMAKE_TARGET_OS STREQUAL wasi)

if((CLR_CMAKE_TARGET_OS STREQUAL wasi OR CLR_CMAKE_TARGET_OS STREQUAL browser)
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 browser)
AND CLR_CMAKE_TARGET_OS_SUBGROUP STREQUAL multithread)

if(CLR_CMAKE_TARGET_ANDROID)
add_definitions(-DFEATURE_EMULATED_TLS)
endif()
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
176 changes: 176 additions & 0 deletions src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,182 @@ 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)
{}

//
// 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
// No-op stubs that assume a single-threaded environment.
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; // only one thread
}

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*);

// Due to a bug in the toolchain, we have to provide an implementation of thread-local destruction.
// Since this is the single-threaded case, we simply delegate to the static destruction mechanism.
// Reference: https://github.com/llvm/llvm-project/blob/main/libcxxabi/src/cxa_thread_atexit.cpp.
//
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<DtorList*>(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
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/nativeaot/Runtime/wasm/PalRedhawkWasm.h
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
<PropertyGroup Condition="'$(TargetsSingleThreadedWasm)' != 'true'">
<FeaturePortableThreadPool>true</FeaturePortableThreadPool>
<FeaturePortableTimer>true</FeaturePortableTimer>
<FeatureWasmManagedThreads Condition="'$(WasmEnableThreads)' == 'true'">true</FeatureWasmManagedThreads>
<FeatureWasmPerfTracing Condition="('$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true') and ('$(WasmEnableThreads)' == 'true')">true</FeatureWasmPerfTracing>
<DefineConstants Condition="'$(FeatureWasmManagedThreads)' == 'true'">$(DefineConstants);FEATURE_WASM_MANAGED_THREADS</DefineConstants>
<DefineConstants Condition="'$(FeatureWasmPerfTracing)' == 'true'">$(DefineConstants);FEATURE_WASM_PERFTRACING</DefineConstants>
</PropertyGroup>
<PropertyGroup>
<FeatureHardwareIntrinsics>true</FeatureHardwareIntrinsics>
Expand Down Expand Up @@ -347,6 +351,8 @@
<Compile Include="System\Diagnostics\StackFrame.NativeAot.Wasm.cs" />
<Compile Include="System\Diagnostics\StackFrame.NativeAot.Wasi.cs" Condition="'$(TargetsWasi)' == 'true'" />
<Compile Include="System\Diagnostics\StackFrame.NativeAot.Browser.cs" Condition="'$(TargetsBrowser)' == 'true'" />
<Compile Include="System\Threading\PortableThreadPool.NativeAot.Browser.cs" Condition="'$(TargetsBrowser)' == 'true' and '$(FeatureWasmManagedThreads)' == 'true'" />
<Compile Include="System\Threading\ThreadPool.NativeAot.Browser.cs" Condition="'$(TargetsBrowser)' == 'true' and '$(FeatureWasmManagedThreads)' == 'true'" />
</ItemGroup>

<!-- WASM-specific things. Keep in sync with Mono. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading
Loading