Kaynağa Gözat

Move FrameworkEventSource to shared partition (dotnet/coreclr#22507)

* Move FrameworkEventSource to shared partition

and remove unused code

* Remove more unused code

* Remove CA8001 suppress message

Signed-off-by: dotnet-bot <[email protected]>
Marek Safar 6 yıl önce
ebeveyn
işleme
dbac2e4ffc

+ 1 - 0
netcore/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems

@@ -869,6 +869,7 @@
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventProvider.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventSource.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventSourceException.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\FrameworkEventSource.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\IEventProvider.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\StubEnvironment.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\Winmeta.cs" />

+ 162 - 0
netcore/System.Private.CoreLib/shared/System/Diagnostics/Tracing/FrameworkEventSource.cs

@@ -0,0 +1,162 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Internal.Runtime.CompilerServices;
+
+namespace System.Diagnostics.Tracing
+{
+    [EventSource(Guid = "8E9F5090-2D75-4d03-8A81-E5AFBF85DAF1", Name = "System.Diagnostics.Eventing.FrameworkEventSource")]
+    internal sealed class FrameworkEventSource : EventSource
+    {
+        public static readonly FrameworkEventSource Log = new FrameworkEventSource();
+
+        // Keyword definitions.  These represent logical groups of events that can be turned on and off independently
+        // Often each task has a keyword, but where tasks are determined by subsystem, keywords are determined by
+        // usefulness to end users to filter.  Generally users don't mind extra events if they are not high volume
+        // so grouping low volume events together in a single keywords is OK (users can post-filter by task if desired)
+        public static class Keywords
+        {
+            public const EventKeywords ThreadPool = (EventKeywords)0x0002;
+            public const EventKeywords ThreadTransfer = (EventKeywords)0x0010;
+        }
+
+        /// <summary>ETW tasks that have start/stop events.</summary>
+        public static class Tasks // this name is important for EventSource
+        {
+            /// <summary>Send / Receive - begin transfer/end transfer</summary>
+            public const EventTask ThreadTransfer = (EventTask)3;
+        }
+
+        // The FrameworkEventSource GUID is {8E9F5090-2D75-4d03-8A81-E5AFBF85DAF1}
+        private FrameworkEventSource() : base(new Guid(0x8e9f5090, 0x2d75, 0x4d03, 0x8a, 0x81, 0xe5, 0xaf, 0xbf, 0x85, 0xda, 0xf1), "System.Diagnostics.Eventing.FrameworkEventSource") { }
+
+        // optimized for common signatures (used by the ThreadTransferSend/Receive events)
+        [NonEvent]
+        private unsafe void WriteEvent(int eventId, long arg1, int arg2, string arg3, bool arg4, int arg5, int arg6)
+        {
+            if (IsEnabled())
+            {
+                if (arg3 == null) arg3 = "";
+                fixed (char* string3Bytes = arg3)
+                {
+                    EventSource.EventData* descrs = stackalloc EventSource.EventData[6];
+                    descrs[0].DataPointer = (IntPtr)(&arg1);
+                    descrs[0].Size = 8;
+                    descrs[0].Reserved = 0;
+                    descrs[1].DataPointer = (IntPtr)(&arg2);
+                    descrs[1].Size = 4;
+                    descrs[1].Reserved = 0;
+                    descrs[2].DataPointer = (IntPtr)string3Bytes;
+                    descrs[2].Size = ((arg3.Length + 1) * 2);
+                    descrs[2].Reserved = 0;
+                    descrs[3].DataPointer = (IntPtr)(&arg4);
+                    descrs[3].Size = 4;
+                    descrs[3].Reserved = 0;
+                    descrs[4].DataPointer = (IntPtr)(&arg5);
+                    descrs[4].Size = 4;
+                    descrs[4].Reserved = 0;
+                    descrs[5].DataPointer = (IntPtr)(&arg6);
+                    descrs[5].Size = 4;
+                    descrs[5].Reserved = 0;
+                    WriteEventCore(eventId, 6, descrs);
+                }
+            }
+        }
+
+        // optimized for common signatures (used by the ThreadTransferSend/Receive events)
+        [NonEvent]
+        private unsafe void WriteEvent(int eventId, long arg1, int arg2, string arg3)
+        {
+            if (IsEnabled())
+            {
+                if (arg3 == null) arg3 = "";
+                fixed (char* string3Bytes = arg3)
+                {
+                    EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
+                    descrs[0].DataPointer = (IntPtr)(&arg1);
+                    descrs[0].Size = 8;
+                    descrs[0].Reserved = 0;
+                    descrs[1].DataPointer = (IntPtr)(&arg2);
+                    descrs[1].Size = 4;
+                    descrs[1].Reserved = 0;
+                    descrs[2].DataPointer = (IntPtr)string3Bytes;
+                    descrs[2].Size = ((arg3.Length + 1) * 2);
+                    descrs[2].Reserved = 0;
+                    WriteEventCore(eventId, 3, descrs);
+                }
+            }
+        }
+
+        [Event(30, Level = EventLevel.Verbose, Keywords = Keywords.ThreadPool | Keywords.ThreadTransfer)]
+        public void ThreadPoolEnqueueWork(long workID)
+        {
+            WriteEvent(30, workID);
+        }
+
+        [NonEvent]
+        public unsafe void ThreadPoolEnqueueWorkObject(object workID)
+        {
+            // convert the Object Id to a long
+            ThreadPoolEnqueueWork((long)*((void**)Unsafe.AsPointer(ref workID)));
+        }
+
+        [Event(31, Level = EventLevel.Verbose, Keywords = Keywords.ThreadPool | Keywords.ThreadTransfer)]
+        public void ThreadPoolDequeueWork(long workID)
+        {
+            WriteEvent(31, workID);
+        }
+
+        [NonEvent]
+        public unsafe void ThreadPoolDequeueWorkObject(object workID)
+        {
+            // convert the Object Id to a long
+            ThreadPoolDequeueWork((long)*((void**)Unsafe.AsPointer(ref workID)));
+        }
+
+        // id -   represents a correlation ID that allows correlation of two activities, one stamped by 
+        //        ThreadTransferSend, the other by ThreadTransferReceive
+        // kind - identifies the transfer: values below 64 are reserved for the runtime. Currently used values:
+        //        1 - managed Timers ("roaming" ID)
+        //        2 - managed async IO operations (FileStream, PipeStream, a.o.)
+        //        3 - WinRT dispatch operations
+        // info - any additional information user code might consider interesting
+        // intInfo1/2 - any additional integer information user code might consider interesting
+        [Event(150, Level = EventLevel.Informational, Keywords = Keywords.ThreadTransfer, Task = Tasks.ThreadTransfer, Opcode = EventOpcode.Send)]
+        public void ThreadTransferSend(long id, int kind, string info, bool multiDequeues, int intInfo1, int intInfo2)
+        {
+            WriteEvent(150, id, kind, info, multiDequeues, intInfo1, intInfo2);
+        }
+
+        // id - is a managed object. it gets translated to the object's address. ETW listeners must
+        //      keep track of GC movements in order to correlate the value passed to XyzSend with the
+        //      (possibly changed) value passed to XyzReceive
+        [NonEvent]
+        public unsafe void ThreadTransferSendObj(object id, int kind, string info, bool multiDequeues, int intInfo1, int intInfo2)
+        {
+            ThreadTransferSend((long)*((void**)Unsafe.AsPointer(ref id)), kind, info, multiDequeues, intInfo1, intInfo2);
+        }
+
+        // id -   represents a correlation ID that allows correlation of two activities, one stamped by 
+        //        ThreadTransferSend, the other by ThreadTransferReceive
+        // kind - identifies the transfer: values below 64 are reserved for the runtime. Currently used values:
+        //        1 - managed Timers ("roaming" ID)
+        //        2 - managed async IO operations (FileStream, PipeStream, a.o.)
+        //        3 - WinRT dispatch operations
+        // info - any additional information user code might consider interesting
+        [Event(151, Level = EventLevel.Informational, Keywords = Keywords.ThreadTransfer, Task = Tasks.ThreadTransfer, Opcode = EventOpcode.Receive)]
+        public void ThreadTransferReceive(long id, int kind, string info)
+        {
+            WriteEvent(151, id, kind, info);
+        }
+        // id - is a managed object. it gets translated to the object's address. ETW listeners must
+        //      keep track of GC movements in order to correlate the value passed to XyzSend with the
+        //      (possibly changed) value passed to XyzReceive
+        [NonEvent]
+        public unsafe void ThreadTransferReceiveObj(object id, int kind, string info)
+        {
+            ThreadTransferReceive((long)*((void**)Unsafe.AsPointer(ref id)), kind, info);
+        }
+    }
+}
+

+ 2 - 2
netcore/System.Private.CoreLib/shared/System/Threading/Timer.cs

@@ -477,7 +477,7 @@ namespace System.Threading
                         // Don't emit this event during EventPipeController.  This avoids initializing FrameworkEventSource during start-up which is expensive relative to the rest of start-up.
                         !EventPipeController.Initializing &&
 #endif
-                        FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.ThreadTransfer))
+                        FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.ThreadTransfer))
                         FrameworkEventSource.Log.ThreadTransferSendObj(this, 1, string.Empty, true, (int)dueTime, (int)period);
 
                     success = _associatedTimerQueue.UpdateTimer(this, dueTime, period);
@@ -631,7 +631,7 @@ namespace System.Threading
 
         internal void CallCallback(bool isThreadPool)
         {
-            if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.ThreadTransfer))
+            if (FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.ThreadTransfer))
                 FrameworkEventSource.Log.ThreadTransferReceiveObj(this, 1, string.Empty);
 
             // Call directly if EC flow is suppressed