Example #1
0
        private void InitializeStartingCPUStates(CPUState[] state, int idCSwitch)
        {
            int countCPU = 0;

            // find the first thread on each proc

            ETWLineReader l = StandardLineReader();

            l.t1 = Int64.MaxValue - 10000; // keep reading until we find all cpus regardless of how far in the future we have to look
            foreach (ByteWindow b in l.Lines())
            {
                if (l.idType != idCSwitch)
                {
                    continue;
                }

                int cpu = b.GetInt(fldCSwitchCPU);
                if (state[cpu].active)
                {
                    continue;
                }

                state[cpu].active = true;
                state[cpu].tid    = b.GetInt(fldCSwitchOldTID);
                state[cpu].time   = l.t0;

                countCPU++;
                if (countCPU >= maxCPU)
                {
                    break;
                }
            }
        }
Example #2
0
        public void ZoomTimeWindow()
        {
            ClearZoomedTimes();

            long      zoomed_t0     = itparms.T0;
            long      zoomed_t1     = itparms.T1;
            const int zoomed_splits = 50;

            int idCSwitch = atomsRecords.Lookup("CSwitch");

            int i = 1;

            long timeStart = zoomed_t0;
            long timeEnd   = zoomed_t0 + (zoomed_t1 - zoomed_t0) * i / zoomed_splits;

            CPUState[] state = new CPUState[maxCPU];

            InitializeStartingCPUStates(state, idCSwitch);

            ETWLineReader l = StandardLineReader();

            foreach (ByteWindow b in l.Lines())
            {
                while (l.t >= timeEnd && i <= zoomed_splits)
                {
                    AddZoomedTimeRow(timeStart, timeEnd, state);
                    i++;
                    timeStart = timeEnd;
                    timeEnd   = zoomed_t0 + (zoomed_t1 - zoomed_t0) * i / zoomed_splits;
                }

                if (l.idType != idCSwitch)
                {
                    continue;
                }

                int newTid = b.GetInt(fldCSwitchNewTID);
                int oldTid = b.GetInt(fldCSwitchOldTID);
                int cpu    = b.GetInt(fldCSwitchCPU);

                int tusage = (int)(l.t - state[cpu].time);

                if (state[cpu].tid != 0)
                {
                    state[cpu].usage += tusage;
                }

                state[cpu].time   = l.t;
                state[cpu].tid    = newTid;
                state[cpu].active = true;
            }

            while (i <= zoomed_splits)
            {
                AddZoomedTimeRow(timeStart, timeEnd, state);
                i++;
                timeStart = timeEnd;
                timeEnd   = zoomed_t0 + (zoomed_t1 - zoomed_t0) * i / zoomed_splits;
            }
        }
Example #3
0
        public string ComputeMatches()
        {
            bool fFilterThreads   = itparms.EnableThreadFilter;
            bool fFilterProcesses = itparms.EnableProcessFilter;

            bool[] filters = itparms.EventFilters.GetFilters();

            if (filters == null)
            {
                return("No filter specified");
            }

            int countLimit = 10000;
            int count      = 0;

            StringWriter sw = new StringWriter();

            ETWLineReader l = StandardLineReader();

            foreach (ByteWindow b in l.Lines())
            {
                if (!l.MatchingRecordType(filters))
                {
                    continue;
                }

                if (fFilterThreads && !l.MatchingThread())
                {
                    continue;
                }

                if (fFilterProcesses && !l.MatchingProcess())
                {
                    continue;
                }

                if (!l.MatchingTextFilter())
                {
                    continue;
                }

                if (!l.MatchingMemory())
                {
                    continue;
                }

                sw.WriteLine(b.GetString());

                count++;
                if (count >= countLimit)
                {
                    sw.WriteLine("Output truncated at {0} lines", countLimit);
                    break;
                }
            }

            return(sw.ToString());
        }
Example #4
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);
        }
Example #5
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());
        }
Example #6
0
        public string ComputeMemory(int intervals, bool fDumpRanges)
        {
            bool fFilterProcesses = itparms.EnableProcessFilter;

            StringWriter sw = new StringWriter();

            var mem = new MemProcessor(this);

            ETWLineReader l = StandardLineReader();

            long tDelta    = (l.t1 - l.t0) / intervals;
            long tStart    = l.t0;
            long tNext     = l.t0 + tDelta;
            int  iInterval = 0;

            bool fOut = false;

            MemEffect effect = new MemEffect();

            foreach (ByteWindow b in l.Lines())
            {
                if (l.t > tNext && iInterval < intervals - 1)
                {
                    if (!mem.IsEmpty)
                    {
                        fOut = true;
                        DumpRangeTime(sw, tStart, tNext);
                        sw.WriteLine(mem.Dump());
                    }

                    mem.Reset();
                    tStart = tNext;
                    tNext += tDelta;
                }

                if (l.idType != mem.idAlloc && l.idType != mem.idFree)
                {
                    continue;
                }

                if (fFilterProcesses && !l.MatchingProcess())
                {
                    continue;
                }

                if (!l.MatchingTextFilter())
                {
                    continue;
                }

                if (!l.MatchingMemory())
                {
                    continue;
                }

                mem.ProcessMemRecord(l, b, effect);
            }

            if (!mem.IsEmpty)
            {
                fOut = true;
                DumpRangeTime(sw, tStart, l.t1);
                sw.WriteLine(mem.Dump());
            }

            sw.WriteLine(mem.DumpMemoryPlots());

            if (fOut)
            {
                if (fDumpRanges)
                {
                    sw.WriteLine();
                    sw.WriteLine(mem.DumpRanges());
                }
            }
            else
            {
                sw.WriteLine("No activity");
            }

            lastMemProcessor = mem;
            return(sw.ToString());
        }
Example #7
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++;
                        }
                    }
                }
            }