diff options
author | José Rivero <jorive@microsoft.com> | 2019-05-28 23:17:02 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-28 23:17:02 -0700 |
commit | 19edba3699daca1002bcd748e152d526d5b7bb69 (patch) | |
tree | c44be3a305bbb2a727a8f32a3895880568d80368 /src/vm/sampleprofiler.h | |
parent | c614a00fed86ffa921b55d169bb6a7eb8625c7ff (diff) | |
download | coreclr-19edba3699daca1002bcd748e152d526d5b7bb69.tar.gz coreclr-19edba3699daca1002bcd748e152d526d5b7bb69.tar.bz2 coreclr-19edba3699daca1002bcd748e152d526d5b7bb69.zip |
Create the Concept of Multiple EventPipe Sessions (#24417)
This is the initial work to enable https://github.com/dotnet/coreclr/issues/15377
## What's here?
- A lot of code move/split. Some important moves:
- `EventPipe` has a colection of `EventPipeSessions` instead of a single session.
- `EventPipeSession` now owns a `EventPipeBufferManager` and a `EventPipeFile`
- `EventPipeThread` now owns a collection of { EventPipeBufferManager, EventPipeBuffer }, and a collection of { EventPipeBufferManager, EventPipeBufferList }
- There is a cap on the max number of `EventPipeSession` (64 sessions)
- `EventPipeProvider` and `EventPipeEvent` use a 64-bit mask to keep track of the sessions that are listening to provider/events.
## What's pending?
https://github.com/dotnet/coreclr/issues/24753
Diffstat (limited to 'src/vm/sampleprofiler.h')
-rw-r--r-- | src/vm/sampleprofiler.h | 143 |
1 files changed, 75 insertions, 68 deletions
diff --git a/src/vm/sampleprofiler.h b/src/vm/sampleprofiler.h index dd8009b071..edf3717017 100644 --- a/src/vm/sampleprofiler.h +++ b/src/vm/sampleprofiler.h @@ -10,7 +10,7 @@ #include "common.h" #include "eventpipe.h" -enum class SampleProfilerSampleType +enum class SampleProfilerSampleType : uint32_t { Error = 0, External = 1, @@ -19,87 +19,94 @@ enum class SampleProfilerSampleType class SampleProfiler { - // Declare friends. friend class EventPipe; - public: - - // Enable profiling. - static void Enable(EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue); - - // Disable profiling. - static void Disable(); - - // Set the sampling rate. - static void SetSamplingRate(unsigned long nanoseconds); - - static unsigned long GetSamplingRate() - { - LIMITED_METHOD_CONTRACT; - - return s_samplingRateInNs; - } - - private: - - // Iterate through all managed threads and walk all stacks. - static void WalkManagedThreads(); - - // Profiling thread proc. Invoked on a new thread when profiling is enabled. - static DWORD WINAPI ThreadProc(void *args); - - // Calls either PAL_nanosleep or ClrSleepEx depending on platform - // Note: Although we specify the time in ns, that is no indication - // of the actually accuracy with which we will return from sleep - // In reality Unix will have a minimum granularity of ~10ms - // and Windows has a default granularity of ~16ms, but can be - // adjusted to as low as ~1ms - // Even this however is not gaurenteed. If the system is under load - // the sampling thread may be delayed up to hundreds of ms due to - // scheduling priority. There is no way to prevent this from user threads - // Additionally we may get lucky and there will be an open CPU to run - // and under light load the timings will achieve great accuracy! - static void PlatformSleep(unsigned long nanoseconds); - - static bool LoadDependencies(); - static void UnloadDependencies(); +public: + // Initialize the sample profiler. + static void Initialize(EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue); + + // Enable profiling. + static void Enable(EventPipeProviderCallbackDataQueue *pEventPipeProviderCallbackDataQueue); + + // Disable profiling. + static void Disable(); + + // Set the sampling rate. + static void SetSamplingRate(unsigned long nanoseconds); + + static unsigned long GetSamplingRate() + { + LIMITED_METHOD_CONTRACT; + return s_samplingRateInNs; + } + +private: + union SampleProfilerPayload + { + SampleProfilerSampleType Type; + BYTE Rawdata[sizeof(SampleProfilerSampleType)]; + }; + + // Iterate through all managed threads and walk all stacks. + static void WalkManagedThreads(); + + // Profiling thread proc. Invoked on a new thread when profiling is enabled. + static DWORD WINAPI ThreadProc(void *args); + + // Calls either PAL_nanosleep or ClrSleepEx depending on platform + // Note: Although we specify the time in ns, that is no indication + // of the actually accuracy with which we will return from sleep + // In reality Unix will have a minimum granularity of ~10ms + // and Windows has a default granularity of ~16ms, but can be + // adjusted to as low as ~1ms + // Even this however is not gaurenteed. If the system is under load + // the sampling thread may be delayed up to hundreds of ms due to + // scheduling priority. There is no way to prevent this from user threads + // Additionally we may get lucky and there will be an open CPU to run + // and under light load the timings will achieve great accuracy! + static void PlatformSleep(unsigned long nanoseconds); + + static bool LoadDependencies(); + static void UnloadDependencies(); #ifndef FEATURE_PAL - static HINSTANCE s_hMultimediaLib; - static PVOID s_timeBeginPeriodFn; - static PVOID s_timeEndPeriodFn; + static HINSTANCE s_hMultimediaLib; + static PVOID s_timeBeginPeriodFn; + static PVOID s_timeEndPeriodFn; #endif //FEATURE_PAL - static void SetTimeGranularity(); - static void ResetTimeGranularity(); + static void SetTimeGranularity(); + static void ResetTimeGranularity(); + + // True when profiling is enabled. + static Volatile<BOOL> s_profilingEnabled; - // True when profiling is enabled. - static Volatile<BOOL> s_profilingEnabled; + // The sampling thread. + static Thread *s_pSamplingThread; - // The sampling thread. - static Thread *s_pSamplingThread; + // The provider and event emitted by the profiler. + static const WCHAR *s_providerName; + static EventPipeProvider *s_pEventPipeProvider; + static EventPipeEvent *s_pThreadTimeEvent; - // The provider and event emitted by the profiler. - static const WCHAR* s_providerName; - static EventPipeProvider *s_pEventPipeProvider; - static EventPipeEvent *s_pThreadTimeEvent; + // Event payloads. + // External represents a sample in external or native code. + // Managed represents a sample in managed code. + static SampleProfilerPayload s_ExternalPayload; + static SampleProfilerPayload s_ManagedPayload; + static const unsigned int c_payloadSize = sizeof(unsigned int); - // Event payloads. - // External represents a sample in external or native code. - // Managed represents a sample in managed code. - static BYTE *s_pPayloadExternal; - static BYTE *s_pPayloadManaged; - static const unsigned int c_payloadSize = sizeof(unsigned int); + // Thread shutdown event for synchronization between Disable() and the sampling thread. + static CLREventStatic s_threadShutdownEvent; - // Thread shutdown event for synchronization between Disable() and the sampling thread. - static CLREventStatic s_threadShutdownEvent; + // The sampling rate. + static unsigned long s_samplingRateInNs; - // The sampling rate. - static unsigned long s_samplingRateInNs; + // Whether or not timeBeginPeriod has been used to set the scheduler period + static bool s_timePeriodIsSet; - // Whether or not timeBeginPeriod has been used to set the scheduler period - static bool s_timePeriodIsSet; + static int32_t s_RefCount; }; #endif // FEATURE_PERFTRACING |