diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h index 7e280e3e059be6..7767eb65a9b9c4 100644 --- a/src/coreclr/inc/clrconfigvalues.h +++ b/src/coreclr/inc/clrconfigvalues.h @@ -610,6 +610,7 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeCircularMB, W("EventPipeCircularMB"), RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeProcNumbers, W("EventPipeProcNumbers"), 0, "Enable/disable capturing processor numbers in EventPipe event headers") RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeOutputStreaming, W("EventPipeOutputStreaming"), 1, "Enable/disable streaming for trace file set in DOTNET_EventPipeOutputPath. Non-zero values enable streaming.") RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeEnableStackwalk, W("EventPipeEnableStackwalk"), 1, "Set to 0 to disable collecting stacks for EventPipe events.") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeThreadSamplingRate, W("EventPipeThreadSamplingRate"), 0, "Desired sample interval in milliseconds for EventPipe thread time sampling profiler. 0 means use the default.") #ifdef FEATURE_AUTO_TRACE RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_AutoTrace_N_Tracers, W("AutoTrace_N_Tracers"), 0, "", CLRConfig::LookupOptions::ParseIntegerAsBase10) diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 78d6578dce29c8..c9ae8dcbd80c8e 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -507,6 +507,23 @@ ep_rt_config_value_get_enable_stackwalk (void) return false; } +static +inline +uint32_t +ep_rt_config_value_get_sampling_rate (void) +{ + STATIC_CONTRACT_NOTHROW; + + uint64_t value; + if (RhConfig::Environment::TryGetIntegerValue("EventPipeThreadSamplingRate", &value, true)) + { + EP_ASSERT(value <= UINT32_MAX); + return static_cast(value); + } + + return 0; +} + /* * EventPipeSampleProfiler. */ diff --git a/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h b/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h index 97991823eaff97..ebb46b8eb5396c 100644 --- a/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h +++ b/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h @@ -444,9 +444,9 @@ ep_rt_provider_config_init (EventPipeProviderConfiguration *provider_config) // This function is auto-generated from /src/scripts/genEventPipe.py #ifdef TARGET_UNIX extern "C" void InitProvidersAndEvents (); -#else +#else // TARGET_UNIX extern void InitProvidersAndEvents (); -#endif +#endif // TARGET_UNIX static void @@ -572,6 +572,15 @@ ep_rt_config_value_get_enable_stackwalk (void) return CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EventPipeEnableStackwalk) != 0; } +static +inline +uint32_t +ep_rt_config_value_get_sampling_rate (void) +{ + STATIC_CONTRACT_NOTHROW; + return CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EventPipeThreadSamplingRate); +} + /* * EventPipeSampleProfiler. */ @@ -622,13 +631,12 @@ void ep_rt_notify_profiler_provider_created (EventPipeProvider *provider) { STATIC_CONTRACT_NOTHROW; - -#ifndef DACCESS_COMPILE +#if !defined(DACCESS_COMPILE) && defined(PROFILING_SUPPORTED) // Let the profiler know the provider has been created so it can register if it wants to BEGIN_PROFILER_CALLBACK (CORProfilerTrackEventPipe ()); (&g_profControlBlock)->EventPipeProviderCreated (provider); END_PROFILER_CALLBACK (); -#endif // DACCESS_COMPILE +#endif // !DACCESS_COMPILE && PROFILING_SUPPORTED } /* diff --git a/src/mono/browser/build/WasmApp.InTree.props b/src/mono/browser/build/WasmApp.InTree.props index d097d45119197d..9031c6f6d0cc25 100644 --- a/src/mono/browser/build/WasmApp.InTree.props +++ b/src/mono/browser/build/WasmApp.InTree.props @@ -14,10 +14,14 @@ - + false + false + + true + library diff --git a/src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c b/src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c index 2fff49357e844c..5503c2c0b9eebf 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c +++ b/src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c @@ -1507,8 +1507,6 @@ void ep_rt_mono_sample_profiler_enabled (EventPipeEvent *sampling_event) { desired_sample_interval_ms = ((double)ep_sample_profiler_get_sampling_rate ()) / 1000000.0; - EP_ASSERT (desired_sample_interval_ms >= 0.0); - EP_ASSERT (desired_sample_interval_ms < 1000.0); current_sampling_event = sampling_event; current_sampling_thread = ep_rt_thread_get_handle (); diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index ce5c7f7e95af96..a5f3c2626509ed 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -637,6 +637,25 @@ ep_rt_config_value_get_enable_stackwalk (void) return value_uint32_t != 0; } +static +inline +uint32_t +ep_rt_config_value_get_sampling_rate (void) +{ + uint32_t value_uint32_t = 0; + gchar *value = g_getenv ("DOTNET_EventPipeThreadSamplingRate"); + if (!value) + value = g_getenv ("COMPlus_EventPipeThreadSamplingRate"); + if (value) { + gchar *endptr = NULL; + guint64 parsed = strtoull (value, &endptr, 10); + if (endptr != value && *endptr == '\0' && value [0] != '-' && parsed <= G_MAXUINT32) + value_uint32_t = (uint32_t)parsed; + } + g_free (value); + return value_uint32_t; +} + /* * EventPipeSampleProfiler. */ diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index 1ef84bdfc7b757..6442c23e87d1ac 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -482,9 +482,22 @@ Copyright (c) .NET Foundation. All rights reserved. - + + + <_WasmPerfInstFilter>$(WasmPerformanceInstrumentation) + <_WasmPerfInstInterval> + <_WasmPerfInstDescriptor> + <_WasmPerfInstInterval Condition="$(WasmPerformanceInstrumentation.Contains(',interval='))">$(WasmPerformanceInstrumentation.Substring($([MSBuild]::Add($(WasmPerformanceInstrumentation.IndexOf(',interval=')), 10)))) + <_WasmPerfInstFilter Condition="$(WasmPerformanceInstrumentation.Contains(',interval='))">$(WasmPerformanceInstrumentation.Substring(0, $(WasmPerformanceInstrumentation.IndexOf(',interval=')))) + <_WasmPerfInstInterval Condition="'$(_WasmPerfInstInterval)' != '' and $(_WasmPerfInstInterval.Contains(','))">$(_WasmPerfInstInterval.Substring(0, $(_WasmPerfInstInterval.IndexOf(',')))) + <_WasmPerfInstDescriptor Condition="'$(_WasmPerfInstFilter)' != '' and '$(UseMonoRuntime)' != 'false'">eventpipe,callspec=$(_WasmPerfInstFilter) + <_WasmPerfInstFilter Condition="'$(_WasmPerfInstFilter)' == 'all' and '$(UseMonoRuntime)' == 'false'">* + <_WasmPerfInstDescriptor Condition="'$(_WasmPerfInstFilter)' != '' and '$(UseMonoRuntime)' == 'false'">$(_WasmPerfInstFilter) + + + diff --git a/src/native/eventpipe/ds-ipc-pal-websocket.h b/src/native/eventpipe/ds-ipc-pal-websocket.h index 1273d9367c9d41..9b948ab89ed4db 100644 --- a/src/native/eventpipe/ds-ipc-pal-websocket.h +++ b/src/native/eventpipe/ds-ipc-pal-websocket.h @@ -53,11 +53,17 @@ struct _DiagnosticsIpcStream { }; #endif +#ifdef __cplusplus +extern "C" { +#endif extern int ds_rt_websocket_poll (int client_socket); extern int ds_rt_websocket_create (const char* url); -extern int ds_rt_websocket_recv (int client_socket, const uint8_t* buffer, uint32_t bytes_to_read); +extern int ds_rt_websocket_recv (int client_socket, uint8_t* buffer, uint32_t bytes_to_read); extern int ds_rt_websocket_send (int client_socket, const uint8_t* buffer, uint32_t bytes_to_write); extern int ds_rt_websocket_close(int client_socket); +#ifdef __cplusplus +} +#endif #endif /* ENABLE_PERFTRACING */ #endif /* __DIAGNOSTICS_IPC_PAL_WEB_SOCKET_H__ */ diff --git a/src/native/eventpipe/ep-rt.h b/src/native/eventpipe/ep-rt.h index ef28cb5147240c..d3cc68db3ffded 100644 --- a/src/native/eventpipe/ep-rt.h +++ b/src/native/eventpipe/ep-rt.h @@ -200,6 +200,11 @@ inline bool ep_rt_config_value_get_enable_stackwalk (void); +static +inline +uint32_t +ep_rt_config_value_get_sampling_rate (void); + /* * EventPipeSampleProfiler. */ diff --git a/src/native/eventpipe/ep.c b/src/native/eventpipe/ep.c index 0b45cf280d3fdc..9cf4acff6bdfed 100644 --- a/src/native/eventpipe/ep.c +++ b/src/native/eventpipe/ep.c @@ -1496,7 +1496,13 @@ ep_init (void) #else // PERFTRACING_DISABLE_THREADS const uint32_t default_profiler_sample_rate_in_nanoseconds = 5000000; // 5 msec. #endif // PERFTRACING_DISABLE_THREADS - ep_sample_profiler_set_sampling_rate (default_profiler_sample_rate_in_nanoseconds); + + // Allow overriding the sampling rate via DOTNET_EventPipeThreadSamplingRate (in milliseconds). + uint32_t configured_rate_ms = ep_rt_config_value_get_sampling_rate (); + if (configured_rate_ms > 0) + ep_sample_profiler_set_sampling_rate ((uint64_t)configured_rate_ms * 1000000); + else + ep_sample_profiler_set_sampling_rate (default_profiler_sample_rate_in_nanoseconds); _ep_deferred_enable_session_ids = dn_vector_alloc_t (EventPipeSessionID); _ep_deferred_disable_session_ids = dn_vector_alloc_t (EventPipeSessionID);