private void OnGCAllocationTick(GCAllocationTickTraceData data) { TraceThread thread = data.Thread(); Debug.Assert(thread != null); if (null == thread) { return; } // Attempt to charge the allocation to a request. ScenarioThreadState scenarioThreadState = m_Configuration.ScenarioThreadState[(int)thread.ThreadIndex]; CallStackIndex traceLogCallStackIndex = data.CallStackIndex(); StackSourceCallStackIndex callStackIndex = scenarioThreadState.GetCallStackIndex(m_OutputStackSource, thread, data); // Add the thread. StackSourceFrameIndex threadFrameIndex = m_OutputStackSource.Interner.FrameIntern(thread.VerboseThreadName); callStackIndex = m_OutputStackSource.Interner.CallStackIntern(threadFrameIndex, callStackIndex); // Get the allocation call stack index. callStackIndex = m_OutputStackSource.GetCallStack(traceLogCallStackIndex, callStackIndex, null); // Add the type. string typeName = data.TypeName; if (typeName.Length > 0) { StackSourceFrameIndex nodeIndex = m_OutputStackSource.Interner.FrameIntern("Type " + data.TypeName); callStackIndex = m_OutputStackSource.Interner.CallStackIntern(nodeIndex, callStackIndex); } // Add a notification for large objects. if (data.AllocationKind == GCAllocationKind.Large) { StackSourceFrameIndex nodeIndex = m_OutputStackSource.Interner.FrameIntern("LargeObject"); callStackIndex = m_OutputStackSource.Interner.CallStackIntern(nodeIndex, callStackIndex); } // Set the time. m_Sample.TimeRelativeMSec = data.TimeStampRelativeMSec; // Set the metric. bool seenBadAllocTick = false; m_Sample.Metric = data.GetAllocAmount(ref seenBadAllocTick); // Set the stack index. m_Sample.StackIndex = callStackIndex; // Add the sample. m_OutputStackSource.AddSample(m_Sample); }
/// <summary> /// Mark the thread as unblocked. /// </summary> public void LogBlockingStop( ComputingResourceStateMachine stateMachine, TraceThread thread, TraceEvent data) { if ((null == stateMachine) || (null == thread) || (null == data)) { return; } // Only add a sample if the thread was blocked. if (ThreadBlocked) { StackSourceSample sample = stateMachine.Sample; MutableTraceEventStackSource stackSource = stateMachine.StackSource; // Set the time and metric. sample.TimeRelativeMSec = this.BlockTimeStartRelativeMSec; sample.Metric = (float)(data.TimeStampRelativeMSec - this.BlockTimeStartRelativeMSec); /* Generate the stack trace. */ CallStackIndex traceLogCallStackIndex = data.CallStackIndex(); ScenarioThreadState scenarioThreadState = stateMachine.Configuration.ScenarioThreadState[ThreadIndex]; StackSourceCallStackIndex callStackIndex = scenarioThreadState.GetCallStackIndex(stateMachine.StackSource, thread, data); // Add the thread. StackSourceFrameIndex threadFrameIndex = stackSource.Interner.FrameIntern(thread.VerboseThreadName); callStackIndex = stackSource.Interner.CallStackIntern(threadFrameIndex, callStackIndex); // Add the full call stack. callStackIndex = stackSource.GetCallStack(traceLogCallStackIndex, callStackIndex, null); // Add Pseud-frames representing the kind of resource. StackSourceFrameIndex frameIndex = stackSource.Interner.FrameIntern("BLOCKED TIME"); callStackIndex = stackSource.Interner.CallStackIntern(frameIndex, callStackIndex); // Add the call stack to the sample. sample.StackIndex = callStackIndex; // Add the sample. stackSource.AddSample(sample); // Mark the thread as executing. BlockTimeStartRelativeMSec = -1; } }
/// <summary> /// Log a CPU sample on this thread. /// </summary> public void LogCPUSample( ComputingResourceStateMachine stateMachine, TraceThread thread, TraceEvent data) { if ((null == stateMachine) || (null == thread) || (null == data)) { return; } StackSourceSample sample = stateMachine.Sample; sample.Metric = 1; sample.TimeRelativeMSec = data.TimeStampRelativeMSec; MutableTraceEventStackSource stackSource = stateMachine.StackSource; // Attempt to charge the CPU to a request. CallStackIndex traceLogCallStackIndex = data.CallStackIndex(); ScenarioThreadState scenarioThreadState = stateMachine.Configuration.ScenarioThreadState[ThreadIndex]; StackSourceCallStackIndex callStackIndex = scenarioThreadState.GetCallStackIndex(stackSource, thread, data); // Add the thread. StackSourceFrameIndex threadFrameIndex = stackSource.Interner.FrameIntern(thread.VerboseThreadName); callStackIndex = stackSource.Interner.CallStackIntern(threadFrameIndex, callStackIndex); // Rest of the stack. // NOTE: Do not pass a call stack map into this method, as it will skew results. callStackIndex = stackSource.GetCallStack(traceLogCallStackIndex, callStackIndex, null); // Add the CPU frame. StackSourceFrameIndex cpuFrameIndex = stackSource.Interner.FrameIntern("CPU"); callStackIndex = stackSource.Interner.CallStackIntern(cpuFrameIndex, callStackIndex); // Add the sample. sample.StackIndex = callStackIndex; stackSource.AddSample(sample); }