Allow coniguration of sampling rate. (#11595)
authorBrian Robbins <brianrob@microsoft.com>
Mon, 15 May 2017 15:15:51 +0000 (08:15 -0700)
committerVance Morrison <vancem@microsoft.com>
Mon, 15 May 2017 15:15:51 +0000 (08:15 -0700)
src/mscorlib/src/System/Diagnostics/Eventing/EventPipe.cs
src/vm/eventpipe.cpp
src/vm/eventpipe.h
src/vm/sampleprofiler.cpp
src/vm/sampleprofiler.h

index 4c6778f..d962023 100644 (file)
@@ -56,6 +56,7 @@ namespace System.Diagnostics.Tracing
         private string m_outputFile;
         private uint m_circularBufferSizeInMB;
         private List<EventPipeProviderConfiguration> 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]
index 6f6108d..5805641 100644 (file)
@@ -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;
 }
index 97d873e..180a768 100644 (file)
@@ -272,6 +272,7 @@ public:
     static void QCALLTYPE Enable(
         __in_z LPCWSTR outputFile,
         unsigned int circularBufferSizeInMB,
+        long profilerSamplingRateInNanoseconds,
         EventPipeProviderConfiguration *pProviders,
         int numProviders);
 
index 7c6429a..3ed1a5b 100644 (file)
@@ -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
         }
     }
 
index 19deb08..1992e1c 100644 (file)
@@ -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