private void DoMetrics(LinuxEvent linuxEvent) { KeyValuePair <LinuxThreadState, LinuxEvent> sampleInfo; if (EndingStates.TryGetValue(linuxEvent.ThreadID, out sampleInfo)) { linuxEvent.Period = linuxEvent.TimeMSec - sampleInfo.Value.TimeMSec; } // This is check for completed scheduler events, ones that start with prev_comm and have // corresponding next_comm. if (linuxEvent.Kind == EventKind.Scheduler) { SchedulerEvent schedEvent = (SchedulerEvent)linuxEvent; if (EndingStates.ContainsKey(schedEvent.Switch.PreviousThreadID) && EndingStates[schedEvent.Switch.PreviousThreadID].Key == LinuxThreadState.CPU_TIME) // Blocking { sampleInfo = EndingStates[schedEvent.Switch.PreviousThreadID]; EndingStates[schedEvent.Switch.PreviousThreadID] = new KeyValuePair <LinuxThreadState, LinuxEvent>(LinuxThreadState.BLOCKED_TIME, linuxEvent); linuxEvent.Period = linuxEvent.TimeMSec - sampleInfo.Value.TimeMSec; } if (EndingStates.TryGetValue(schedEvent.Switch.NextThreadID, out sampleInfo) && sampleInfo.Key == LinuxThreadState.BLOCKED_TIME) // Unblocking { EndingStates[schedEvent.Switch.NextThreadID] = new KeyValuePair <LinuxThreadState, LinuxEvent>(LinuxThreadState.CPU_TIME, linuxEvent); // sampleInfo.Value.Period = linuxEvent.Time - sampleInfo.Value.Time; AddThreadPeriod(linuxEvent.ThreadID, sampleInfo.Value.TimeMSec, linuxEvent.TimeMSec); } } else if (linuxEvent.Kind == EventKind.Cpu) { int threadid; if (EndingCpuUsage.TryGetValue(linuxEvent.CpuNumber, out threadid) && threadid != linuxEvent.ThreadID) // Unblocking { if (EndingStates.TryGetValue(threadid, out sampleInfo)) { EndingStates[threadid] = new KeyValuePair <LinuxThreadState, LinuxEvent>(LinuxThreadState.CPU_TIME, linuxEvent); sampleInfo.Value.Period = linuxEvent.TimeMSec - sampleInfo.Value.TimeMSec; AddThreadPeriod(linuxEvent.ThreadID, sampleInfo.Value.TimeMSec, linuxEvent.TimeMSec); } } } EndingCpuUsage[linuxEvent.CpuNumber] = linuxEvent.ThreadID; }
/// <summary> /// Given a Linux event gotten from the trace, make its corresponding sample for the stack source. /// </summary> public StackSourceSample CreateSampleFor(LinuxEvent linuxEvent, BlockedTimeAnalyzer blockedTimeAnalyzer) { IEnumerable <Frame> frames = linuxEvent.CallerStacks; StackSourceCallStackIndex stackIndex = currentStackIndex; var sample = new StackSourceSample(this); sample.TimeRelativeMSec = linuxEvent.TimeMSec; sample.Metric = 1; stackIndex = InternFrames(frames.GetEnumerator(), stackIndex, linuxEvent.ProcessID, linuxEvent.ThreadID, blockedTimeAnalyzer); sample.StackIndex = stackIndex; return(sample); }
/// <summary> /// Given a Linux event gotten from the trace, make its corresponding sample for the stack source. /// </summary> public LinuxPerfScriptStackSourceSample CreateSampleFor(LinuxEvent linuxEvent, BlockedTimeAnalyzer blockedTimeAnalyzer) { IEnumerable <Frame> frames = linuxEvent.CallerStacks; StackSourceCallStackIndex stackIndex = currentStackIndex; var sample = new LinuxPerfScriptStackSourceSample(this); sample.TimeRelativeMSec = linuxEvent.TimeMSec - StartTimeStampMSec; sample.Metric = (float)linuxEvent.Period; sample.CpuNumber = linuxEvent.CpuNumber; stackIndex = InternFrames(frames.GetEnumerator(), stackIndex, linuxEvent.ProcessID, linuxEvent.ThreadID, doThreadTime ? blockedTimeAnalyzer : null); sample.StackIndex = stackIndex; return(sample); }
public void UpdateThreadState(LinuxEvent linuxEvent) { if (TimeStamp < linuxEvent.TimeMSec) { TimeStamp = linuxEvent.TimeMSec; } if (!BeginningStates.ContainsKey(linuxEvent.ThreadID)) { BeginningStates.Add( linuxEvent.ThreadID, new KeyValuePair <LinuxThreadState, LinuxEvent>(LinuxThreadState.CPU_TIME, linuxEvent)); EndingStates[linuxEvent.ThreadID] = BeginningStates[linuxEvent.ThreadID]; } DoMetrics(linuxEvent); }
public void LinuxEventSampleAssociation(LinuxEvent linuxEvent, StackSourceSample sample) { LinuxEventSamples[linuxEvent] = sample; }
private void DoMetrics(LinuxEvent linuxEvent) { KeyValuePair <LinuxThreadState, LinuxEvent> sampleInfo; // This is check for completed scheduler events, ones that start with prev_comm and have // corresponding next_comm. if (linuxEvent.Kind == EventKind.Scheduler) { SchedulerEvent schedEvent = (SchedulerEvent)linuxEvent; if (EndingStates.ContainsKey(schedEvent.Switch.PreviousThreadID) && EndingStates[schedEvent.Switch.PreviousThreadID].Key == LinuxThreadState.CPU_TIME) // Blocking { // PreviousThreadID is now blocking. linuxEvent contains its blocking stack, so save it here. // When it unblocks (becomes NextThreadID below, we'll log a sample for it.) EndingStates[schedEvent.Switch.PreviousThreadID] = new KeyValuePair <LinuxThreadState, LinuxEvent>(LinuxThreadState.BLOCKED_TIME, linuxEvent); } if (EndingStates.TryGetValue(schedEvent.Switch.NextThreadID, out sampleInfo) && sampleInfo.Key == LinuxThreadState.BLOCKED_TIME) // Unblocking { sampleInfo.Value.Period = linuxEvent.TimeMSec - sampleInfo.Value.TimeMSec; AddThreadPeriod(sampleInfo.Value.ThreadID, sampleInfo.Value.TimeMSec, linuxEvent.TimeMSec); StackSource.AddSample(StackSource.CreateSampleFor(sampleInfo.Value, this)); EndingStates[schedEvent.Switch.NextThreadID] = new KeyValuePair <LinuxThreadState, LinuxEvent>(LinuxThreadState.CPU_TIME, linuxEvent); } } else if (linuxEvent.Kind == EventKind.ThreadExit) { ThreadExitEvent exitEvent = (ThreadExitEvent)linuxEvent; if (EndingStates.TryGetValue(exitEvent.Exit.ThreadID, out sampleInfo)) { if (sampleInfo.Key == LinuxThreadState.BLOCKED_TIME) // Blocked on exit { sampleInfo.Value.Period = linuxEvent.TimeMSec - sampleInfo.Value.TimeMSec; AddThreadPeriod(sampleInfo.Value.ThreadID, sampleInfo.Value.TimeMSec, linuxEvent.TimeMSec); StackSource.AddSample(StackSource.CreateSampleFor(sampleInfo.Value, this)); } else // Unblocked on exit { linuxEvent.Period = linuxEvent.TimeMSec - sampleInfo.Value.TimeMSec; StackSource.AddSample(StackSource.CreateSampleFor(linuxEvent, this)); } // Remove the thread so that any events that might come after the exit are ignored. EndingStates.Remove(exitEvent.Exit.ThreadID); } } else if (linuxEvent.Kind == EventKind.Cpu) { // Keep track of the last CPU sample for each CPU, and use its timestamp // to determine how much weight to give the sample. if (LastCpuUsage.TryGetValue(linuxEvent.CpuNumber, out LinuxEvent lastCpuEvent)) { lastCpuEvent.Period = linuxEvent.TimeMSec - lastCpuEvent.TimeMSec; StackSource.AddSample(StackSource.CreateSampleFor(lastCpuEvent, this)); } LastCpuUsage[linuxEvent.CpuNumber] = linuxEvent; } }