-
Notifications
You must be signed in to change notification settings - Fork 216
[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
base: feature/NativeAOT-LLVM
Are you sure you want to change the base?
Changes from all commits
494d4c5
46699a7
7fc1d34
e8e2de4
301c775
456f600
4099b10
c3ed443
3261466
900df40
8ccf2ec
d494b8e
06f4e2d
2672e75
3b7cfbc
ddf7606
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,6 +71,28 @@ 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 | ||
osSubgroup: multithread | ||
platforms: | ||
- browser_wasm_win | ||
- wasi_wasm_win | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is this going to work with WASI, considering we don't have a |
||
jobParameters: | ||
timeoutInMinutes: 300 | ||
buildArgs: -s clr.aot+libs -c debug -rc $(_BuildConfig) '/p:WasmEnableThreads=true' | ||
nameSuffix: Multithreaded | ||
postBuildSteps: | ||
- 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 | ||
# | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -438,6 +438,7 @@ The .NET Foundation licenses this file to you under the MIT license. | |
<CompileWasmArgs Condition="'$(NativeDebugSymbols)' == 'true'">$(CompileWasmArgs) -g3</CompileWasmArgs> | ||
<CompileWasmArgs Condition="'$(WasmEnableNonTrappingFloatToIntConversions)' == 'true'">$(CompileWasmArgs) -mnontrapping-fptoint</CompileWasmArgs> | ||
<CompileWasmArgs Condition="'$(IlcLlvmExceptionHandlingModel)' == 'wasm'">$(CompileWasmArgs) -fwasm-exceptions</CompileWasmArgs> | ||
<CompileWasmArgs Condition="'$(WasmEnableThreads)' == 'true'">$(CompileWasmArgs) -pthread -matomics -mbulk-memory</CompileWasmArgs> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You also need to modify the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't think there were any triples for threads, at least not yet. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is |
||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition="'$(_targetOS)' == 'browser'"> | ||
|
@@ -608,6 +609,7 @@ The .NET Foundation licenses this file to you under the MIT license. | |
<CustomLinkerArg Include="-s MAXIMUM_MEMORY=$(EmccMaximumHeapSize)" Condition="'$(EmccMaximumHeapSize)' != ''" /> | ||
<CustomLinkerArg Include="-s INITIAL_MEMORY=$(EmccInitialHeapSize)" Condition="'$(EmccInitialHeapSize)' != ''" /> | ||
<CustomLinkerArg Condition="'$(EmccEnableAssertions)' == 'true'" Include="-s ASSERTIONS=1" /> | ||
<CustomLinkerArg Condition="'$(WasmEnableThreads)' == 'true'" Include="-pthread" /> | ||
</ItemGroup> | ||
|
||
<!-- wasm-ld only supports listing exports on the command line --> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1169,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. | ||
Comment on lines
+1172
to
+1173
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we not? Could you test whether our Emscripten version already has a working version of it, it needs |
||
#else | ||
#error Dont know how to get thread attributes on this platform! | ||
#endif | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -191,6 +191,186 @@ 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; | ||
|
||
Comment on lines
+195
to
+208
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a lot of code copied here and it's not clear what part of it is needed and what part is there because WASI doesn't actually |
||
#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 *) | ||
{ | ||
// 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; | ||
} | ||
|
||
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<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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
// 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); | ||
#else | ||
void PalGetMaximumStackBounds_SingleThreadedWasm(void** ppStackLowOut, void** ppStackHighOut); | ||
#endif // !FEATURE_WASM_MANAGED_THREADS |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,11 @@ | |
<PropertyGroup Condition="'$(TargetsSingleThreadedWasm)' != 'true'"> | ||
<FeaturePortableThreadPool>true</FeaturePortableThreadPool> | ||
<FeaturePortableTimer>true</FeaturePortableTimer> | ||
<!-- LLVM-TODO: Remove FeatureWasmManagedThreads in favor of WasmEnableThreads. --> | ||
<FeatureWasmManagedThreads Condition="'$(WasmEnableThreads)' == 'true'">true</FeatureWasmManagedThreads> | ||
<FeatureWasmPerfTracing Condition="('$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true') and ('$(WasmEnableThreads)' == 'true')">true</FeatureWasmPerfTracing> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is |
||
<DefineConstants Condition="'$(WasmEnableThreads)' == 'true'">$(DefineConstants);FEATURE_WASM_MANAGED_THREADS</DefineConstants> | ||
<DefineConstants Condition="'$(FeatureWasmPerfTracing)' == 'true'">$(DefineConstants);FEATURE_WASM_PERFTRACING</DefineConstants> | ||
</PropertyGroup> | ||
<PropertyGroup> | ||
<FeatureHardwareIntrinsics>true</FeatureHardwareIntrinsics> | ||
|
@@ -347,6 +352,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 '$(WasmEnableThreads)' == 'true'" /> | ||
<Compile Include="System\Threading\ThreadPool.NativeAot.Browser.cs" Condition="'$(TargetsBrowser)' == 'true' and '$(WasmEnableThreads)' == 'true'" /> | ||
Comment on lines
+355
to
+356
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are the portable thread pool files insufficient and we need these as well? |
||
</ItemGroup> | ||
|
||
<!-- WASM-specific things. Keep in sync with Mono. --> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed (also below)?