Skip to content

Commit fdaebbf

Browse files
authored
[browser] native - no process, no signals, no threads, no blocking (#123962)
1 parent 47654b0 commit fdaebbf

15 files changed

Lines changed: 158 additions & 37 deletions

File tree

eng/native.wasm.targets

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,22 @@
2828
<ItemGroup Condition="'$(TargetsBrowser)' == 'true' and '$(RuntimeFlavor)' == 'CoreCLR'">
2929
<NativeCMakeArg Include="-cmakeargs &quot;-DBUILD_LIBS_NATIVE_BROWSER=1&quot;" />
3030
<NativeCMakeArg Include="-cmakeargs &quot;-DGEN_PINVOKE=1&quot;" />
31+
<NativeCMakeArg Include="-cmakeargs &quot;-DFEATURE_PERFTRACING_PAL_WS=1&quot;" />
32+
<NativeCMakeArg Include="-cmakeargs &quot;-DFEATURE_PERFTRACING_DISABLE_PERFTRACING_LISTEN_PORTS=1&quot;" />
33+
<NativeCMakeArg Include="-cmakeargs &quot;-DFEATURE_PERFTRACING_DISABLE_DEFAULT_LISTEN_PORT=1&quot;" />
3134
</ItemGroup>
35+
<ItemGroup Condition="'$(TargetsBrowser)' == 'true' and '$(RuntimeFlavor)' == 'CoreCLR' and '$(WasmEnableThreads)' != 'true'">
36+
<NativeCMakeArg Include="-cmakeargs &quot;-DFEATURE_PERFTRACING_DISABLE_THREADS=1&quot;" />
37+
<NativeCMakeArg Include="-cmakeargs &quot;-DFEATURE_SINGLE_THREADED=1&quot;" />
38+
</ItemGroup>
39+
<!-- TODO-WASM - https://github.com/dotnet/runtime/issues/68162
40+
<ItemGroup Condition="'$(WasmEnableThreads)' == 'true'">
41+
-sUSE_PTHREADS=1
42+
-sPTHREAD_POOL_SIZE=0
43+
-sPTHREAD_POOL_SIZE_STRICT=0
44+
-Wno-pthreads-mem-growth
45+
</ItemGroup>
46+
-->
3247

3348
<Target Name="GenerateEmccExports" Condition="'$(TargetsBrowser)' == 'true'">
3449
<ItemGroup>

src/coreclr/pal/src/debug/debug.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -755,13 +755,19 @@ PAL_ProbeMemory(
755755
DWORD cbBuffer,
756756
BOOL fWriteAccess)
757757
{
758-
#if defined(__EMSCRIPTEN__)
758+
#if defined(TARGET_BROWSER)
759759
if ((uintptr_t)((PBYTE)pBuffer + cbBuffer) <= emscripten_get_heap_size())
760760
{
761761
return TRUE;
762762
}
763763
return FALSE;
764-
#else // __EMSCRIPTEN__
764+
#elif defined(TARGET_WASI)
765+
if ((uintptr_t)((PBYTE)pBuffer + cbBuffer) <= (__builtin_wasm_memory_size(0) * 65536))
766+
{
767+
return TRUE;
768+
}
769+
return FALSE;
770+
#else // TARGET_BROWSER || TARGET_WASI
765771
int fds[2];
766772
int flags;
767773

@@ -818,7 +824,7 @@ PAL_ProbeMemory(
818824
close(fds[1]);
819825

820826
return result;
821-
#endif // __EMSCRIPTEN__
827+
#endif // TARGET_BROWSER || TARGET_WASI
822828
}
823829

824830
} // extern "C"

src/coreclr/pal/src/file/file.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,6 +2128,10 @@ CorUnix::InternalCreatePipe(
21282128
DWORD nSize
21292129
)
21302130
{
2131+
#ifdef TARGET_WASM
2132+
// Pipes are not supported on wasm
2133+
return ERROR_NOT_SUPPORTED;
2134+
#else // TARGET_WASM
21312135
PAL_ERROR palError = NO_ERROR;
21322136
IPalObject *pReadFileObject = NULL;
21332137
IPalObject *pReadRegisteredFile = NULL;
@@ -2342,6 +2346,7 @@ CorUnix::InternalCreatePipe(
23422346
}
23432347

23442348
return palError;
2349+
#endif // !TARGET_WASM
23452350
}
23462351

23472352
/*++

src/coreclr/pal/src/synchmgr/synchmanager.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,19 @@ namespace CorUnix
404404
goto TNW_exit;
405405
}
406406

407+
#ifdef FEATURE_SINGLE_THREADED
408+
// In single-threaded WASM, if the object is not already signaled (iPred == FALSE),
409+
// we cannot wait because there is no other thread to signal us - this would deadlock.
410+
// This is a programming error in single-threaded WASM.
411+
_ASSERT_MSG(FALSE != ptnwdNativeWaitData->iPred, "Cannot wait in single-threaded mode\n");
412+
if (FALSE == ptnwdNativeWaitData->iPred)
413+
{
414+
iRet = pthread_mutex_unlock(&ptnwdNativeWaitData->mutex);
415+
palErr = ERROR_NOT_SUPPORTED;
416+
*ptwrWakeupReason = WaitFailed;
417+
}
418+
#else // FEATURE_SINGLE_THREADED
419+
407420
while (FALSE == ptnwdNativeWaitData->iPred)
408421
{
409422
if (INFINITE == dwTimeout)
@@ -475,6 +488,7 @@ namespace CorUnix
475488
*ptwrWakeupReason = WaitTimeout;
476489
}
477490

491+
#endif // FEATURE_SINGLE_THREADED
478492
TNW_exit:
479493
TRACE("ThreadNativeWait: returning %u [WakeupReason=%u]\n", palErr, *ptwrWakeupReason);
480494
return palErr;

src/coreclr/pal/src/synchmgr/wait.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,14 @@ DWORD CorUnix::InternalWaitForMultipleObjectsEx(
418418

419419
if (fNeedToBlock)
420420
{
421+
#ifdef FEATURE_SINGLE_THREADED
422+
// In single-threaded WASM, blocking would deadlock because there is no other
423+
// thread to signal the object. This is a programming error.
424+
_ASSERT_MSG(false, "Cannot block on wait in single-threaded mode\n");
425+
pThread->SetLastError(ERROR_NOT_SUPPORTED);
426+
dwRet = WAIT_FAILED;
427+
goto WFMOExIntCleanup;
428+
#else // FEATURE_SINGLE_THREADED
421429
ThreadWakeupReason twrWakeupReason;
422430

423431
//
@@ -452,6 +460,7 @@ DWORD CorUnix::InternalWaitForMultipleObjectsEx(
452460
dwRet = WAIT_FAILED;
453461
break;
454462
}
463+
#endif // FEATURE_SINGLE_THREADED
455464
}
456465

457466
if (!fWAll && (WAIT_OBJECT_0 == dwRet))
@@ -493,6 +502,13 @@ DWORD CorUnix::InternalSleepEx (
493502
CPalThread * pThread,
494503
DWORD dwMilliseconds)
495504
{
505+
#ifdef FEATURE_SINGLE_THREADED
506+
// In single-threaded WASM, Sleep returns immediately.
507+
// There's no other thread that could make progress while we sleep.
508+
(void)pThread;
509+
(void)dwMilliseconds;
510+
return 0;
511+
#else // FEATURE_SINGLE_THREADED
496512
PAL_ERROR palErr = NO_ERROR;
497513
DWORD dwRet = WAIT_FAILED;
498514
int iSignaledObjIndex;
@@ -535,5 +551,6 @@ DWORD CorUnix::InternalSleepEx (
535551

536552
TRACE("Done sleeping %u ms", dwMilliseconds);
537553
return dwRet;
554+
#endif // FEATURE_SINGLE_THREADED
538555
}
539556

src/coreclr/pal/src/thread/process.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ CorUnix::InternalCreateProcess(
486486
LPPROCESS_INFORMATION lpProcessInformation
487487
)
488488
{
489-
#ifdef TARGET_TVOS
489+
#if defined(TARGET_TVOS) || defined(TARGET_WASM)
490490
return ERROR_NOT_SUPPORTED;
491491
#else
492492
PAL_ERROR palError = NO_ERROR;
@@ -1025,7 +1025,7 @@ CorUnix::InternalCreateProcess(
10251025
}
10261026

10271027
return palError;
1028-
#endif // !TARGET_TVOS
1028+
#endif // !TARGET_TVOS && !TARGET_WASM
10291029
}
10301030

10311031

@@ -2396,7 +2396,7 @@ PROCCreateCrashDump(
23962396
INT cbErrorMessageBuffer,
23972397
bool serialize)
23982398
{
2399-
#if defined(TARGET_IOS) || defined(TARGET_TVOS)
2399+
#if defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_WASM)
24002400
return FALSE;
24012401
#else
24022402
_ASSERTE(argv[0] != nullptr);
@@ -2573,7 +2573,7 @@ PROCCreateCrashDump(
25732573
}
25742574
}
25752575
return true;
2576-
#endif // !TARGET_IOS && !TARGET_TVOS
2576+
#endif // !TARGET_IOS && !TARGET_TVOS && !TARGET_WASM
25772577
}
25782578

25792579
/*++

src/coreclr/pal/src/thread/thread.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,10 @@ CorUnix::InternalCreateThread(
434434
HANDLE *phThread
435435
)
436436
{
437+
#ifdef FEATURE_SINGLE_THREADED
438+
ERROR("Threads are not supported in single-threaded mode.\n");
439+
return ERROR_NOT_SUPPORTED;
440+
#else // FEATURE_SINGLE_THREADED
437441
PAL_ERROR palError;
438442
CPalThread *pNewThread = NULL;
439443
CObjectAttributes oa;
@@ -629,6 +633,7 @@ CorUnix::InternalCreateThread(
629633
}
630634

631635
return palError;
636+
#endif // FEATURE_SINGLE_THREADED
632637
}
633638

634639

@@ -1352,6 +1357,7 @@ SetThreadDescription(
13521357
return HRESULT_FROM_WIN32(palError);
13531358
}
13541359

1360+
#ifndef FEATURE_SINGLE_THREADED
13551361
void *
13561362
CPalThread::ThreadEntry(
13571363
void *pvParam
@@ -1497,6 +1503,7 @@ CPalThread::ThreadEntry(
14971503
above should release all resources */
14981504
return NULL;
14991505
}
1506+
#endif // !FEATURE_SINGLE_THREADED
15001507

15011508
/*++
15021509
Function:

src/coreclr/pal/src/thread/threadsusp.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ SET_DEFAULT_DEBUG_CHANNEL(THREAD);
4444
in suspended state in order to resume it. */
4545
CONST BYTE WAKEUPCODE=0x2A;
4646

47+
#ifndef FEATURE_SINGLE_THREADED
4748
/*++
4849
Function:
4950
InternalSuspendNewThreadFromData
@@ -118,6 +119,7 @@ CThreadSuspensionInfo::InternalSuspendNewThreadFromData(
118119

119120
return palError;
120121
}
122+
#endif // !FEATURE_SINGLE_THREADED
121123

122124
/*++
123125
Function:
@@ -132,6 +134,10 @@ ResumeThread(
132134
IN HANDLE hThread
133135
)
134136
{
137+
#ifdef FEATURE_SINGLE_THREADED
138+
ERROR("Threads are not supported in single-threaded mode.\n");
139+
return ERROR_NOT_SUPPORTED;
140+
#else // FEATURE_SINGLE_THREADED
135141
PAL_ERROR palError;
136142
CPalThread *pthrResumer;
137143
DWORD dwSuspendCount = (DWORD)-1;
@@ -159,6 +165,7 @@ ResumeThread(
159165
LOGEXIT("ResumeThread returns DWORD %u\n", dwSuspendCount);
160166
PERF_EXIT(ResumeThread);
161167
return dwSuspendCount;
168+
#endif // FEATURE_SINGLE_THREADED
162169
}
163170

164171
/*++

src/mono/browser/runtime/dotnet.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,14 @@ interface DotnetHostBuilder {
137137
* Note: after the runtime exits, it would reject all further calls to the API.
138138
* You can use runMain() if you want to keep the runtime alive.
139139
*/
140-
runMainAndExit (): Promise<number>;
140+
runMainAndExit(): Promise<number>;
141141
/**
142142
* Runs the Main() method of the application and keeps the runtime alive.
143143
* You can provide "command line" arguments for the Main() method using
144144
* - dotnet.withApplicationArguments("A", "B", "C")
145145
* - dotnet.withApplicationArgumentsFromQuery()
146146
*/
147-
runMain (): Promise<number>;
147+
runMain(): Promise<number>;
148148
}
149149
type MonoConfig = {
150150
/**

src/native/eventpipe/ds-ipc-pal-websocket.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,30 @@ ep_rt_object_array_free (void *ptr)
7373
if (ptr)
7474
free (ptr);
7575
}
76+
77+
static
78+
inline
79+
ep_char8_t *
80+
ep_rt_utf8_string_dup (const ep_char8_t *str)
81+
{
82+
if (!str)
83+
return NULL;
84+
85+
return strdup (str);
86+
}
87+
88+
static
89+
inline
90+
void
91+
ep_rt_utf8_string_free (ep_char8_t *str)
92+
{
93+
if (str)
94+
free (str);
95+
}
96+
97+
#undef EP_UNREACHABLE
98+
#define EP_UNREACHABLE(msg) do { EP_ASSERT (!(msg)); abort (); } while (0)
99+
76100
#endif
77101

78102
static bool _ipc_pal_socket_init = false;

0 commit comments

Comments
 (0)