G_BEGIN_DECLS
@@ -27,12 +28,12 @@ typedef uint32_t MonoWasmEventPipeSessionID;
EMSCRIPTEN_KEEPALIVE gboolean
mono_wasm_event_pipe_enable (const ep_char8_t *output_path,
+ IpcStream *ipc_stream,
uint32_t circular_buffer_size_in_mb,
const ep_char8_t *providers,
/* EventPipeSessionType session_type = EP_SESSION_TYPE_FILE, */
/* EventPipieSerializationFormat format = EP_SERIALIZATION_FORMAT_NETTRACE_V4, */
/* bool */ gboolean rundown_requested,
- /* IpcStream stream = NULL, */
/* EventPipeSessionSycnhronousCallback sync_callback = NULL, */
/* void *callback_additional_data, */
MonoWasmEventPipeSessionID *out_session_id);
@@ -43,6 +44,18 @@ mono_wasm_event_pipe_session_start_streaming (MonoWasmEventPipeSessionID session
EMSCRIPTEN_KEEPALIVE gboolean
mono_wasm_event_pipe_session_disable (MonoWasmEventPipeSessionID session_id);
+EMSCRIPTEN_KEEPALIVE gboolean
+mono_wasm_diagnostic_server_create_thread (const char *websocket_url, pthread_t *out_thread_id);
+
+EMSCRIPTEN_KEEPALIVE void
+mono_wasm_diagnostic_server_thread_attach_to_runtime (void);
+
+EMSCRIPTEN_KEEPALIVE void
+mono_wasm_diagnostic_server_post_resume_runtime (void);
+
+EMSCRIPTEN_KEEPALIVE IpcStream *
+mono_wasm_diagnostic_server_create_stream (void);
+
G_END_DECLS
#endif /* HOST_WASM */
diff --git a/src/mono/mono/component/event_pipe.c b/src/mono/mono/component/event_pipe.c
index f0c4b24583ba20..4d59f5af94b681 100644
--- a/src/mono/mono/component/event_pipe.c
+++ b/src/mono/mono/component/event_pipe.c
@@ -98,9 +98,18 @@ event_pipe_wait_for_session_signal (
EventPipeSessionID session_id,
uint32_t timeout);
+#ifdef HOST_WASM
+static void
+mono_wasm_event_pipe_init (void);
+#endif
+
static MonoComponentEventPipe fn_table = {
{ MONO_COMPONENT_ITF_VERSION, &event_pipe_available },
+#ifndef HOST_WASM
&ep_init,
+#else
+ &mono_wasm_event_pipe_init,
+#endif
&ep_finish_init,
&ep_shutdown,
&event_pipe_enable,
@@ -354,19 +363,22 @@ wasm_to_ep_session_id (MonoWasmEventPipeSessionID session_id)
EMSCRIPTEN_KEEPALIVE gboolean
mono_wasm_event_pipe_enable (const ep_char8_t *output_path,
+ IpcStream *ipc_stream,
uint32_t circular_buffer_size_in_mb,
const ep_char8_t *providers,
/* EventPipeSessionType session_type = EP_SESSION_TYPE_FILE, */
/* EventPipieSerializationFormat format = EP_SERIALIZATION_FORMAT_NETTRACE_V4, */
/* bool */ gboolean rundown_requested,
- /* IpcStream stream = NULL, */
/* EventPipeSessionSycnhronousCallback sync_callback = NULL, */
/* void *callback_additional_data, */
MonoWasmEventPipeSessionID *out_session_id)
{
MONO_ENTER_GC_UNSAFE;
EventPipeSerializationFormat format = EP_SERIALIZATION_FORMAT_NETTRACE_V4;
- EventPipeSessionType session_type = EP_SESSION_TYPE_FILE;
+ EventPipeSessionType session_type = output_path != NULL ? EP_SESSION_TYPE_FILE : EP_SESSION_TYPE_IPCSTREAM;
+
+ g_assert ((output_path == NULL && ipc_stream != NULL) ||
+ (output_path != NULL && ipc_stream == NULL));
EventPipeSessionID session;
session = ep_enable_2 (output_path,
@@ -375,7 +387,7 @@ mono_wasm_event_pipe_enable (const ep_char8_t *output_path,
session_type,
format,
!!rundown_requested,
- /* stream */NULL,
+ ipc_stream,
/* callback*/ NULL,
/* callback_data*/ NULL);
@@ -403,4 +415,15 @@ mono_wasm_event_pipe_session_disable (MonoWasmEventPipeSessionID session_id)
return TRUE;
}
+// JS callback to invoke on the main thread early during runtime initialization once eventpipe is functional but before too much of the rest of the runtime is loaded.
+extern void mono_wasm_event_pipe_early_startup_callback (void);
+
+
+static void
+mono_wasm_event_pipe_init (void)
+{
+ ep_init ();
+ mono_wasm_event_pipe_early_startup_callback ();
+}
+
#endif /* HOST_WASM */
diff --git a/src/mono/mono/utils/mono-threads-wasm.h b/src/mono/mono/utils/mono-threads-wasm.h
index f73192c7c47b7d..c06d8501e1ec3e 100644
--- a/src/mono/mono/utils/mono-threads-wasm.h
+++ b/src/mono/mono/utils/mono-threads-wasm.h
@@ -42,6 +42,23 @@ mono_threads_wasm_async_run_in_main_thread_vi (void (*func)(gpointer), gpointer
void
mono_threads_wasm_async_run_in_main_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)
+{
+ // Don't call this on the main thread!
+ // See https://github.com/WebAssembly/threads/issues/174
+ // memory.atomic.wait32
+ //
+ // timeout_ns == -1 means infinite wait
+ //
+ // return values:
+ // 0 == "ok", thread blocked and was woken up
+ // 1 == "not-equal", value at addr was not equal to expected
+ // 2 == "timed-out", timeout expired before thread was woken up
+ return __builtin_wasm_memory_atomic_wait32((int32_t*)addr, expected, timeout_ns);
+}
#endif /* DISABLE_THREADS */
// Called from register_thread when a pthread attaches to the runtime
diff --git a/src/mono/sample/wasm/browser-eventpipe/Wasm.Browser.EventPipe.Sample.csproj b/src/mono/sample/wasm/browser-eventpipe/Wasm.Browser.EventPipe.Sample.csproj
index 8bcabdb2ea181c..94253eaed38346 100644
--- a/src/mono/sample/wasm/browser-eventpipe/Wasm.Browser.EventPipe.Sample.csproj
+++ b/src/mono/sample/wasm/browser-eventpipe/Wasm.Browser.EventPipe.Sample.csproj
@@ -13,12 +13,32 @@
CA2007
+
+ false
+
+
-
+
+
+
+
+
+
+
diff --git a/src/mono/sample/wasm/browser-eventpipe/index.html b/src/mono/sample/wasm/browser-eventpipe/index.html
index 9d97103c7de467..dd13b5fb6c661f 100644
--- a/src/mono/sample/wasm/browser-eventpipe/index.html
+++ b/src/mono/sample/wasm/browser-eventpipe/index.html
@@ -18,7 +18,6 @@
Computing Fib(N) repeatedly:
-