/* This file is part of procinfo-NG procinfo-NG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2. procinfo-NG is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with procinfo-NG; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Procinfo-NG is Copyright tabris@tabris.net 2007, 2008 vector normalizeCPUstats(const double elapsed, const uint64_t CPUcount, const vector &input) { if(elapsed == 0) return input; vector output(input.begin(), input.end() - 2); uint64_t timeSum = sumVec(output); double factor = (USER_HZ * (CPUcount * elapsed)) / double(timeSum); for(uint32_t i = 0; i < output.size(); i++) output[i] = uint64_t(double(output[i]) * factor); return output; } // returns multiple lists of uint64s, cpuDiffs, intrDiffs, and a list consisting of context-switches and the boot-time vector > getProcStat(bool showTotals, const uint32_t CPUcount, const double elapsed) { vector lines = readFile(string("/proc/stat")); vector cpuDiff, cpuStat, intrDiff, intrStat; static vector oldCPUstat, oldIntrStat; static uint64_t oldCtxtStat = 0; uint64_t ctxtStat, ctxtDiff, bootTime; uint64_t cpuTotal = 0; for(uint32_t i = 0; i < lines.size(); i++) { vector tokens = splitString(" ", lines[i]); if (!tokens.size()) break; // a) prevents SIGSEGV b) skips empty lines if(tokens[0] == "cpu") { tokens.erase(tokens.begin()); // pop the first token off. cpuStat = stringVec2uint64Vec(tokens); if(!oldCPUstat.size()) oldCPUstat.resize(cpuStat.size()); cpuDiff = (showTotals ? cpuStat : subVec(cpuStat, oldCPUstat)); cpuTotal = sumVec(cpuStat); oldCPUstat.assign(cpuStat.begin(), cpuStat.end()); cpuDiff.push_back(cpuTotal); } else if(tokens[0] == "intr") { if(tokens.size() <= 2) { intrStat = getIRQcount(); } else { // We don't want the second token b/c it's just the total number of interrupts serviced. tokens.erase(tokens.begin()); // pop the first token off. tokens.erase(tokens.begin()); // pop the second token off. intrStat = stringVec2uint64Vec(tokens); } if(oldIntrStat.size() < intrStat.size()) oldIntrStat.resize(intrStat.size(), 0); intrDiff = (showTotals ? intrStat : subVec(intrStat, oldIntrStat)); oldIntrStat.assign(intrStat.begin(), intrStat.end()); } else if(tokens[0] == "ctxt") { ctxtStat = string2uint64(tokens[1]); ctxtDiff = (showTotals ? ctxtStat : ctxtStat - oldCtxtStat); oldCtxtStat = ctxtStat; } else if(tokens[0] == "btime") { bootTime = string2uint64(tokens[1]); } } vector > stats; stats.resize(3); stats[0] = normalizeCPUstats(elapsed, CPUcount, cpuDiff); stats[1] = intrDiff; stats[2].push_back(ctxtDiff); stats[2].push_back(bootTime); return stats; } // returns the contents of /proc/vmstat, only the parts we want. // as such it returns a vector of 4 elements, pageInDiff, pageOutDiff, swapInDiff, swapOutDiff vector getVMstat(bool showTotals) { vector lines = readFile(string("/proc/vmstat")); static uint64_t oldPageIn = 0, oldPageOut = 0, oldSwapIn = 0, oldSwapOut = 0; uint64_t pageIn = 0, pageOut = 0, swapIn = 0, swapOut = 0; uint64_t pageInDiff = 0, pageOutDiff = 0, swapInDiff = 0, swapOutDiff = 0; static uint64_t oldPageAct = 0, oldPageDeact = 0, oldPageFault = 0; uint64_t pageAct = 0, pageDeact = 0, pageFault = 0; uint64_t pageActDiff = 0, pageDeactDiff = 0, pageFaultDiff = 0; for(uint32_t i = 0; i < lines.size(); i++) { vector tokens = splitString(" ", lines[i]); if (!tokens.size()) break; if(tokens[0] == "pgpgin") { pageIn = string2uint64(tokens[1]); pageInDiff = (showTotals ? pageIn : pageIn - oldPageIn); oldPageIn = pageIn; } else if(tokens[0] == "pgpgout") { pageOut = string2uint64(tokens[1]); pageOutDiff = (showTotals ? pageOut : pageOut - oldPageOut); oldPageOut = pageOut; } else if(tokens[0] == "pswpin") { swapIn = string2uint64(tokens[1]); swapInDiff = (showTotals ? swapIn : swapIn - oldSwapIn); oldSwapIn = swapIn; } else if(tokens[0] == "pswpout") { swapOut = string2uint64(tokens[1]); swapOutDiff = (showTotals ? swapOut : swapOut - oldSwapOut); oldSwapOut = swapOut; } else if(tokens[0] == "pgactivate") { pageAct = string2uint64(tokens[1]); pageActDiff = (showTotals ? pageAct : pageAct - oldPageAct); oldPageAct = pageAct; } else if(tokens[0] == "pgdeactivate") { pageDeact = string2uint64(tokens[1]); pageDeactDiff = (showTotals ? pageDeact : pageDeact - oldPageDeact); oldPageDeact = pageDeact; } else if(tokens[0] == "pgfault") { pageFault = string2uint64(tokens[1]); pageFaultDiff = (showTotals ? pageFault : pageFault - oldPageFault); oldPageFault = pageFault; } } vector vmStat; vmStat.push_back(pageInDiff); vmStat.push_back(pageOutDiff); vmStat.push_back(pageActDiff); vmStat.push_back(pageDeactDiff); vmStat.push_back(pageFaultDiff); vmStat.push_back(swapInDiff); vmStat.push_back(swapOutDiff); return vmStat; }