private void InitializeStartingCPUStates(CPUState[] state, int idCSwitch) { int countCPU = 0; // find the first thread on each proc ETWLineReader l = StandardLineReader(); l.t1 = Int64.MaxValue - 10000; // keep reading until we find all cpus regardless of how far in the future we have to look foreach (ByteWindow b in l.Lines()) { if (l.idType != idCSwitch) { continue; } int cpu = b.GetInt(fldCSwitchCPU); if (state[cpu].active) { continue; } state[cpu].active = true; state[cpu].tid = b.GetInt(fldCSwitchOldTID); state[cpu].time = l.t0; countCPU++; if (countCPU >= maxCPU) { break; } } }
public void ZoomTimeWindow() { ClearZoomedTimes(); long zoomed_t0 = itparms.T0; long zoomed_t1 = itparms.T1; const int zoomed_splits = 50; int idCSwitch = atomsRecords.Lookup("CSwitch"); int i = 1; long timeStart = zoomed_t0; long timeEnd = zoomed_t0 + (zoomed_t1 - zoomed_t0) * i / zoomed_splits; CPUState[] state = new CPUState[maxCPU]; InitializeStartingCPUStates(state, idCSwitch); ETWLineReader l = StandardLineReader(); foreach (ByteWindow b in l.Lines()) { while (l.t >= timeEnd && i <= zoomed_splits) { AddZoomedTimeRow(timeStart, timeEnd, state); i++; timeStart = timeEnd; timeEnd = zoomed_t0 + (zoomed_t1 - zoomed_t0) * i / zoomed_splits; } if (l.idType != idCSwitch) { continue; } int newTid = b.GetInt(fldCSwitchNewTID); int oldTid = b.GetInt(fldCSwitchOldTID); int cpu = b.GetInt(fldCSwitchCPU); int tusage = (int)(l.t - state[cpu].time); if (state[cpu].tid != 0) { state[cpu].usage += tusage; } state[cpu].time = l.t; state[cpu].tid = newTid; state[cpu].active = true; } while (i <= zoomed_splits) { AddZoomedTimeRow(timeStart, timeEnd, state); i++; timeStart = timeEnd; timeEnd = zoomed_t0 + (zoomed_t1 - zoomed_t0) * i / zoomed_splits; } }
public string ComputeMatches() { bool fFilterThreads = itparms.EnableThreadFilter; bool fFilterProcesses = itparms.EnableProcessFilter; bool[] filters = itparms.EventFilters.GetFilters(); if (filters == null) { return("No filter specified"); } int countLimit = 10000; int count = 0; StringWriter sw = new StringWriter(); ETWLineReader l = StandardLineReader(); foreach (ByteWindow b in l.Lines()) { if (!l.MatchingRecordType(filters)) { continue; } if (fFilterThreads && !l.MatchingThread()) { continue; } if (fFilterProcesses && !l.MatchingProcess()) { continue; } if (!l.MatchingTextFilter()) { continue; } if (!l.MatchingMemory()) { continue; } sw.WriteLine(b.GetString()); count++; if (count >= countLimit) { sw.WriteLine("Output truncated at {0} lines", countLimit); break; } } return(sw.ToString()); }
public ContextSwitchResult ComputeContextSwitchesRaw() { IContextSwitchParameters icswitchparms = itparms.ContextSwitchParameters; bool fSimulateHyperthreading = icswitchparms.SimulateHyperthreading; bool fSortBySwitches = icswitchparms.SortBySwitches; bool fComputeReasons = icswitchparms.ComputeReasons; int nTop = icswitchparms.TopThreadCount; ByteWindow bT = new ByteWindow(); long timeTotal = 0; int switchesTotal = 0; tStart = itparms.T0; tEnd = itparms.T1; ThreadStat[] stats = NewThreadStats(); CPUState[] state = new CPUState[maxCPU]; int idCSwitch = atomsRecords.Lookup("CSwitch"); bool[] threadFilters = itparms.GetThreadFilters(); InitializeStartingCPUStates(state, idCSwitch); // rewind ETWLineReader l = StandardLineReader(); foreach (ByteWindow b in l.Lines()) { if (l.idType != idCSwitch) { continue; } int oldTid = b.GetInt(fldCSwitchOldTID); int cpu = b.GetInt(fldCSwitchCPU); timeTotal += AddCSwitchTime(fSimulateHyperthreading, l.t, stats, state); int newTid = b.GetInt(fldCSwitchNewTID); int idx = FindThreadInfoIndex(l.t, oldTid); stats[idx].switches++; switchesTotal++; if (fComputeReasons) { bT.Assign(b, fldCSwitchWaitReason).Trim(); int id = atomsReasons.EnsureContains(bT); if (stats[idx].swapReasons == null) { stats[idx].swapReasons = new int[maxReasons]; } stats[idx].swapReasons[id]++; } state[cpu].active = true; state[cpu].tid = newTid; state[cpu].time = l.t; } timeTotal += AddCSwitchTime(fSimulateHyperthreading, l.t1, stats, state); if (fSortBySwitches) { Array.Sort(stats, delegate(ThreadStat c1, ThreadStat c2) { if (c1.switches > c2.switches) { return(-1); } if (c1.switches < c2.switches) { return(1); } return(0); } ); } else { Array.Sort(stats, delegate(ThreadStat c1, ThreadStat c2) { if (c1.time > c2.time) { return(-1); } if (c1.time < c2.time) { return(1); } return(0); } ); } var result = new ContextSwitchResult(); result.stats = stats; result.switchesTotal = switchesTotal; result.timeTotal = timeTotal; result.fSortBySwitches = fSortBySwitches; result.reasonsComputed = fComputeReasons; result.threadFilters = threadFilters; result.countCPU = maxCPU; result.nTop = nTop; return(result); }
public string ComputeDelays(int delaySize) { ThreadStat[] stats = NewThreadStats(); bool[] threadFilters = itparms.GetThreadFilters(); int idCSwitch = atomsRecords.Lookup("CSwitch"); StringWriter sw = new StringWriter(); sw.WriteLine("{0,15} {1,15} {2,15} {3,30} {4,5} {5,-60}", "Delay Start", "Delay End", "Delay Duration", "Process Name ( ID )", "TID", "Threadproc"); sw.WriteLine("{0,15} {1,15} {2,15} {3,30} {4,5} {5,-60}", "-----------", "---------", "--------------", "-------------------", "---", "----------"); listDelays = new List <TimeMark>(); int totalDelays = 0; long totalDelay = 0; long T0 = itparms.T0; for (int i = 0; i < stats.Length; i++) { stats[i].time = Math.Max(T0, threads[i].timestamp); } ETWLineReader l = StandardLineReader(); foreach (ByteWindow b in l.Lines()) { if (l.idType != idCSwitch) { continue; } int oldTid = b.GetInt(fldCSwitchOldTID); int idxOld = FindThreadInfoIndex(l.t, oldTid); stats[idxOld].time = l.t; int newTid = b.GetInt(fldCSwitchNewTID); int idxNew = FindThreadInfoIndex(l.t, newTid); int waitTime = (int)(l.t - stats[idxNew].time); if (waitTime <= 0) { continue; } if (!threadFilters[idxNew]) { continue; } totalDelays++; totalDelay += waitTime; if (waitTime > delaySize) { TimeMark tm = new TimeMark(); tm.t0 = l.t - waitTime; tm.t1 = l.t; string process = ByteWindow.MakeString(threads[idxNew].processPid); string threadproc = ByteWindow.MakeString(threads[idxNew].threadproc); tm.desc = String.Format("{0,15:n0} {1,15:n0} {2,15:n0} {3,30} {4,5} {5,-60}", tm.t0, tm.t1, waitTime, process, newTid, threadproc); sw.WriteLine(tm.desc); listDelays.Add(tm); } } sw.WriteLine(); sw.WriteLine("Total Delays: {0:n0} Total Delay Time {1:n0}", totalDelays, totalDelay); return(sw.ToString()); }
public string ComputeMemory(int intervals, bool fDumpRanges) { bool fFilterProcesses = itparms.EnableProcessFilter; StringWriter sw = new StringWriter(); var mem = new MemProcessor(this); ETWLineReader l = StandardLineReader(); long tDelta = (l.t1 - l.t0) / intervals; long tStart = l.t0; long tNext = l.t0 + tDelta; int iInterval = 0; bool fOut = false; MemEffect effect = new MemEffect(); foreach (ByteWindow b in l.Lines()) { if (l.t > tNext && iInterval < intervals - 1) { if (!mem.IsEmpty) { fOut = true; DumpRangeTime(sw, tStart, tNext); sw.WriteLine(mem.Dump()); } mem.Reset(); tStart = tNext; tNext += tDelta; } if (l.idType != mem.idAlloc && l.idType != mem.idFree) { continue; } if (fFilterProcesses && !l.MatchingProcess()) { continue; } if (!l.MatchingTextFilter()) { continue; } if (!l.MatchingMemory()) { continue; } mem.ProcessMemRecord(l, b, effect); } if (!mem.IsEmpty) { fOut = true; DumpRangeTime(sw, tStart, l.t1); sw.WriteLine(mem.Dump()); } sw.WriteLine(mem.DumpMemoryPlots()); if (fOut) { if (fDumpRanges) { sw.WriteLine(); sw.WriteLine(mem.DumpRanges()); } } else { sw.WriteLine("No activity"); } lastMemProcessor = mem; return(sw.ToString()); }
public void ProcessMemRecord(ETWLineReader l, ByteWindow b, MemEffect memeffect) { // empty the net effect of this record memeffect.released = memeffect.reserved = memeffect.committed = memeffect.decommitted = 0; int interval = (int)((l.t - l.t0) / (double)(l.t1 - l.t0) * memoryPlotColumns); // the above can overflow because time ranges might be out of order so clamp any overflows // also we have to handle the case where l.t == l.t1 which would otherwise overflow if (interval < 0) { interval = 0; } if (interval >= memoryPlotColumns) { interval = memoryPlotColumns - 1; } bT.Assign(b, fldProcessNamePID).Trim(); int idProcess = trace.atomsProcesses.Lookup(bT); // bogus process, disregard if (idProcess == -1) { return; } MemInfo p = memInfos[idProcess]; var rsReserved = p.rsReserved; var rsCommitted = p.rsCommitted; ulong addrBase = b.GetHex(fldMemBaseAddr); ulong addrEnd = b.GetHex(fldMemEndAddr); b.Field(fldFlags).Trim(); if (l.idType == idAlloc) { if (b.StartsWith(byReserveCommit)) { memeffect.reserved = rsReserved.AddRange(addrBase, addrEnd); p.cbReserved += memeffect.reserved; p.reservedDistribution[interval] += (long)memeffect.reserved; if (memeffect.reserved != 0) { p.cReserved++; } memeffect.committed = rsCommitted.AddRange(addrBase, addrEnd); p.cbCommitted += memeffect.committed; p.committedDistribution[interval] += (long)memeffect.committed; if (memeffect.committed != 0) { p.cCommitted++; } } else if (b.StartsWith(byReserve)) { memeffect.reserved = rsReserved.AddRange(addrBase, addrEnd); p.cbReserved += memeffect.reserved; p.reservedDistribution[interval] += (long)memeffect.reserved; if (memeffect.reserved != 0) { p.cReserved++; } } else if (b.StartsWith(byCommit)) { memeffect.committed = rsCommitted.AddRange(addrBase, addrEnd); p.cbCommitted += memeffect.committed; p.committedDistribution[interval] += (long)memeffect.committed; if (memeffect.committed != 0) { p.cCommitted++; } } } if (l.idType == idFree) { if (b.StartsWith(byRelease)) { memeffect.decommitted = rsCommitted.RemoveRange(addrBase, addrEnd); p.cbDecommitted += memeffect.decommitted; p.committedDistribution[interval] -= (long)memeffect.decommitted; if (memeffect.decommitted != 0) { p.cDecommitted++; } memeffect.released = rsReserved.RemoveRange(addrBase, addrEnd); p.cbReleased += memeffect.released; p.reservedDistribution[interval] -= (long)memeffect.released; if (memeffect.released != 0) { p.cReleased++; } } else if (b.StartsWith(byDecommit)) { memeffect.decommitted = rsCommitted.RemoveRange(addrBase, addrEnd); p.cbDecommitted += memeffect.decommitted; p.committedDistribution[interval] -= (long)memeffect.decommitted; if (memeffect.decommitted != 0) { p.cDecommitted++; } } } }