From 1cf39a4e686668f35aec3f336615c422e3cc9fec Mon Sep 17 00:00:00 2001 From: Brian Robbins Date: Mon, 15 May 2017 08:15:51 -0700 Subject: [PATCH] Allow coniguration of sampling rate. (#11595) --- .../src/System/Diagnostics/Eventing/EventPipe.cs | 20 +++++++++++++++++++- src/vm/eventpipe.cpp | 2 ++ src/vm/eventpipe.h | 1 + src/vm/sampleprofiler.cpp | 16 ++++++---------- src/vm/sampleprofiler.h | 5 +++-- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventPipe.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventPipe.cs index 4c6778f..d962023 100644 --- a/src/mscorlib/src/System/Diagnostics/Eventing/EventPipe.cs +++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventPipe.cs @@ -56,6 +56,7 @@ namespace System.Diagnostics.Tracing private string m_outputFile; private uint m_circularBufferSizeInMB; private List m_providers; + private TimeSpan m_minTimeBetweenSamples = TimeSpan.FromMilliseconds(1); internal EventPipeConfiguration( string outputFile, @@ -89,6 +90,12 @@ namespace System.Diagnostics.Tracing get { return m_providers.ToArray(); } } + internal long ProfilerSamplingRateInNanoseconds + { + // 100 nanoseconds == 1 tick. + get { return m_minTimeBetweenSamples.Ticks * 100; } + } + internal void EnableProvider(string providerName, UInt64 keywords, uint loggingLevel) { m_providers.Add(new EventPipeProviderConfiguration( @@ -96,6 +103,16 @@ namespace System.Diagnostics.Tracing keywords, loggingLevel)); } + + internal void SetProfilerSamplingRate(TimeSpan minTimeBetweenSamples) + { + if(minTimeBetweenSamples.Ticks <= 0) + { + throw new ArgumentOutOfRangeException(nameof(minTimeBetweenSamples)); + } + + m_minTimeBetweenSamples = minTimeBetweenSamples; + } } internal static class EventPipe @@ -112,6 +129,7 @@ namespace System.Diagnostics.Tracing EventPipeInternal.Enable( configuration.OutputFile, configuration.CircularBufferSizeInMB, + configuration.ProfilerSamplingRateInNanoseconds, providers, providers.Length); } @@ -129,7 +147,7 @@ namespace System.Diagnostics.Tracing // [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] - internal static extern void Enable(string outputFile, uint circularBufferSizeInMB, EventPipeProviderConfiguration[] providers, int numProviders); + internal static extern void Enable(string outputFile, uint circularBufferSizeInMB, long profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration[] providers, int numProviders); [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [SuppressUnmanagedCodeSecurity] diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp index 6f6108d..5805641 100644 --- a/src/vm/eventpipe.cpp +++ b/src/vm/eventpipe.cpp @@ -446,12 +446,14 @@ CrstStatic* EventPipe::GetLock() void QCALLTYPE EventPipeInternal::Enable( __in_z LPCWSTR outputFile, unsigned int circularBufferSizeInMB, + long profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration *pProviders, int numProviders) { QCALL_CONTRACT; BEGIN_QCALL; + SampleProfiler::SetSamplingRate(profilerSamplingRateInNanoseconds); EventPipe::Enable(outputFile, circularBufferSizeInMB, pProviders, numProviders); END_QCALL; } diff --git a/src/vm/eventpipe.h b/src/vm/eventpipe.h index 97d873e..180a768 100644 --- a/src/vm/eventpipe.h +++ b/src/vm/eventpipe.h @@ -272,6 +272,7 @@ public: static void QCALLTYPE Enable( __in_z LPCWSTR outputFile, unsigned int circularBufferSizeInMB, + long profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration *pProviders, int numProviders); diff --git a/src/vm/sampleprofiler.cpp b/src/vm/sampleprofiler.cpp index 7c6429a..3ed1a5b 100644 --- a/src/vm/sampleprofiler.cpp +++ b/src/vm/sampleprofiler.cpp @@ -17,9 +17,7 @@ const GUID SampleProfiler::s_providerID = {0x3c530d44,0x97ae,0x513a,{0x1e,0x6d,0 EventPipeProvider* SampleProfiler::s_pEventPipeProvider = NULL; EventPipeEvent* SampleProfiler::s_pThreadTimeEvent = NULL; CLREventStatic SampleProfiler::s_threadShutdownEvent; -#ifdef FEATURE_PAL long SampleProfiler::s_samplingRateInNs = 1000000; // 1ms -#endif void SampleProfiler::Enable() { @@ -88,6 +86,12 @@ void SampleProfiler::Disable() s_threadShutdownEvent.Wait(0, FALSE /* bAlertable */); } +void SampleProfiler::SetSamplingRate(long nanoseconds) +{ + LIMITED_METHOD_CONTRACT; + s_samplingRateInNs = nanoseconds; +} + DWORD WINAPI SampleProfiler::ThreadProc(void *args) { CONTRACTL @@ -111,11 +115,7 @@ DWORD WINAPI SampleProfiler::ThreadProc(void *args) if(ThreadSuspend::SysIsSuspendInProgress() || (ThreadSuspend::GetSuspensionThread() != 0)) { // Skip the current sample. -#ifdef FEATURE_PAL PAL_nanosleep(s_samplingRateInNs); -#else - ClrSleepEx(1, FALSE); -#endif continue; } @@ -129,11 +129,7 @@ DWORD WINAPI SampleProfiler::ThreadProc(void *args) ThreadSuspend::RestartEE(FALSE /* bFinishedGC */, TRUE /* SuspendSucceeded */); // Wait until it's time to sample again. -#ifdef FEATURE_PAL PAL_nanosleep(s_samplingRateInNs); -#else - ClrSleepEx(1, FALSE); -#endif } } diff --git a/src/vm/sampleprofiler.h b/src/vm/sampleprofiler.h index 19deb08..1992e1c 100644 --- a/src/vm/sampleprofiler.h +++ b/src/vm/sampleprofiler.h @@ -25,6 +25,9 @@ class SampleProfiler // Disable profiling. static void Disable(); + // Set the sampling rate. + static void SetSamplingRate(long nanoseconds); + private: // Iterate through all managed threads and walk all stacks. @@ -47,10 +50,8 @@ class SampleProfiler // Thread shutdown event for synchronization between Disable() and the sampling thread. static CLREventStatic s_threadShutdownEvent; -#ifdef FEATURE_PAL // The sampling rate. static long s_samplingRateInNs; -#endif }; #endif // FEATURE_PERFTRACING -- 2.7.4