Skip to content

[browser][MT] deputy testing (16) #94525

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

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:
alwaysRun: ${{ parameters.isWasmOnlyBuild }}

# NOTE - Since threading is experimental, we don't want to block mainline work
shouldContinueOnError: true
# TODO put back shouldContinueOnError: true
scenarios:
- WasmTestOnBrowser
#- WasmTestOnNodeJS - this is not supported yet, https://github.com/dotnet/runtime/issues/85592
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ internal static (ConsoleLogger Logger, ConsoleSink Sink, ConsoleSink ErrorSink,
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/91538", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))]
public void ConsoleLoggerOptions_TimeStampFormat_IsReloaded()
{
// Arrange
Expand All @@ -88,7 +87,6 @@ public void ConsoleLoggerOptions_TimeStampFormat_IsReloaded()
}

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/91538", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))]
[MemberData(nameof(FormatterNames))]
public void InvalidLogLevel_Throws(string formatterName)
{
Expand All @@ -103,7 +101,6 @@ public void InvalidLogLevel_Throws(string formatterName)
}

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/91538", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))]
[MemberData(nameof(FormatterNamesAndLevels))]
public void NoMessageOrException_Noop(string formatterName, LogLevel level)
{
Expand All @@ -123,7 +120,6 @@ public void NoMessageOrException_Noop(string formatterName, LogLevel level)
}

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/91538", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))]
[MemberData(nameof(FormatterNamesAndLevels))]
public void Log_LogsCorrectTimestamp(string formatterName, LogLevel level)
{
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<EnableDefaultItems>true</EnableDefaultItems>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetOS)' == 'browser'">
<WasmXHarnessMonoArgs>--setenv=XHARNESS_LOG_TEST_START=true --no-memory-snapshot</WasmXHarnessMonoArgs>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\src\LogLevelAttribute.cs"
Link="tests\DI.Common\Common\src\LogLevelAttribute.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetOS)' == 'browser'">
<WasmXHarnessMonoArgs>--setenv=XHARNESS_LOG_TEST_START=true --no-memory-snapshot</WasmXHarnessMonoArgs>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(CommonTestPath)TestUtilities\System\DisableParallelization.cs" Link="Common\TestUtilities\System\DisableParallelization.cs" />
</ItemGroup>
Expand Down
1 change: 0 additions & 1 deletion src/libraries/System.IO.Pipelines/tests/PipeWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,6 @@ public async Task WritesUsingGetMemoryWorks()
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/91547", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))]
public async Task CompleteWithLargeWriteThrows()
{
var completeDelay = TimeSpan.FromMilliseconds(10);
Expand Down
1 change: 1 addition & 0 deletions src/libraries/System.Linq.Parallel/tests/ExchangeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ public static void Partitioning_Default_Longrunning(Labeled<ParallelQuery<int>>

[ConditionalTheory]
[MemberData(nameof(PartitioningData), new[] { 0, 1, 2, 16, 1024 })]
[ActiveIssue("https://github.com/dotnet/runtime/issues/91541", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))]
public static void Partitioning_Striped(Labeled<ParallelQuery<int>> labeled, int count, int partitions)
{
if (partitions > 1 && !PlatformDetection.IsThreadingSupported)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition="'$(TargetOS)' == 'browser'">
<WasmXHarnessMonoArgs>--setenv=XHARNESS_LOG_TEST_START=true --no-memory-snapshot</WasmXHarnessMonoArgs>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(CommonTestPath)System\Diagnostics\Tracing\TestEventListener.cs" Link="Common\System\Diagnostics\Tracing\TestEventListener.cs" />
<Compile Include="BreakTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<_WasmPThreadPoolSize Condition="'$(MonoWasmBuildVariant)' == 'multithread'">64</_WasmPThreadPoolSize>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetOS)' == 'browser'">
<WasmXHarnessMonoArgs>--setenv=XHARNESS_LOG_TEST_START=true --no-memory-snapshot</WasmXHarnessMonoArgs>
</PropertyGroup>
<ItemGroup>
<Compile Include="Helpers.cs" />
<Compile Include="Task\TaskArgumentValidationTests.cs" />
Expand Down
3 changes: 0 additions & 3 deletions src/libraries/System.Threading/tests/SemaphoreSlimTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ public static void RunSemaphoreSlimTest1_Wait_NegativeCases()
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/91541", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))]
public static void RunSemaphoreSlimTest1_WaitAsync()
{
// Infinite timeout
Expand Down Expand Up @@ -464,7 +463,6 @@ private static void RunSemaphoreSlimTest7_AvailableWaitHandle_Helper(int initial
/// <param name="finalCount">The final semaphore count</param>
/// <returns>True if the test succeeded, false otherwise</returns>
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/91538", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))]
[InlineData(5, 1000, 50, 50, 50, 0, 5, 1000)]
[InlineData(0, 1000, 50, 25, 25, 25, 0, 500)]
[InlineData(0, 1000, 50, 0, 0, 50, 0, 100)]
Expand Down Expand Up @@ -531,7 +529,6 @@ public static void RunSemaphoreSlimTest8_ConcWaitAndRelease(int initial, int max
/// <param name="finalCount">The final semaphore count</param>
/// <returns>True if the test succeeded, false otherwise</returns>
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/91541", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))]
[InlineData(5, 1000, 50, 50, 50, 0, 5, 500)]
[InlineData(0, 1000, 50, 25, 25, 25, 0, 500)]
[InlineData(0, 1000, 50, 0, 0, 50, 0, 100)]
Expand Down
10 changes: 10 additions & 0 deletions src/libraries/tests.proj
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@
<ProjectExclusions Include="$(MonoProjectRoot)sample\wasm\browser-minimal-config\Wasm.Browser.Config.Sample.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetOS)' == 'browser' and '$(MonoWasmBuildVariant)' == 'multithread'" >
<!-- until we fix JS interop with deputy -->
<ProjectExclusions Include="$(MonoProjectRoot)sample\wasm\browser-threads\Wasm.Browser.Threads.Sample.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices.JavaScript\tests\System.Runtime.InteropServices.JavaScript.Legacy.UnitTests\System.Runtime.InteropServices.JavaScript.Legacy.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices.JavaScript\tests\System.Runtime.InteropServices.JavaScript.UnitTests\System.Runtime.InteropServices.JavaScript.Tests.csproj" />
</ItemGroup>


<!-- wasm EAT/AOT -->
<ItemGroup Condition="'$(TargetOS)' == 'browser' and '$(RunDisabledWasmTests)' != 'true' and '$(EnableAggressiveTrimming)' == 'true'">
</ItemGroup>
Expand Down Expand Up @@ -568,7 +576,9 @@
<ItemGroup Condition="'$(TargetOS)' == 'browser' and '$(MonoWasmBuildVariant)' == 'multithread'">
<!-- Don't want the default smoke tests - just verify that threading works -->
<SmokeTestProject Remove="@(SmokeTestProject)" />
<!-- TODO deputy JS interop
<SmokeTestProject Include="$(MonoProjectRoot)sample\wasm\browser-threads\Wasm.Browser.Threads.Sample.csproj" />
-->
<!-- this sample is messy sandbox right now
<SmokeTestProject Include="$(MonoProjectRoot)sample\wasm\browser-threads-minimal\Wasm.Browser.Threads.Minimal.Sample.csproj" />
-->
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/component/diagnostics_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ queue_push_sync (WasmIpcStreamQueue *q, const uint8_t *buf, uint32_t buf_size, u
gboolean is_browser_thread = FALSE;
while (mono_atomic_load_i32 (&q->buf_full) != 0) {
if (G_UNLIKELY (!is_browser_thread_inited)) {
is_browser_thread = mono_threads_wasm_is_ui_thread ();
is_browser_thread = mono_threads_wasm_is_deputy_thread ();
is_browser_thread_inited = TRUE;
}
if (G_UNLIKELY (is_browser_thread)) {
Expand Down
3 changes: 2 additions & 1 deletion src/mono/mono/metadata/sgen-stw.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,8 @@ mono_wasm_gc_lock(void)
MONO_ENTER_GC_UNSAFE;
#ifndef DISABLE_THREADS
/* only the browser thread is allowed to take the GC lock */
g_assert (mono_threads_wasm_is_ui_thread ());
// FIXME, to make it work for deputy
g_assert (mono_threads_wasm_is_deputy_thread ());
LOCK_GC;
acquire_gc_locks();
#else
Expand Down
5 changes: 4 additions & 1 deletion src/mono/mono/metadata/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,11 @@ mono_native_thread_join_handle (HANDLE thread_handle, gboolean close_handle);

#include "icall-decl.h"

/*#define THREAD_DEBUG(a) do { a; } while (0)*/
#ifdef DEBUG
#define THREAD_DEBUG(a) do { a; } while (0)
#else
#define THREAD_DEBUG(a)
#endif // DEBUG
/*#define THREAD_WAIT_DEBUG(a) do { a; } while (0)*/
#define THREAD_WAIT_DEBUG(a)
/*#define LIBGC_DEBUG(a) do { a; } while (0)*/
Expand Down
4 changes: 2 additions & 2 deletions src/mono/mono/utils/mono-threads-debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#define MOSTLY_ASYNC_SAFE_PRINTF(...) MOSTLY_ASYNC_SAFE_FPRINTF(1, __VA_ARGS__);

#if 1
#ifndef DEBUG
#define THREADS_DEBUG(...)
#else
#define THREADS_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
Expand All @@ -27,7 +27,7 @@
#define THREADS_STW_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
#endif

#if 1
#ifndef DEBUG
#define THREADS_SUSPEND_DEBUG(...)
#else
#define THREADS_SUSPEND_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
Expand Down
65 changes: 65 additions & 0 deletions src/mono/mono/utils/mono-threads-wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,30 @@ mono_threads_wasm_ui_thread_tid (void)
#endif
}

#ifndef DISABLE_THREADS
static pthread_t deputy_thread_tid;
#endif

gboolean
mono_threads_wasm_is_deputy_thread (void)
{
#ifdef DISABLE_THREADS
return TRUE;
#else
return pthread_self () == deputy_thread_tid;
#endif
}

MonoNativeThreadId
mono_threads_wasm_deputy_thread_tid (void)
{
#ifdef DISABLE_THREADS
return (MonoNativeThreadId)1;
#else
return (MonoNativeThreadId) deputy_thread_tid;
#endif
}

#ifndef DISABLE_THREADS
extern void mono_wasm_pthread_on_pthread_attached (MonoNativeThreadId pthread_id);
extern void mono_wasm_pthread_on_pthread_detached (MonoNativeThreadId pthread_id);
Expand Down Expand Up @@ -549,6 +573,47 @@ mono_threads_wasm_async_run_in_target_thread_vii (pthread_t target_thread, void
emscripten_dispatch_to_thread_async (target_thread, EM_FUNC_SIG_VII, func, NULL, user_data1, user_data2);
}

extern void mono_wasm_setup_deputy_thread (void);

// this is running in deputy thread
static void*
deputy_thread_fn (void* unused_arg G_GNUC_UNUSED)
{
mono_wasm_setup_deputy_thread();

// "exit" from server_thread, but keep the pthread alive and responding to events
emscripten_exit_with_live_runtime ();
}

EMSCRIPTEN_KEEPALIVE gboolean
mono_wasm_create_deputy_thread (pthread_t *out_thread_id)
{
if (!pthread_create (&deputy_thread_tid, NULL, deputy_thread_fn, NULL)) {
*out_thread_id = deputy_thread_tid;
return TRUE;
}
memset(out_thread_id, 0, sizeof(pthread_t));
return FALSE;
}

void
mono_threads_wasm_async_run_in_deputy_thread (void (*func) (void))
{
mono_threads_wasm_async_run_in_target_thread (deputy_thread_tid, func);
}

void
mono_threads_wasm_async_run_in_deputy_thread_vi (void (*func) (gpointer), gpointer user_data)
{
mono_threads_wasm_async_run_in_target_thread_vi (deputy_thread_tid, func, user_data);
}

void
mono_threads_wasm_async_run_in_deputy_thread_vii (void (*func) (gpointer, gpointer), gpointer user_data1, gpointer user_data2)
{
mono_threads_wasm_async_run_in_target_thread_vii (deputy_thread_tid, func, user_data1, user_data2);
}


#endif /* DISABLE_THREADS */

Expand Down
19 changes: 19 additions & 0 deletions src/mono/mono/utils/mono-threads-wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,15 @@
gboolean
mono_threads_wasm_is_ui_thread (void);

gboolean
mono_threads_wasm_is_deputy_thread (void);

MonoNativeThreadId
mono_threads_wasm_ui_thread_tid (void);

MonoNativeThreadId
mono_threads_wasm_deputy_thread_tid (void);

#ifndef DISABLE_THREADS
/**
* Runs the given function asynchronously on the main thread.
Expand All @@ -52,6 +58,19 @@ mono_threads_wasm_async_run_in_target_thread_vi (pthread_t target_thread, void (
void
mono_threads_wasm_async_run_in_target_thread_vii (pthread_t target_thread, void (*func) (gpointer, gpointer), gpointer user_data1, gpointer user_data2);

gboolean
mono_wasm_create_deputy_thread (pthread_t *out_thread_id);

void
mono_threads_wasm_async_run_in_deputy_thread (void (*func) (void));

void
mono_threads_wasm_async_run_in_deputy_thread_vi (void (*func)(gpointer), gpointer user_data);

void
mono_threads_wasm_async_run_in_deputy_thread_vii (void (*func)(gpointer, gpointer), gpointer user_data1, gpointer user_data2);


static inline
int32_t
mono_wasm_atomic_wait_i32 (volatile int32_t *addr, int32_t expected, int32_t timeout_ns)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<WasmEnableThreads>true</WasmEnableThreads>
<MonoWasmBuildVariant>multithread</MonoWasmBuildVariant>
</PropertyGroup>
<Import Project="..\DefaultBrowserSample.targets" />

Expand Down
3 changes: 0 additions & 3 deletions src/mono/sample/wasm/browser-threads-minimal/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ try {
const { getAssemblyExports, runMain } = await dotnet
//.withEnvironmentVariable("MONO_LOG_LEVEL", "debug")
//.withDiagnosticTracing(true)
.withConfig({
pthreadPoolSize: 6,
})
.withElementOnExit()
.withExitCodeLogging()
.create();
Expand Down
45 changes: 40 additions & 5 deletions src/mono/sample/wasm/browser/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,55 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.InteropServices.JavaScript;
using System.Runtime.InteropServices;

namespace Sample
{
public partial class Test
{
public static int Main(string[] args)
public static async Task<int> Main(string[] args)
{
DisplayMeaning(42);
Console.WriteLine($"smoke: TestCanStartThread 0 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
var are = new AutoResetEvent(false);
/*
var t = new Thread(() =>
{
Console.WriteLine($"smoke: TestCanStartThread 2 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
are.Set();
Console.WriteLine($"smoke: TestCanStartThread 3 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
});
*/
/*
var factory = new TaskFactory();
await factory.StartNew(() =>
{
Console.WriteLine($"smoke: TestCanStartThread 2 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
are.Set();
Console.WriteLine($"smoke: TestCanStartThread 3 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
}, TaskCreationOptions.LongRunning);
*/
var p = Task.Run(async ()=>{
Console.WriteLine($"smoke: TestCanStartThread 1 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
await Task.Delay(1000);
Console.WriteLine($"smoke: TestCanStartThread 2 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
are.Set();
Console.WriteLine($"smoke: TestCanStartThread 3 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
});

Console.WriteLine($"smoke: TestCanStartThread 4 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");

are.WaitOne();

Console.WriteLine($"smoke: TestCanStartThread 5 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");

await p;

Console.WriteLine($"smoke: TestCanStartThread 6 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");

return 0;
}

[JSImport("Sample.Test.displayMeaning", "main.js")]
internal static partial void DisplayMeaning(int meaning);
}
}
4 changes: 4 additions & 0 deletions src/mono/sample/wasm/browser/Wasm.Browser.Sample.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<WasmEnableThreads>true</WasmEnableThreads>
<MonoWasmBuildVariant>multithread</MonoWasmBuildVariant>
</PropertyGroup>
<Import Project="..\DefaultBrowserSample.targets" />
<ItemGroup>
<WasmExtraFilesToDeploy Include="main.js" />
Expand Down
Loading