コード例 #1
0
            public IEnumerable <ByteWindow> Lines()
            {
                while (stm.ReadLine(b))
                {
                    if (b.len < typeLen)
                    {
                        continue;
                    }

                    // strip the newline but leave the CR so there is some kind of delimeter left
                    // this assists in parsing (a non-numeric trail character is always at the end)
                    b.len--;

                    t = b.GetLong(1);
                    if (t < t0)
                    {
                        continue;
                    }

                    bAll.Assign(b);

                    bRecord.Assign(b, 0).Trim();

                    idType = trace.atomsRecords.Lookup(bRecord);

                    // unknown record
                    if (idType < 0)
                    {
                        continue;
                    }

                    // ignoreable record
                    if (trace.recordInfo[idType].count <= 0)
                    {
                        continue;
                    }

                    // wait to get a little past the desired area
                    // because lines are sometimes slightly out of order
                    // 1ms cushion is all we do
                    if (t > t1 + 1000)
                    {
                        break;
                    }

                    // don't use any line that is beyond the desired region
                    if (t > t1)
                    {
                        continue;
                    }

                    yield return(b);
                }
            }
コード例 #2
0
ファイル: CSwitch.cs プロジェクト: ScriptBox21/MS-perfview
        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);
        }
コード例 #3
0
ファイル: Memory.cs プロジェクト: lelonek1/perfview-1
            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++;
                        }
                    }
                }
            }
コード例 #4
0
 public int Lookup(string s)
 {
     return(Lookup(bT.Assign(s)));
 }
コード例 #5
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();
        }