File: src\libraries\System.Private.CoreLib\src\System\Diagnostics\Tracing\EventPipe.cs
Web Access
Project: src\src\coreclr\System.Private.CoreLib\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.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
 
namespace System.Diagnostics.Tracing
{
    [StructLayout(LayoutKind.Sequential)]
    internal struct EventPipeEventInstanceData
    {
        internal IntPtr ProviderID;
        internal uint EventID;
        internal uint ThreadID;
        internal long TimeStamp;
        internal Guid ActivityId;
        internal Guid ChildActivityId;
        internal IntPtr Payload;
        internal uint PayloadLength;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    internal struct EventPipeSessionInfo
    {
        internal long StartTimeAsUTCFileTime;
        internal long StartTimeStamp;
        internal long TimeStampFrequency;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    internal readonly struct EventPipeProviderConfiguration
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        private readonly string m_providerName;
        private readonly ulong m_keywords;
        private readonly uint m_loggingLevel;
 
        [MarshalAs(UnmanagedType.LPWStr)]
        private readonly string? m_filterData;
 
        internal EventPipeProviderConfiguration(
            string providerName,
            ulong keywords,
            uint loggingLevel,
            string? filterData)
        {
            ArgumentException.ThrowIfNullOrEmpty(providerName);
            ArgumentOutOfRangeException.ThrowIfGreaterThan(loggingLevel, 5u); // 5 == Verbose, the highest value in EventPipeLoggingLevel.
            m_providerName = providerName;
            m_keywords = keywords;
            m_loggingLevel = loggingLevel;
            m_filterData = filterData;
        }
 
        internal string ProviderName
        {
            get { return m_providerName; }
        }
 
        internal ulong Keywords
        {
            get { return m_keywords; }
        }
 
        internal uint LoggingLevel
        {
            get { return m_loggingLevel; }
        }
 
        internal string? FilterData => m_filterData;
    }
 
    internal enum EventPipeSerializationFormat
    {
        NetPerf,
        NetTrace
    }
 
    internal sealed class EventPipeWaitHandle : WaitHandle
    {
    }
 
    internal static partial class EventPipeInternal
    {
#if FEATURE_PERFTRACING
        private unsafe struct EventPipeProviderConfigurationNative
        {
            private char* m_pProviderName;
            private ulong m_keywords;
            private uint m_loggingLevel;
            private char* m_pFilterData;
 
            internal static void MarshalToNative(EventPipeProviderConfiguration managed, ref EventPipeProviderConfigurationNative native)
            {
                native.m_pProviderName = (char*)Marshal.StringToCoTaskMemUni(managed.ProviderName);
                native.m_keywords = managed.Keywords;
                native.m_loggingLevel = managed.LoggingLevel;
                native.m_pFilterData = (char*)Marshal.StringToCoTaskMemUni(managed.FilterData);
            }
 
            internal void Release()
            {
                if (m_pProviderName != null)
                {
                    Marshal.FreeCoTaskMem((IntPtr)m_pProviderName);
                }
                if (m_pFilterData != null)
                {
                    Marshal.FreeCoTaskMem((IntPtr)m_pFilterData);
                }
            }
        }
 
        internal static unsafe ulong Enable(
            string? outputFile,
            EventPipeSerializationFormat format,
            uint circularBufferSizeInMB,
            EventPipeProviderConfiguration[] providers)
        {
            Span<EventPipeProviderConfigurationNative> providersNative = new Span<EventPipeProviderConfigurationNative>((void*)Marshal.AllocCoTaskMem(sizeof(EventPipeProviderConfigurationNative) * providers.Length), providers.Length);
            providersNative.Clear();
 
            try
            {
                for (int i = 0; i < providers.Length; i++)
                {
                    EventPipeProviderConfigurationNative.MarshalToNative(providers[i], ref providersNative[i]);
                }
 
                fixed (char* outputFilePath = outputFile)
                fixed (EventPipeProviderConfigurationNative* providersNativePointer = providersNative)
                {
                    return Enable(outputFilePath, format, circularBufferSizeInMB, providersNativePointer, (uint)providersNative.Length);
                }
            }
            finally
            {
                for (int i = 0; i < providers.Length; i++)
                {
                    providersNative[i].Release();
                }
 
                fixed (EventPipeProviderConfigurationNative* providersNativePointer = providersNative)
                {
                    Marshal.FreeCoTaskMem((IntPtr)providersNativePointer);
                }
            }
        }
#else
#pragma warning disable IDE0060
        private unsafe struct EventPipeProviderConfigurationNative
        {
        }
 
        internal static unsafe ulong Enable(
            string? outputFile,
            EventPipeSerializationFormat format,
            uint circularBufferSizeInMB,
            EventPipeProviderConfiguration[] providers)
        {
            return 0;
        }
#pragma warning restore IDE0060
#endif //FEATURE_PERFTRACING
    }
}