//////////////////////////////////////////////////////////////////////////////// // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: EvProcessor.cs // // using System; using System.Threading; using System.Runtime.CompilerServices; using Microsoft.Singularity; using Microsoft.Singularity.V1.Services; using Microsoft.Singularity.Eventing; using Microsoft.Singularity.Isal; using System.Collections; namespace Microsoft.Singularity.Eventing { [CLSCompliant(false)] public class ProcessorLogger : EventSource { private const uint DefaultProcessorLogSize = 0x10000; public static ProcessorLogger Create(string sourceName) { EventingStorage storage = EventingStorage.CreateLocalStorage(QualityOfService.RecyclableEvents, DefaultProcessorLogSize); if (storage == null) { return null; } ProcessorLogger Logger = new ProcessorLogger(sourceName, storage, CAPTURE_STACK_TRACE | ENABLE_ALL_MASK); if (Logger != null) { Logger.Register(); } return Logger; } //[EventType=Interrupt] [NoHeapAllocation] public bool Log(int Vector) { // !!!!! this line must be entered to define a schema // ???? GENCODE from here if ((ControlFlags & Interrupt_Control_flag) != 0) { unsafe { InterruptEvent Event; Event.Vector = Vector; return (LogEntry(ControlFlags, eventTypeInterrupt, (byte *)&Event, sizeof(InterruptEvent)) != 0); } } return false; } public unsafe struct InterruptEvent { public int Vector; }; UIntPtr eventTypeInterrupt; const uint Interrupt_Control_flag = 0x10000; public override bool Register() { if (!base.Register()) { return false; } if (HostController.RegisterEvent("Interrupt", "Interrupt: Vector={0}", ref eventTypeInterrupt)) { HostController.RegisterEventField(eventTypeInterrupt, "Vector", 0, DataType.__int); } else { // The event might have been registered already // Check whether we foundit already in the table or not if (eventTypeInterrupt == 0) { return false; } } return true; } ProcessorLogger(string sourceName, EventingStorage storage, uint controlFlags) :base(sourceName, storage, controlFlags) {} } [CLSCompliant(false)] public class ProcessorCounter : ActiveSource{ //[ActiveCounter] void InterruptCounter(int Hits){} // ???? CODEGEN from here //[ActiveCounter=InterruptCounter, ArraySize=256] public struct tmpInterruptCounter{ public int Hits; } internal tmpInterruptCounter[] Buffer; public static ProcessorCounter Create(string sourceName, int size) { ProcessorCounter Logger = new ProcessorCounter(sourceName, size, ENABLE_ALL_MASK); if (Logger != null) { Logger.Register(); } return Logger; } public override bool Register() { Buffer = new tmpInterruptCounter[Count]; if (Buffer == null) { return false; } if (HostController.RegisterEvent("InterruptCounter", "InterruptCounter: Hits={0}", ref EventTypeHandle)) { HostController.RegisterEventField(EventTypeHandle, "Hits", 0, DataType.__int); } else { // The event might have been registered already // Check whether we foundit already in the table or not if (EventTypeHandle == 0) { return false; } } unsafe { fixed (void * ptr = &Buffer[0]) { DebugBufferAddress = (UIntPtr)ptr; } } // After all internal fields are setup, we can go ahead and register with the controller if (!base.Register()) { return false; } return true; } public tmpInterruptCounter this[int index] { get { return Buffer[index]; } } public override unsafe bool GetActiveEntry(int index, UIntPtr * type, byte * buffer, UInt16 bufferSize ) { if (!base.GetActiveEntry(index, type, buffer, bufferSize)) { return false; } *(tmpInterruptCounter *)buffer = Buffer[index]; return true; } ProcessorCounter(string sourceName, int size, uint controlFlags) :base(sourceName, size, controlFlags) { unsafe { EntrySize = (ushort)sizeof(tmpInterruptCounter); } } } [CLSCompliant(false)] public class SamplingProfiler : EventSource { public static SamplingProfiler Create(string sourceName, int maxStackSize, uint storageSize) { EventingStorage storage = EventingStorage.CreateLocalStorage(QualityOfService.RecyclableEvents, storageSize); if (storage == null) { return null; } SamplingProfiler Logger = new SamplingProfiler(sourceName, maxStackSize, storage, ENABLE_ALL_MASK); if (Logger != null) { Logger.Register(); } return Logger; } [NoHeapAllocation] public void LogStackTrace(UIntPtr eip, UIntPtr ebp) { if ((ControlFlags & Profile_Control_flag) != 0) { int actualStacks = 0; // // Capture the stack trace from the context // while (actualStacks < MaxStackSize) { if (eip == 0) { break; } StackTrace[actualStacks++] = eip; if (ebp == 0) { break; } eip = Isa.GetFrameReturnAddress(ebp); ebp = Isa.GetFrameCallerFrame(ebp); } // // Setup the log structure and log the event // unsafe { ProfilerEvent profilerEvent; profilerEvent.StackTrace = 1;                     ArrayType arrayDescriptor;                       fixed (UIntPtr * ptr = StackTrace) {                           arrayDescriptor.ItemSize = (ushort)sizeof(UIntPtr);                         arrayDescriptor.Length = (ushort)(actualStacks * arrayDescriptor.ItemSize);                         arrayDescriptor.Type = DataType.__UIntPtr;                         arrayDescriptor.Buffer = (void *)ptr;                                                     LogEntry(ControlFlags, eventProfileType, (byte *)&profilerEvent, sizeof(ProfilerEvent), 1, &arrayDescriptor);                     } } } }         public unsafe struct ProfilerEvent{               public ushort StackTrace;         }; UIntPtr eventProfileType; const uint Profile_Control_flag = 0x10000; public override bool Register() { if (!base.Register()) { return false; }             if (HostController.RegisterEvent("ProfileEvent", "Profile event.", ref eventProfileType)) {                     HostController.RegisterEventField(eventProfileType,                                                   "StackTrace",                                                   0,                                                   DataType.__arrayType | DataType.__UIntPtr);               } else {                   // The event might have been registered already                 // Check whether we foundit already in the table or not                   if (eventProfileType == 0) {                     return false;                 }             }   return true; } UIntPtr [] StackTrace; int MaxStackSize; SamplingProfiler (string sourceName, int maxStackSize, EventingStorage storage, uint controlFlags) :base(sourceName, storage, controlFlags) { MaxStackSize = maxStackSize; StackTrace = new UIntPtr[maxStackSize]; } } }