public ByteWindow(ByteWindow b) { buffer = b.buffer; fields = b.fields; ib = b.ib; len = b.len; }
public ByteWindow(string s) { buffer = ByteWindow.MakeBytes(s); fields = null; ib = 0; len = buffer.Length; }
public ByteWindow Assign(ByteWindow b, int fld) { buffer = b.buffer; fields = b.fields; ib = fields[fld]; len = fields[fld + 1] - ib - 1; return(this); }
public ByteWindow Assign(ByteWindow b) { buffer = b.buffer; fields = b.fields; ib = b.ib; len = b.len; return(this); }
public ByteWindow(ByteWindow b, int fld) { buffer = b.buffer; fields = b.fields; ib = b.ib; len = b.len; Field(fld); }
public ETLTrace(ITraceParameters itparms, ITraceUINotify itnotify, string filename) { this.filename = filename; this.initial_parms = itparms; // the original parameters this.itparms = itparms; this.itnotify = itnotify; stm = new BigStream(filename); if (!TryLoadState()) { InitializeFromPrimary(); } else { itnotify.ClearEventFields(); foreach (TimeMark t in listInitialTime) { itnotify.AddTimeToTimeList(t.desc); } } for (int i = 0; i < atomsRecords.Count; i++) { if (recordInfo[i].count > 0) { itnotify.AddEventToEventList(atomsRecords.MakeString(i)); } } for (int i = 0; i < sortedThreads.Length; i++) { ThreadInfo ti = threads[sortedThreads[i]]; itnotify.AddThreadToThreadList(String.Format("{0,20} {1,5} {2}", ByteWindow.MakeString(ti.processPid), ti.threadid, ByteWindow.MakeString(ti.threadproc))); } for (int i = 0; i < processes.Count; i++) { ProcessInfo pi = processes[sortedProcesses[i]]; itnotify.AddProcessToProcessList(ByteWindow.MakeString(pi.processPid)); } for (int i = 0; i < stackTypes.Length; i++) { if (stackTypes[i]) { itnotify.AddEventToStackEventList(atomsRecords.MakeString(i)); } } }
public string DumpMemoryPlots() { if (sortedMemInfos == null || sortedMemInfos.Length < 1) { return(""); } StringWriter sw = new StringWriter(); sw.WriteLine(); sw.WriteLine("VM PLOTS FOR SELECTED PROCESSES"); sw.WriteLine(); int count = 0; foreach (int ipi in sortedMemInfos) { MemInfo p = memInfos[ipi]; if (p.cCommitted == 0 && p.cDecommitted == 0 && p.cReleased == 0 && p.cReserved == 0) { continue; } sw.WriteLine(); sw.WriteLine(); string xLabel = String.Format("Usage from {0}", ByteWindow.MakeString(p.processPid)); string yLabel = "Reserved Bytes"; sw.WriteLine(FormatOnePlot(memoryPlotRows, memoryPlotColumns, xLabel, yLabel, p.reservedDistribution)); sw.WriteLine(); sw.WriteLine(); xLabel = String.Format("Usage from {0}", ByteWindow.MakeString(p.processPid)); yLabel = "Committed Bytes"; sw.WriteLine(FormatOnePlot(memoryPlotRows, memoryPlotColumns, xLabel, yLabel, p.committedDistribution)); count++; if (count >= 3) { break; } } return(sw.ToString()); }
public ThreadInfo FindThreadInfo(long t, int tid) { int iBest = FindThreadInfoIndex(t, tid); if (iBest == -1) { ThreadInfo ti = new ThreadInfo(); ti.threadproc = ByteWindow.MakeBytes("Thread: " + tid.ToString()); ti.processNopid = ByteWindow.MakeBytes("Unknown"); ti.processPid = ti.processNopid; return(ti); } return(threads[iBest]); }
private uint Hash(ref ByteWindow by) { int len = by.len; int ib = by.ib; byte[] buffer = by.buffer; uint hash = 0; for (int i = 0; i < len; i++) { hash = ((hash << 2) | (hash >> 30)) ^ buffer[ib + i]; } return(hash); }
private bool Equals(ByteWindow by, byte[] bytes) { if (by.len != bytes.Length) { return(false); } int len = by.len; int ib = by.ib; byte[] buffer = by.buffer; for (int i = len; --i >= 0;) { if (bytes[i] != buffer[ib + i]) { return(false); } } return(true); }
public int Lookup(ByteWindow by) { uint hash = Hash(ref by); int i = (int)(hash % buckets.Length); for (; ;) { if (buckets[i].bytes == null) { return(-1); } if (Equals(by, buckets[i].bytes)) { return(buckets[i].id); } i++; if (i == buckets.Length) { i = 0; } } }
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()); }
private byte[] GetFilterText() { return(ByteWindow.MakeBytes(itparms.FilterText)); }
public string FormatContextSwitchResult(ContextSwitchResult results) { int nTop = results.nTop; string[] reasonNames = new string[atomsReasons.Count]; for (int i = 0; i < reasonNames.Length; i++) { reasonNames[i] = atomsReasons.MakeString(i); } ThreadStat[] stats = results.stats; int ithreadIdle = IdleThreadIndex; int iStatsIdle = 0; // find where the idle thread landed after sorting for (int i = 0; i < stats.Length; i++) { if (stats[i].ithread == ithreadIdle) { iStatsIdle = i; break; } } StringWriter sw = new StringWriter(); sw.WriteLine("Start time: {0:n0} End time: {1:n0} Interval Length: {2:n0}", tStart, tEnd, tEnd - tStart); sw.WriteLine(); sw.WriteLine("CPUs: {0:n0}, Total CPU Time: {1:n0} usec. Total Switches: {2:n0} Idle: {3,5:f1}% Busy: {4,5:f1}%", results.countCPU, results.timeTotal, results.switchesTotal, stats[iStatsIdle].time * 100.0 / results.timeTotal, (results.timeTotal - stats[iStatsIdle].time) * 100.0 / results.timeTotal); sw.WriteLine(); sw.WriteLine("{0,20} {1,17} {2,35} {3,5} {4,32} {5}", " Time (usec)", " Switches", "Process ( PID)", " TID", "Run Mask", "ThreadProc"); sw.WriteLine("{0,20} {1,17} {2,35} {3,5} {4,32} {5}", "-------------------", "---------------", "--------------", "----", "--------", "----------"); char[] maskChars = new char[32]; for (int i = 0; i < Math.Min(threads.Count, nTop); i++) { int ithread = stats[i].ithread; if (stats[i].time == 0) { continue; } if (!results.threadFilters[ithread]) { continue; } for (int bit = 0; bit < 32; bit++) { maskChars[bit] = ((stats[i].runmask & (1 << bit)) != 0 ? 'X' : '_'); } sw.WriteLine("{0,11:n0} ({1,5:f1}%) {2,8:n0} ({3,5:f1}%) {4,35} {5,5} {6} {7}", stats[i].time, stats[i].time * 100.0 / results.timeTotal, stats[i].switches, stats[i].switches * 100.0 / results.switchesTotal, ByteWindow.MakeString(threads[ithread].processPid), threads[ithread].threadid, new String(maskChars), ByteWindow.MakeString(threads[ithread].threadproc) ); if (results.reasonsComputed) { int[] swapReasons = stats[i].swapReasons; if (swapReasons != null) { for (int k = 0; k < swapReasons.Length; k++) { if (swapReasons[k] > 0) { sw.WriteLine(" {0,17} {1}", reasonNames[k], swapReasons[k]); } } } sw.WriteLine(); } } if (results.fSimulateHyperthreading) { sw.WriteLine(); sw.WriteLine("Hyperthreading Simulation was used to attribute idle cost more accurately"); } return(sw.ToString()); }
public string Dump() { StringWriter sw = new StringWriter(); SortMemInfos(); sw.WriteLine("VM CHANGES IN THIS INTERVAL"); sw.WriteLine(); sw.WriteLine("{8,-35} {0,14} {1,14} {2,14} {3,14} {4,14} {5,14} {6,14} {7,14}", "Reserved", "Count", "Committed", "Count", "Decomitt", "Count", "Released", "Count", "Process"); sw.WriteLine("{8,-35} {0,14} {1,14} {2,14} {3,14} {4,14} {5,14} {6,14} {7,14}", "---------", "-----", "---------", "-----", "--------", "-----", "--------", "-----", "-------"); foreach (int ipi in sortedMemInfos) { MemInfo p = memInfos[ipi]; if (p.cCommitted == 0 && p.cDecommitted == 0 && p.cReleased == 0 && p.cReserved == 0) { continue; } sw.WriteLine("{8,-35} {0,14:n0} {1,14:n0} {2,14:n0} {3,14:n0} {4,14:n0} {5,14:n0} {6,14:n0} {7,14:n0}" , p.cbReserved , p.cReserved , p.cbCommitted , p.cCommitted , p.cbDecommitted , p.cDecommitted , p.cbReleased , p.cReleased , ByteWindow.MakeString(p.processPid) ); } sw.WriteLine(); sw.WriteLine("VM ALLOCATED AT END OF THIS INTERVAL"); sw.WriteLine(); sw.WriteLine("{4,-35} {0,14} {1,14} {2,14} {3,14}", "Reserved", "Ranges", "Committed", "Ranges", "Process"); sw.WriteLine("{4,-35} {0,14} {1,14} {2,14} {3,14}", "--------", "------", "---------", "------", "-------"); foreach (int ipi in sortedMemInfos) { MemInfo p = memInfos[ipi]; if (p.cCommitted == 0 && p.cDecommitted == 0 && p.cReleased == 0 && p.cReserved == 0) { continue; } sw.WriteLine("{4,-35} {0,14:n0} {1,14:n0} {2,14:n0} {3,14:n0}" , p.rsReserved.Count , p.rsReserved.RangeCount , p.rsCommitted.Count , p.rsCommitted.RangeCount , ByteWindow.MakeString(p.processPid) ); } return(sw.ToString()); }
public bool ReadLine(ByteWindow b) { pos = posNext; for (; ;) { int fld = 0; while (stm_i_offset < stm_c_offsets) { ib = stm_offsets[stm_i_offset]; if (ib >= 0) { if (fld < fields.Length) { fields[fld++] = ib; } stm_i_offset++; } else { ib = -ib; b.ib = fields[0]; b.len = (ib - b.ib); b.fields = fields; b.buffer = stm_buffer; b.fieldsLen = fld; // note the fields offset array goes one past the number of fields so that length can always be computed // for a legal field by taking the offset of field[n+1] minus field[n] // include just one terminator character, either the /r or the /n if (ib > 0 && stm_buffer[ib - 1] == '\r') { if (fld < fields.Length) { fields[fld++] = ib; // use the /r if there is one } } else { if (fld < fields.Length) { fields[fld++] = ib + 1; // else use the /n } b.len++; } stm_i_offset++; posNext += b.len + 1; return(true); } } int cb = ReadBuffer(stm_buffer, 0, stm_buffer.Length); if (cb == 0) { b.fields = null; b.buffer = null; b.ib = 0; b.len = 0; b.fieldsLen = 0; return(false); } } }
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++; } } } }
void InitializeFromPrimary() { atomsFields = new ByteAtomTable(); atomsRecords = new ByteAtomTable(); atomsProcesses = new ByteAtomTable(); listEventFields = new List <List <int> >(); byte[] byRecordEscape = ByteWindow.MakeBytes("$R"); idRecordEscape = atomsFields.EnsureContains(byRecordEscape); byte[] byTimeEscape = ByteWindow.MakeBytes("$T"); idTimeEscape = atomsFields.EnsureContains(byTimeEscape); byte[] byTimeOffsetEscape = ByteWindow.MakeBytes("$TimeOffset"); idTimeOffsetEscape = atomsFields.EnsureContains(byTimeOffsetEscape); byte[] byWhenEscape = ByteWindow.MakeBytes("$When"); idWhenEscape = atomsFields.EnsureContains(byWhenEscape); byte[] byFirstEscape = ByteWindow.MakeBytes("$First"); idFirstEscape = atomsFields.EnsureContains(byFirstEscape); byte[] byLastEscape = ByteWindow.MakeBytes("$Last"); idLastEscape = atomsFields.EnsureContains(byLastEscape); byte[] byBeginHeader = ByteWindow.MakeBytes("BeginHeader"); byte[] byEndHeader = ByteWindow.MakeBytes("EndHeader"); ByteWindow b = new ByteWindow(); threads.Clear(); offsets.Clear(); while (stm.ReadLine(b)) { if (b.StartsWith(byBeginHeader)) { break; } } while (stm.ReadLine(b)) { if (b.StartsWith(byEndHeader)) { break; } b.Field(0).Trim(); int iCountBefore = atomsRecords.Count; atomsRecords.EnsureContains(b); if (atomsRecords.Count == iCountBefore) { continue; } List <int> listFields = new List <int>(); listEventFields.Add(listFields); listFields.Add(0); // the ID for $R, the record escape field // start from field 1 -- that skips only field 0 which is already mapped to $R for (int i = 1; i < b.fieldsLen; i++) { b.Field(i).Trim(); int id = atomsFields.EnsureContains(b); listFields.Add(id); } } stackIgnoreEvents = new bool[atomsRecords.Count]; foreach (string strEvent in stackIgnoreEventStrings) { int id = atomsRecords.Lookup(strEvent); if (id >= 0) { stackIgnoreEvents[id] = true; } } recordInfo = new RecordInfo[atomsRecords.Count]; int idThreadField = atomsFields.Lookup("ThreadID"); int idFileNameField = atomsFields.Lookup("FileName"); int idTypeField = atomsFields.Lookup("Type"); int idSizeField = atomsFields.Lookup("Size"); int idIOSizeField = atomsFields.Lookup("IOSize"); int idElapsedTimeField = atomsFields.Lookup("ElapsedTime"); for (int i = 0; i < recordInfo.Length; i++) { List <int> fieldList = listEventFields[i]; recordInfo[i].threadField = fieldList.IndexOf(idThreadField); recordInfo[i].sizeField = fieldList.IndexOf(idSizeField); if (-1 == recordInfo[i].sizeField) { recordInfo[i].sizeField = fieldList.IndexOf(idIOSizeField); } recordInfo[i].goodNameField = fieldList.IndexOf(idFileNameField); if (-1 == recordInfo[i].goodNameField) { recordInfo[i].goodNameField = fieldList.IndexOf(idTypeField); } recordInfo[i].elapsedTimeField = fieldList.IndexOf(idElapsedTimeField); } int idT_DCEnd = atomsRecords.Lookup("T-DCEnd"); int idT_DCStart = atomsRecords.Lookup("T-DCStart"); int idT_Start = atomsRecords.Lookup("T-Start"); int idT_End = atomsRecords.Lookup("T-End"); int idCSwitch = atomsRecords.Lookup("CSwitch"); int idStack = atomsRecords.Lookup("Stack"); int idAlloc = atomsRecords.Lookup("Allocation"); int idFirstReliableEventTimeStamp = atomsRecords.Lookup("FirstReliableEventTimeStamp"); int idFirstReliableCSwitchEventTimeStamp = atomsRecords.Lookup("FirstReliableCSwitchEventTimeStamp"); long tNext = 100000; long t = 0; // seed offsets for the 0th record offsets.Add(stm.Position); listInitialTime = new List <TimeMark>(); maxCPU = 64; CPUState[] state = new CPUState[maxCPU]; const int maxEvent = 16; PreviousEvent[] prev = new PreviousEvent[maxEvent]; int iNextEvent = 0; stackTypes = new bool[atomsRecords.Count]; Dictionary <int, int> dictStartedThreads = new Dictionary <int, int>(); ByteWindow record = new ByteWindow(); ByteWindow bThreadProc = new ByteWindow(); ByteWindow bProcess = new ByteWindow(); // the first line of the trace is the trace info, that, importantly, has the OSVersion tag if (stm.ReadLine(b)) { traceinfo = b.GetString(); } else { traceinfo = "None"; } while (stm.ReadLine(b)) { if (b.len < typeLen) { continue; } record.Assign(b, 0).Trim(); int idrec = atomsRecords.Lookup(record); if (idrec < 0) { continue; } if (idrec == idFirstReliableCSwitchEventTimeStamp || idrec == idFirstReliableEventTimeStamp) { continue; } recordInfo[idrec].count++; t = b.GetLong(1); while (t >= tNext) { tNext = AddTimeRow(tNext, state); } if (idrec != idStack && !stackIgnoreEvents[idrec]) { prev[iNextEvent].time = t; prev[iNextEvent].eventId = idrec; iNextEvent = (iNextEvent + 1) % maxEvent; } if (idrec == idStack) { int i = iNextEvent; for (; ;) { if (--i < 0) { i = maxEvent - 1; } if (i == iNextEvent) { break; } if (prev[i].time == t) { stackTypes[prev[i].eventId] = true; break; } } } else if (idrec == idT_Start || idrec == idT_End || idrec == idT_DCStart || idrec == idT_DCEnd) { ThreadInfo ti = new ThreadInfo(); ti.threadid = b.GetInt(fldTStartThreadId); bool fStarted = dictStartedThreads.ContainsKey(ti.threadid); if (idrec == idT_Start) { ti.timestamp = t; } else if (idrec == idT_DCStart) { ti.timestamp = 0; } else { if (fStarted) { continue; } ti.timestamp = 0; } if (!fStarted) { dictStartedThreads.Add(ti.threadid, 0); } bThreadProc.Assign(b, fldTStartThreadProc).Trim(); bProcess.Assign(b, fldTStartProcess).Trim(); ti.processPid = bProcess.Clone(); if (atomsProcesses.Lookup(bProcess) == -1) { atomsProcesses.EnsureContains(ti.processPid); ProcessInfo pi = new ProcessInfo(); pi.processPid = ti.processPid; processes.Add(pi); } bProcess.Truncate((byte)'(').Trim(); ti.processNopid = bProcess.Clone(); ti.threadproc = bThreadProc.Clone(); threads.Add(ti); } else if (idrec == idCSwitch) { int newTid = b.GetInt(fldCSwitchNewTID); int oldTid = b.GetInt(fldCSwitchOldTID); int cpu = b.GetInt(fldCSwitchCPU); if (cpu < 0 || cpu > state.Length) { continue; } int tusage = (int)(t - state[cpu].time); if (state[cpu].tid != 0 && tusage > 0) { state[cpu].usage += tusage; } state[cpu].time = t; state[cpu].tid = newTid; state[cpu].active = true; } } AddTimeRow(t, state); threads.Sort(); int tid = -1; mp_tid_firstindex = new Dictionary <int, int>(); for (int i = 0; i < threads.Count; i++) { if (tid != threads[i].threadid) { tid = threads[i].threadid; mp_tid_firstindex.Add(tid, i); } } sortedThreads = new int[threads.Count]; for (int i = 0; i < sortedThreads.Length; i++) { sortedThreads[i] = i; } Array.Sort(sortedThreads, delegate(int id1, int id2) { byte[] b1 = threads[id1].processPid; byte[] b2 = threads[id2].processPid; int cmp = ByteWindow.CompareBytes(b1, b2, true); if (cmp != 0) { return(cmp); } if (threads[id1].threadid < threads[id2].threadid) { return(-1); } if (threads[id1].threadid > threads[id2].threadid) { return(1); } return(0); } ); sortedProcesses = new int[processes.Count]; for (int i = 0; i < sortedProcesses.Length; i++) { sortedProcesses[i] = i; } Array.Sort(sortedProcesses, delegate(int id1, int id2) { byte[] b1 = processes[id1].processPid; byte[] b2 = processes[id2].processPid; return(ByteWindow.CompareBytes(b1, b2, true)); } ); tmax = t; TrySaveState(); }
public string MakeString(int id) { return(ByteWindow.MakeString(GetBytes(id))); }