Replace compGetMemArray uses
[platform/upstream/coreclr.git] / src / System.Private.CoreLib / src / System / Diagnostics / Eventing / EventPipe.cs
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 using System.Collections.Generic;
5 using System.Runtime.CompilerServices;
6 using System.Runtime.InteropServices;
7 using System.Security;
8 using Microsoft.Win32;
9
10 namespace System.Diagnostics.Tracing
11 {
12     [StructLayout(LayoutKind.Sequential)]
13     internal struct EventPipeProviderConfiguration
14     {
15         [MarshalAs(UnmanagedType.LPWStr)]
16         private string m_providerName;
17         private ulong m_keywords;
18         private uint m_loggingLevel;
19
20         internal EventPipeProviderConfiguration(
21             string providerName,
22             ulong keywords,
23             uint loggingLevel)
24         {
25             if(string.IsNullOrEmpty(providerName))
26             {
27                 throw new ArgumentNullException(nameof(providerName));
28             }
29             if(loggingLevel > 5) // 5 == Verbose, the highest value in EventPipeLoggingLevel.
30             {
31                 throw new ArgumentOutOfRangeException(nameof(loggingLevel));
32             }
33             m_providerName = providerName;
34             m_keywords = keywords;
35             m_loggingLevel = loggingLevel;
36         }
37
38         internal string ProviderName
39         {
40             get { return m_providerName; }
41         }
42
43         internal ulong Keywords
44         {
45             get { return m_keywords; }
46         }
47
48         internal uint LoggingLevel
49         {
50             get { return m_loggingLevel; }
51         }
52     }
53
54     internal sealed class EventPipeConfiguration
55     {
56         private string m_outputFile;
57         private uint m_circularBufferSizeInMB;
58         private List<EventPipeProviderConfiguration> m_providers;
59         private TimeSpan m_minTimeBetweenSamples = TimeSpan.FromMilliseconds(1);
60
61         internal EventPipeConfiguration(
62             string outputFile,
63             uint circularBufferSizeInMB)
64         {
65             if(string.IsNullOrEmpty(outputFile))
66             {
67                 throw new ArgumentNullException(nameof(outputFile));
68             }
69             if(circularBufferSizeInMB == 0)
70             {
71                 throw new ArgumentOutOfRangeException(nameof(circularBufferSizeInMB));
72             }
73             m_outputFile = outputFile;
74             m_circularBufferSizeInMB = circularBufferSizeInMB;
75             m_providers = new List<EventPipeProviderConfiguration>();
76         }
77
78         internal string OutputFile
79         {
80             get { return m_outputFile; }
81         }
82
83         internal uint CircularBufferSizeInMB
84         {
85             get { return m_circularBufferSizeInMB; }
86         }
87
88         internal EventPipeProviderConfiguration[] Providers
89         {
90             get { return m_providers.ToArray(); }
91         }
92
93         internal long ProfilerSamplingRateInNanoseconds
94         {
95             // 100 nanoseconds == 1 tick.
96             get { return m_minTimeBetweenSamples.Ticks * 100; }
97         }
98
99         internal void EnableProvider(string providerName, ulong keywords, uint loggingLevel)
100         {
101             m_providers.Add(new EventPipeProviderConfiguration(
102                 providerName,
103                 keywords,
104                 loggingLevel));
105         }
106
107         internal void SetProfilerSamplingRate(TimeSpan minTimeBetweenSamples)
108         {
109             if(minTimeBetweenSamples.Ticks <= 0)
110             {
111                 throw new ArgumentOutOfRangeException(nameof(minTimeBetweenSamples));
112             }
113
114             m_minTimeBetweenSamples = minTimeBetweenSamples;
115         }
116     }
117
118     internal static class EventPipe
119     {
120         internal static void Enable(EventPipeConfiguration configuration)
121         {
122             if(configuration == null)
123             {
124                 throw new ArgumentNullException(nameof(configuration));
125             }
126
127             if(configuration.Providers == null)
128             {
129                 throw new ArgumentNullException(nameof(configuration.Providers));
130             }
131
132             EventPipeProviderConfiguration[] providers = configuration.Providers;
133
134             EventPipeInternal.Enable(
135                 configuration.OutputFile,
136                 configuration.CircularBufferSizeInMB,
137                 configuration.ProfilerSamplingRateInNanoseconds,
138                 providers,
139                 providers.Length);
140         }
141
142         internal static void Disable()
143         {
144             EventPipeInternal.Disable();
145         }
146     }
147
148     internal static class EventPipeInternal
149     {
150         //
151         // These PInvokes are used by the configuration APIs to interact with EventPipe.
152         //
153         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
154         internal static extern void Enable(string outputFile, uint circularBufferSizeInMB, long profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration[] providers, int numProviders);
155
156         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
157         internal static extern void Disable();
158
159         //
160         // These PInvokes are used by EventSource to interact with the EventPipe.
161         //
162         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
163         internal static extern IntPtr CreateProvider(string providerName, UnsafeNativeMethods.ManifestEtw.EtwEnableCallback callbackFunc);
164
165         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
166         internal static extern unsafe IntPtr DefineEvent(IntPtr provHandle, uint eventID, long keywords, uint eventVersion, uint level, void *pMetadata, uint metadataLength);
167
168         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
169         internal static extern void DeleteProvider(IntPtr provHandle);
170
171         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
172         internal static extern int EventActivityIdControl(uint controlCode, ref Guid activityId);
173
174         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
175         internal static extern unsafe void WriteEvent(IntPtr eventHandle, uint eventID, void* pData, uint length, Guid* activityId, Guid* relatedActivityId);
176
177         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
178         internal static extern unsafe void WriteEventData(IntPtr eventHandle, uint eventID, EventProvider.EventData* pEventData, uint dataCount, Guid* activityId, Guid* relatedActivityId);
179     }
180 }