| File: src\runtime\src\libraries\System.Private.CoreLib\src\System\Runtime\CompilerServices\AsyncProfilerEventSource.cs | Web Access |
| Project: System.Private.CoreLib.csproj (System.Private.CoreLib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Tracing; namespace System.Runtime.CompilerServices { /// <summary>Provides an event source for tracing async execution.</summary> [EventSource(Name = "System.Runtime.CompilerServices.AsyncProfilerEventSource")] internal sealed partial class AsyncProfilerEventSource : EventSource { private const string EventSourceSuppressMessage = "Parameters to this method are primitive and are trimmer safe"; public static readonly AsyncProfilerEventSource Log = new AsyncProfilerEventSource(); public static class Keywords // this name is important for EventSource { public const EventKeywords CreateRuntimeAsyncContext = (EventKeywords)0x1; public const EventKeywords ResumeRuntimeAsyncContext = (EventKeywords)0x2; public const EventKeywords SuspendRuntimeAsyncContext = (EventKeywords)0x4; public const EventKeywords CompleteRuntimeAsyncContext = (EventKeywords)0x8; public const EventKeywords UnwindRuntimeAsyncException = (EventKeywords)0x10; public const EventKeywords CreateRuntimeAsyncCallstack = (EventKeywords)0x20; public const EventKeywords ResumeRuntimeAsyncCallstack = (EventKeywords)0x40; public const EventKeywords SuspendRuntimeAsyncCallstack = (EventKeywords)0x80; public const EventKeywords ResumeRuntimeAsyncMethod = (EventKeywords)0x100; public const EventKeywords CompleteRuntimeAsyncMethod = (EventKeywords)0x200; public const EventKeywords CreateStateMachineAsyncContext = (EventKeywords)0x400; public const EventKeywords ResumeStateMachineAsyncContext = (EventKeywords)0x800; public const EventKeywords SuspendStateMachineAsyncContext = (EventKeywords)0x1000; public const EventKeywords CompleteStateMachineAsyncContext = (EventKeywords)0x2000; public const EventKeywords UnwindStateMachineAsyncException = (EventKeywords)0x4000; public const EventKeywords ResumeStateMachineAsyncCallstack = (EventKeywords)0x8000; public const EventKeywords ResumeStateMachineAsyncMethod = (EventKeywords)0x10000; public const EventKeywords CompleteStateMachineAsyncMethod = (EventKeywords)0x20000; } public const EventKeywords AsyncEventKeywords = Keywords.CreateRuntimeAsyncContext | Keywords.ResumeRuntimeAsyncContext | Keywords.SuspendRuntimeAsyncContext | Keywords.CompleteRuntimeAsyncContext | Keywords.CreateRuntimeAsyncCallstack | Keywords.ResumeRuntimeAsyncCallstack | Keywords.SuspendRuntimeAsyncCallstack | Keywords.UnwindRuntimeAsyncException | Keywords.ResumeRuntimeAsyncMethod | Keywords.CompleteRuntimeAsyncMethod | Keywords.CreateStateMachineAsyncContext | Keywords.ResumeStateMachineAsyncContext | Keywords.SuspendStateMachineAsyncContext | Keywords.CompleteStateMachineAsyncContext | Keywords.UnwindStateMachineAsyncException | Keywords.ResumeStateMachineAsyncCallstack | Keywords.ResumeStateMachineAsyncMethod | Keywords.CompleteStateMachineAsyncMethod; public const int FlushCommand = 1; //----------------------- Event IDs (must be unique) ----------------------- public const int ASYNC_EVENTS_ID = 1; //----------------------------------------------------------------------------------- // // Events // [Event( ASYNC_EVENTS_ID, Version = 1, Opcode = EventOpcode.Info, Level = EventLevel.Informational, Keywords = AsyncEventKeywords, Message = "")] public void AsyncEvents(byte[] buffer) { AsyncEvents(buffer.AsSpan()); } [NonEvent] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern", Justification = EventSourceSuppressMessage)] public void AsyncEvents(ReadOnlySpan<byte> buffer) { unsafe { fixed (byte* pBuffer = buffer) { int length = buffer.Length; EventData* eventPayload = stackalloc EventData[2]; eventPayload[0].Size = sizeof(int); eventPayload[0].DataPointer = ((IntPtr)(&length)); eventPayload[0].Reserved = 0; eventPayload[1].Size = sizeof(byte) * length; eventPayload[1].DataPointer = length != 0 ? ((IntPtr)pBuffer) : ((IntPtr)(&length)); eventPayload[1].Reserved = 0; WriteEventCore(ASYNC_EVENTS_ID, 2, eventPayload); } } } /// <summary> /// Get callbacks when the ETW sends us commands /// </summary> protected override void OnEventCommand(EventCommandEventArgs command) { if (command.Command == (EventCommand)FlushCommand || command.Command == EventCommand.SendManifest) { AsyncProfiler.Config.CaptureState(); return; } EventKeywords keywords = m_matchAnyKeyword; // A keyword mask of 0 from an enable means "all keywords", so substitute the full async set. // On disable EventSource also resets m_matchAnyKeyword to 0 (with m_level 0 == LogAlways) before // this callback, so gate the substitution on IsEnabled() to avoid re-enabling instrumentation // while the source is being disabled. if (keywords == 0 && IsEnabled()) { keywords = AsyncEventKeywords; } AsyncProfiler.Config.Update(m_level, keywords); } } }