Skip to content
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

[wasm-mt] Use asset loading for dotnet.worker.js; update WasmAppBuilder #73697

Merged
merged 11 commits into from
Aug 14, 2022

Conversation

lambdageek
Copy link
Member

@lambdageek lambdageek commented Aug 10, 2022

Enables using asset loading to get the dotnet.worker.js file that provides the emscripten pthread worker code.
Also allows specifying the number of pre-allocated workers that will be created at startup using MSBuild properties.

Fixes #68509 and fixes #68397 and fixes #72606

  • Override Emscripten PThread.allocateUnusedWorker
    We want to use our own allocateUnusedWorker because we want to load
    dotnet.worker.js using our asset loading machinery.

    Unfortunately, Emscripten first calls allocateUnusedWorker very early (from
    PThread.init) to pre-allocate the pthread worker pool.

    So we set Emscripten's own pthread worker pool to size 0 and make our own. This requires calling loadWasmModuleToWorker during our startup because Emscripten deletes their code that normally does it (in "receiveInstance" in "createWasm" in "emscripten/src/preamble.js") when the pthread pool size is 0.

    Also added a pthreadPoolSize field to MonoConfig to allow specifying the initial pthread pool size in mono-config.json

  • Add IncludeThreadsWorker and PThreadPoolSize props to WasmAppBuilder

    IncludeThreadsWorker adds the "js-module-threads" asset to the mono-config.json

    PThreadPoolSize can be -1 or >=0 to specify the number of workers that will be pre-allocated at startup for the pthread worker pool. -1 means use the default compiled into dotnet.js

  • Reorganize the pthreads TS code by moving Internals (access API that digs through Emscripten's pthreads implementation) to its own module. And add types.

  • Replace emscripten's allocateUnusedWorker function with our own that goes through the asset loading API.

  • Update samples

  • Set up console proxying for the workers.
    This is done by sending a message from the main thread to the pthread workers with the current MonoConfig on our
    dedicated channel. (This means the proxying is setup asynchronously, so if the worker is busy before it receives the message, it may not start redirecting messages right away).

lambdageek and others added 5 commits August 10, 2022 00:23
We want to use our own allocateUnusedWorker because we want to load
`dotnet.worker.js` using our asset loading machinery.

Unfortunately, Emscripten first calls allocateUnusedWorker very early (from
`PThread.init`) to pre-allocate the pthread worker pool.

So we set Emscripten's own pthread worker pool to size 0 and make our
own.  This requires calling `loadWasmModuleToWorker` during our
startup because Emscripten deletes their code that normally does
it (in "receiveInstance" in "createWasm" in
"emscripten/src/preamble.js") when the pthread pool size is 0.

Also added a pthreadPoolSize field to MonoConfig to allow specifying
the initial pthread pool size in mono-config.json
IncludeThreadsWorker adds the js-module-threads asset to the
mono-config

PThreadPoolSize can be -1 or >=0 to specify the number of workers that
will be pre-allocated at startup for the pthread worker pool.  -1
means use the default compiled into dotnet.js
Makes the WasmAppBuilder include the threads worker module
@ghost ghost assigned lambdageek Aug 10, 2022
@lambdageek lambdageek added the arch-wasm WebAssembly architecture label Aug 10, 2022
@ghost
Copy link

ghost commented Aug 10, 2022

Tagging subscribers to 'arch-wasm': @lewing
See info in area-owners.md if you want to be subscribed.

Issue Details

Enables using asset loading to get the dotnet.worker.js file that provides the emscripten pthread worker code.
Also allows specifying the number of pre-allocated workers that will be created at startup using MSBuild properties.

Fixes #68509 and #68397

  • Override Emscripten PThread.allocateUnusedWorker
    We want to use our own allocateUnusedWorker because we want to load
    dotnet.worker.js using our asset loading machinery.

    Unfortunately, Emscripten first calls allocateUnusedWorker very early (from
    PThread.init) to pre-allocate the pthread worker pool.

    So we set Emscripten's own pthread worker pool to size 0 and make our own. This requires calling loadWasmModuleToWorker during our startup because Emscripten deletes their code that normally does it (in "receiveInstance" in "createWasm" in "emscripten/src/preamble.js") when the pthread pool size is 0.

    Also added a pthreadPoolSize field to MonoConfig to allow specifying the initial pthread pool size in mono-config.json

  • Add IncludeThreadsWorker and PThreadPoolSize props to WasmAppBuilder

    IncludeThreadsWorker adds the "js-module-threads" asset to the mono-config.json

    PThreadPoolSize can be -1 or >=0 to specify the number of workers that will be pre-allocated at startup for the pthread worker pool. -1 means use the default compiled into dotnet.js

  • Reorganize the pthreads TS code by moving Internals (access API that digs through Emscripten's pthreads implementation) to its own module. And add types.

  • Replace emscripten's allocateUnusedWorker function with our own that goes through the asset loading API.

  • Update samples

Author: lambdageek
Assignees: lambdageek
Labels:

arch-wasm, area-Build-mono

Milestone: -

@lambdageek
Copy link
Member Author

/azp run runtime-wasm

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@lambdageek
Copy link
Member Author

/azp run runtime-wasm

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@lambdageek
Copy link
Member Author

@pavelsavara @radical any more feedback? Anything for WasmApp.targets or the Task?

lambdageek and others added 2 commits August 12, 2022 13:47
Co-authored-by: Marek Fišera <mara@neptuo.com>
Copy link
Member

@radical radical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very familiar with src/mono/wasm/runtime, so I can't much review those changes. Rest of it looks fine. I would suggest running runtime-wasm though, and if the tests pass then it should be good to merge 👍

@radical
Copy link
Member

radical commented Aug 13, 2022

/azp run runtime-wasm

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

const asset = resolve_asset_path("js-module-threads");
const uri = asset.resolvedUrl;
mono_assert(uri !== undefined, "could not resolve the uri for the js-module-threads asset");
const worker = new Worker(uri);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should subscribe onError here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and maybe proxy the console in the worker, similar way how it was done in crypto worker. See how we passed the json.stringify(runtimeHelpers.config) and then only forward console when enabled.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should subscribe onError here

Emscripten installs an onerror handler of their own that will overwrite ours. we can set one up later (in afterLoadWasmModuleToWorker) but we should probably not use the worker onerror handler for anything that we want to handle - we should catch exceptions around our code and post it using our custom message channel. We have a task to do that in the tracking issue.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and maybe proxy the console in the worker, similar way how it was done in crypto worker. See how we passed the json.stringify(runtimeHelpers.config) and then only forward console when enabled.

ok, i'll see if I can add that over the weekend; if not, there's a task to do it in the tracking issue

@@ -125,7 +125,7 @@
<_EmccCommonFlags Condition="'$(WasmEnableSIMD)' == 'true'" Include="-msimd128" />
<_EmccCommonFlags Condition="'$(MonoWasmThreads)' == 'true'" Include="-s USE_PTHREADS=1" />
<_EmccLinkFlags Condition="'$(MonoWasmThreads)' == 'true'" Include="-Wno-pthreads-mem-growth" />
<_EmccLinkFlags Condition="'$(MonoWasmThreads)' == 'true'" Include="-s PTHREAD_POOL_SIZE=4" />
<_EmccLinkFlags Condition="'$(MonoWasmThreads)' == 'true'" Include="-s PTHREAD_POOL_SIZE=0" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't know if this is the case when the flag would be written into .rsp file in workload and could not be switched back on customer machine. just asking. And maybe it's OK

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea if they use wasm-tools, they will inherit this flag. I'm not sure if it's possible to override it.

Copy link
Member

@pavelsavara pavelsavara left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

lambdageek and others added 2 commits August 13, 2022 14:39
Co-authored-by: Ankit Jain <radical@gmail.com>
use a new MonoThreadMessageApplyMonoConfig message to send
the MonoConfig from the main thread to each worker when the workers
set up the communication channel to the main thread.

then if the diagnosticTracing property is true, redirect the worker
console logging to a websocket.

Fixes dotnet#72606
@lambdageek
Copy link
Member Author

Added console proxying. verified that it gets set up in the browser-threading sample and the worker messages are going through the proxy. Did not try running via xharness, though, but i assume that part works

@lambdageek
Copy link
Member Author

/azp run runtime-wasm

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@lambdageek
Copy link
Member Author

Failures seem to be #73901.

@lambdageek lambdageek merged commit 88ba045 into dotnet:main Aug 14, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Sep 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
arch-wasm WebAssembly architecture area-Build-mono
Projects
None yet
4 participants