Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
e73537f
[wasm] Enable the tracing component if threading is supported
lambdageek Jun 17, 2022
8c3360a
WIP: add a way to specify EP sessions in the MonoConfig
lambdageek May 23, 2022
6334ee7
Add a mechanism to copy startup configs into the runtime and session
lambdageek May 23, 2022
4897241
WIP: C side startup provider copying
lambdageek May 31, 2022
43d6ec8
WIP checkpoint. Do more from JS
lambdageek Jun 2, 2022
b232adb
checkpoint: starting a session at startup works
lambdageek Jun 3, 2022
3d22fe1
WIP: checkpoint add a controller and a webworker for DS
lambdageek Jun 6, 2022
ee53f05
WIP checkpoint EventPipeIPCSession class skeleton
lambdageek Jun 8, 2022
6ddb829
WIP checkpoint: runtime crashes; but WS from JS works
lambdageek Jun 8, 2022
5c4aa81
WIP: diagnostic server
lambdageek Jun 14, 2022
dfcc613
XXX PrintfDebuggingHacks
lambdageek Jun 13, 2022
0daa0e0
WIP some bits of the websocket worker
lambdageek Jun 14, 2022
377a50a
WIP some notes on diagnostics and JS workers
lambdageek Jun 15, 2022
4a17d5d
fix eslint
lambdageek Jun 17, 2022
fd8df98
debug printfs etc
lambdageek Jun 17, 2022
f235f55
WIP: start moving the diagnostic server to a JS pthread
lambdageek Jun 21, 2022
431e2c6
WIP: move things around
lambdageek Jun 22, 2022
563b31a
cleanup
lambdageek Jun 23, 2022
5e999a3
notes
lambdageek Jun 22, 2022
2906e1e
[diagnostic_server] wasm-specific fn_table
lambdageek Jun 23, 2022
6c249f0
[wasm-ep] disable DS connect ports in C, too
lambdageek Jun 24, 2022
567484c
asyncify finalize_startup; make 1 diagnostics init function
lambdageek Jun 24, 2022
199cc80
(not implemented) set browser-eventpipe sample to start a DS server
lambdageek Jun 24, 2022
c3e7fe1
ping in the DS server (not functional yet)
lambdageek Jun 24, 2022
e64e539
Start diagnostic server pthread
lambdageek Jun 24, 2022
00f73ba
WIP try to start the server
lambdageek Jun 25, 2022
f803c3c
WIP diagnostic server server
lambdageek Jun 29, 2022
58851b4
Add a mock WebSocket connection to simulate the remote end
lambdageek Jul 1, 2022
c497c59
cleanup diagnostics.ts
lambdageek Jul 5, 2022
74d8443
wasm-mt: use a PThreadSelf struct instead of a raw MessagePort
lambdageek Jul 5, 2022
9ce7348
Move all the EP and diagnostic server modules to one directory
lambdageek Jul 5, 2022
e8fd671
Refactor; remove dead code; rationalize controller
lambdageek Jul 5, 2022
e8aace4
WIP more server pthread impl
lambdageek Jul 6, 2022
54e618b
WIP: start adding queue from streaming thread to DS thread
lambdageek Jul 6, 2022
c1c4c86
[wasm] Incremental build and rollup warnings cleanups
lambdageek Jul 7, 2022
2cca7f0
WIP: work on wiring up DS protocol commands (mock); resume hack
lambdageek Jul 7, 2022
0609be7
WIP: set up a WasmIpcStream, create EP sessions from DS
lambdageek Jul 8, 2022
9e00d8b
WIP: starting to stream works; needs PTHREAD_POOL_SIZE bump
lambdageek Jul 9, 2022
50e035c
cleanup browser-eventpipe sample
lambdageek Jul 10, 2022
69d0ca7
refactor to simplify and cleanup; rm duplicate code
lambdageek Jul 11, 2022
032e41e
call mono_wasm_event_pipe_early_startup_callback from event_pipe init
lambdageek Jul 11, 2022
637f88a
if diagnostics server isn't enabled, don't try to initialize it
lambdageek Jul 11, 2022
33c7d39
WIP: start parsing binary commands
lambdageek Jul 11, 2022
7c2d7a1
WIP: start wiring up binary protocol parsing to the websocket
lambdageek Jul 13, 2022
e015940
WIP: Can parse a CollectTracing2 command and attempt to create a
lambdageek Jul 14, 2022
182872c
[wasm-ep] use the new PromiseController<T>
lambdageek Jul 15, 2022
0e7a6ba
get back to the server loop quicker by queueing the parsing in the mi…
lambdageek Jul 15, 2022
6ef49c3
update mock for binary ADVR_V1 message
lambdageek Jul 15, 2022
76abc4d
sample: don't suspend, and use a mock url
lambdageek Jul 15, 2022
32dbdd9
use better values for parse results
lambdageek Jul 16, 2022
c417200
parse a few more binary protocol commands
lambdageek Jul 16, 2022
c3c9a25
wasm_ipc_stream: wire up close command
lambdageek Jul 18, 2022
07c0691
Send proper OK messages in replies to binary protocol commands
lambdageek Jul 18, 2022
ab5e247
(testing) turn off the file session for now
lambdageek Jul 18, 2022
bde9669
TODO: handle WS connection failures
lambdageek Jul 18, 2022
c4b8cc1
remove em_asm(console.log); simplify wasm EP init
lambdageek Jul 19, 2022
051e257
remove debug output
lambdageek Jul 19, 2022
c75ee2c
remove debug output in startup
lambdageek Jul 19, 2022
bca82f0
cleanup wasm ipc stream impl
lambdageek Jul 19, 2022
83e4d29
put diagnostics mocks behind a const flag
lambdageek Jul 19, 2022
7f95626
don't build wasm-specific DS if threads are disabled
lambdageek Jul 19, 2022
033b0c4
refactor and cleanup
lambdageek Jul 19, 2022
0d1eefe
help treeshaking
lambdageek Jul 19, 2022
be703f2
update DS design notes
lambdageek Jul 19, 2022
7a63e7e
remove more printfs
lambdageek Jul 19, 2022
e5d1838
use PromiseController in more places
lambdageek Jul 19, 2022
d92d45f
remove more console.debug in startup
lambdageek Jul 19, 2022
26751d6
Merge remote-tracking branch 'origin/main' into wasm-ep-on-startup
lambdageek Jul 19, 2022
530fa1c
fix Windows build
lambdageek Jul 19, 2022
ca2f204
add MONO_WASM prefix to console logging outputs
lambdageek Jul 19, 2022
d1d088a
fix sample logic when startup session is disabled
lambdageek Jul 20, 2022
e6979c1
improve debug output for DS server
lambdageek Jul 20, 2022
0bf7c0b
bugfix: don't confuse buf_addr for the value stored in it
lambdageek Jul 20, 2022
b3676b5
slight refactor of EventPipeSocketConnection and more logging
lambdageek Jul 20, 2022
2d22094
review feedback
lambdageek Jul 20, 2022
88ef693
Merge remote-tracking branch 'origin/main' into wasm-ep-on-startup
lambdageek Jul 20, 2022
b8b2148
merge fixup
lambdageek Jul 20, 2022
0de9719
fix bug in queue_push_sync main thread detection
lambdageek Jul 20, 2022
17d12e8
fix typo
lambdageek Jul 21, 2022
6abe463
Merge remote-tracking branch 'origin/main' into wasm-ep-on-startup
lambdageek Jul 22, 2022
d2f0acd
merge fixup
lambdageek Jul 22, 2022
2e135e7
fix rollup warning when making the crypto worker
lambdageek Jul 22, 2022
7da9d41
add MONO_WASM: prefix to logging
lambdageek Jul 22, 2022
f4219a6
make diagnostic server mocking friendlier
lambdageek Jul 21, 2022
18e199a
disable mocking in the sample project by default
lambdageek Jul 22, 2022
4bdbbfa
Merge remote-tracking branch 'origin/main' into wasm-ep-on-startup
lambdageek Jul 24, 2022
cbd4691
fixup after merge
lambdageek Jul 24, 2022
2fe9a3e
review feedback
lambdageek Jul 25, 2022
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
Prev Previous commit
Next Next commit
update DS design notes
  • Loading branch information
lambdageek committed Jul 19, 2022
commit be703f255cc94ef4a4d94b92dae0eb8183741804
55 changes: 9 additions & 46 deletions src/mono/wasm/runtime/diagnostics/diagnostic-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ We will need a dedicated thread to handle the WebSocket connections. This threa

- The diagnostic worker needs to start before the runtime starts - we have to be able to accept connections in "wait to start" mode to do startup profiling.

- The diagnostic worker needs to be able to send commands to the runtime. Or to directlly start sessions.
- The runtime needs to be able to send events from (some? all?) thread to the server.
- The diagnostic worker needs to be able to notify the runtime when the connection is closed. Or to directly stop sessions.
- WebSocket JS objects are not transferable between WebWorkers. So the diagnostic server worker needs to
forward streamed eventpipe data from the EventPipe session streaming thread to the WebSocket.

## Make the diagnostic Worker a pthread

Expand All @@ -31,49 +30,13 @@ Early during runtime startup if the appropriate bits are set, we will call into

The problem is if the diagnostic URL has a "suspend" option, the Worker should wait in JS for a resume command and then post a message back to the main thread to resume.

So we need to create a promise in the main thread that becomes resolved when we receive some kind of notification from the worker. We could use the `Atomics.waitAsync` to make a promise on the main thread that will resolve when the memory changes.
One idea was to use a promise on the main thread to wait for the diagnostic server to signal us. But that would be too early - before `mono_wasm_load_runtime` runs - and unfortunately the DS server needs to be able to create EventPipe session IDs before resuming the runtime. If we could break up `mono_wasm_load_runtime` into several callees we could set up the runtime threading and minimal EventPipie initialization and then pause until the resume.

## DS IPC stream

the native code for an EP session uses an `IpcStream` object to do the actual reading and writing which has a vtable of callbacks to provide the implementation.
We can use the `ds-ipc-pal-socket.c` implementation as a guide - essentially there's an `IpcStream` subclass that
has a custom vtable that has pointers to the functions to call.

Once we're sending the actual payloads, we can wrap up the bytes in a JS buffer and pass it over to websocket.

For this to work well we probably need the diagnostic Worker to be a pthread?

It would be nice if we didn't have to do our own message queue.

## Make our own MessagePort

the emscripten onmessage handler in the worker errors on unknown messages. the emscripten onmessage handler in the main thread ignores unknown messages.

So when mono starts a thread it can send over a port to the main thread.
But instead right now we busy-wait in the main thread in `ds_server_wasm_pause_for_diagnostics_monitor`. This at least processes the Emscripten dispatch queue (so other pthreads can do syscalls), but it hangs the browser UI.

then the main thread can talk to the worker thread.

There's a complication here that we need to be careful because emscripten reuses workers for pthreads. but if we only ever talk over the dedicated channel, it's probably good.

Emscripten `pthread_t` is a pointer. hope...fully... they're not reused.

Basically make `mono_thread_create_internal` run some JS that

## TODO

- [browser] in dotnet preInit read the config options. extract websocket URL and whether to suspend.
- [browser] call down to C to start diagnostics
- [browser] create a pthread and have it call the JS diagnostic server start and then set it to not die after thread main returns. return pthread id to JS.
- [server_worker] start listening on the URL.
- [browser] if suspending, listen for a continue event from the JS and await for that to resolve.
- [server_worker] when there's a session start event, if we were suspended, add a pending session, and send a continue event.
- [server_worker] wait for a "runtime started" event?
- [server_worker] when there's a new session start event, call down to C to start and EP session. **FIXME** need a port at this point -
- [browser] in early startup callback, start any pending EP sessions (and create ports for them to the diagnostic server)
- [session_streamer] call out to JS to post messages to the diagnostic server.
- [browser] in C, fire events, which will wake up the session streamer
- [session_streamer] post more messages

So the tricky bit is that for startup sessions and for "course of running" sessions, we need the browser thread to originate the message port transfer. (hopefully queuing work on the main thread is good enough?)
## DS IPC stream

Also the streamer thread probably needs to do a bunch of preliminary work in asynchronous JS before it can begin serving sessions.
The native code for an EP session uses an `IpcStream` object to do the actual reading and writing which has a vtable of callbacks to provide the implementation.
We implement our own `WasmIpcStream` that has a 1-element single-writer single-reader queue so that synchronous writes from the eventpipe streaming threads wake the diagnostic server to pull the filled buffer
and send it over the websocket.
There's no particular reason why this has to be (1) synchronous, (2) 1-element. Although that would make the implementation more complicated. If there's a perf issue here we could look into something more sophisticated.