1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5#ifndef __SAMPLEPROFILER_H__
6#define __SAMPLEPROFILER_H__
7
8#ifdef FEATURE_PERFTRACING
9
10#include "common.h"
11#include "eventpipe.h"
12
13enum class SampleProfilerSampleType
14{
15 Error = 0,
16 External = 1,
17 Managed = 2
18};
19
20class SampleProfiler
21{
22
23 // Declare friends.
24 friend class EventPipe;
25 friend class SampleProfilerEventInstance;
26
27 public:
28
29 // Enable profiling.
30 static void Enable();
31
32 // Disable profiling.
33 static void Disable();
34
35 // Set the sampling rate.
36 static void SetSamplingRate(unsigned long nanoseconds);
37
38 static unsigned long GetSamplingRate()
39 {
40 LIMITED_METHOD_CONTRACT;
41
42 return s_samplingRateInNs;
43 }
44
45 private:
46
47 // Iterate through all managed threads and walk all stacks.
48 static void WalkManagedThreads();
49
50 // Profiling thread proc. Invoked on a new thread when profiling is enabled.
51 static DWORD WINAPI ThreadProc(void *args);
52
53 // Calls either PAL_nanosleep or ClrSleepEx depending on platform
54 // Note: Although we specify the time in ns, that is no indication
55 // of the actually accuracy with which we will return from sleep
56 // In reality Unix will have a minimum granularity of ~10ms
57 // and Windows has a default granularity of ~16ms, but can be
58 // adjusted to as low as ~1ms
59 // Even this however is not gaurenteed. If the system is under load
60 // the sampling thread may be delayed up to hundreds of ms due to
61 // scheduling priority. There is no way to prevent this from user threads
62 // Additionally we may get lucky and there will be an open CPU to run
63 // and under light load the timings will achieve great accuracy!
64 static void PlatformSleep(unsigned long nanoseconds);
65
66 static bool LoadDependencies();
67 static void UnloadDependencies();
68
69#ifndef FEATURE_PAL
70 static HINSTANCE s_hMultimediaLib;
71 static PVOID s_timeBeginPeriodFn;
72 static PVOID s_timeEndPeriodFn;
73#endif //FEATURE_PAL
74
75 static void SetTimeGranularity();
76 static void ResetTimeGranularity();
77
78 // True when profiling is enabled.
79 static Volatile<BOOL> s_profilingEnabled;
80
81 // The sampling thread.
82 static Thread *s_pSamplingThread;
83
84 // The provider and event emitted by the profiler.
85 static const WCHAR* s_providerName;
86 static EventPipeProvider *s_pEventPipeProvider;
87 static EventPipeEvent *s_pThreadTimeEvent;
88
89 // Event payloads.
90 // External represents a sample in external or native code.
91 // Managed represents a sample in managed code.
92 static BYTE *s_pPayloadExternal;
93 static BYTE *s_pPayloadManaged;
94 static const unsigned int c_payloadSize = sizeof(unsigned int);
95
96 // Thread shutdown event for synchronization between Disable() and the sampling thread.
97 static CLREventStatic s_threadShutdownEvent;
98
99 // The sampling rate.
100 static unsigned long s_samplingRateInNs;
101
102 // Whether or not timeBeginPeriod has been used to set the scheduler period
103 static bool s_timePeriodIsSet;
104};
105
106#endif // FEATURE_PERFTRACING
107
108#endif // __SAMPLEPROFILER_H__
109