355 lines
11 KiB
C#
355 lines
11 KiB
C#
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
//
|
|||
|
// 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;
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ArrayType arrayDescriptor;
|
|||
|
<EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> fixed (UIntPtr * ptr = StackTrace) {
|
|||
|
<EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> arrayDescriptor.ItemSize = (ushort)sizeof(UIntPtr);
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> arrayDescriptor.Length = (ushort)(actualStacks * arrayDescriptor.ItemSize);
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> arrayDescriptor.Type = DataType.__UIntPtr;
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> arrayDescriptor.Buffer = (void *)ptr;
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> LogEntry(ControlFlags,
|
|||
|
eventProfileType,
|
|||
|
(byte *)&profilerEvent,
|
|||
|
sizeof(ProfilerEvent),
|
|||
|
1,
|
|||
|
&arrayDescriptor);
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> public unsafe struct ProfilerEvent{
|
|||
|
<EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> public ushort StackTrace;
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> };
|
|||
|
|
|||
|
UIntPtr eventProfileType;
|
|||
|
const uint Profile_Control_flag = 0x10000;
|
|||
|
|
|||
|
|
|||
|
public override bool Register() {
|
|||
|
|
|||
|
if (!base.Register()) {
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> if (HostController.RegisterEvent("ProfileEvent",
|
|||
|
"Profile event.",
|
|||
|
ref eventProfileType)) {
|
|||
|
<EFBFBD>
|
|||
|
<EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> HostController.RegisterEventField(eventProfileType,
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "StackTrace",
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0,
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DataType.__arrayType | DataType.__UIntPtr);
|
|||
|
<EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> } else {
|
|||
|
<EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // The event might have been registered already
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Check whether we foundit already in the table or not
|
|||
|
<EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> if (eventProfileType == 0) {
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> return false;
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> }
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> }
|
|||
|
<EFBFBD> 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];
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|