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(); }