Beispiel #1
0
 public ByteWindow(ByteWindow b)
 {
     buffer = b.buffer;
     fields = b.fields;
     ib     = b.ib;
     len    = b.len;
 }
Beispiel #2
0
 public ByteWindow(string s)
 {
     buffer = ByteWindow.MakeBytes(s);
     fields = null;
     ib     = 0;
     len    = buffer.Length;
 }
Beispiel #3
0
        public ByteWindow Assign(ByteWindow b, int fld)
        {
            buffer = b.buffer;
            fields = b.fields;
            ib     = fields[fld];
            len    = fields[fld + 1] - ib - 1;

            return(this);
        }
Beispiel #4
0
        public ByteWindow Assign(ByteWindow b)
        {
            buffer = b.buffer;
            fields = b.fields;
            ib     = b.ib;
            len    = b.len;

            return(this);
        }
Beispiel #5
0
        public ByteWindow(ByteWindow b, int fld)
        {
            buffer = b.buffer;
            fields = b.fields;
            ib     = b.ib;
            len    = b.len;

            Field(fld);
        }
Beispiel #6
0
        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));
                }
            }
        }
Beispiel #7
0
            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());
            }
Beispiel #8
0
        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]);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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;
                }
            }
        }
Beispiel #12
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);
        }
Beispiel #13
0
        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());
        }
Beispiel #14
0
 private byte[] GetFilterText()
 {
     return(ByteWindow.MakeBytes(itparms.FilterText));
 }
Beispiel #15
0
        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());
        }
Beispiel #16
0
            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());
            }
Beispiel #17
0
        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);
                }
            }
        }
Beispiel #18
0
            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++;
                        }
                    }
                }
            }
Beispiel #19
0
        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();
        }
Beispiel #20
0
 public string MakeString(int id)
 {
     return(ByteWindow.MakeString(GetBytes(id)));
 }