kernel_stats.cc revision 2665
1754SN/A/* 21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 3754SN/A * All rights reserved. 4754SN/A * 5754SN/A * Redistribution and use in source and binary forms, with or without 6754SN/A * modification, are permitted provided that the following conditions are 7754SN/A * met: redistributions of source code must retain the above copyright 8754SN/A * notice, this list of conditions and the following disclaimer; 9754SN/A * redistributions in binary form must reproduce the above copyright 10754SN/A * notice, this list of conditions and the following disclaimer in the 11754SN/A * documentation and/or other materials provided with the distribution; 12754SN/A * neither the name of the copyright holders nor the names of its 13754SN/A * contributors may be used to endorse or promote products derived from 14754SN/A * this software without specific prior written permission. 15754SN/A * 16754SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17754SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18754SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19754SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20754SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21754SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22754SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23754SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24754SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25754SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26754SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Lisa Hsu 292665Ssaidi@eecs.umich.edu * Nathan Binkert 30754SN/A */ 31754SN/A 32754SN/A#include <map> 33754SN/A#include <stack> 34754SN/A#include <string> 35754SN/A 361070SN/A#include "arch/alpha/osfpal.hh" 371070SN/A#include "base/trace.hh" 38754SN/A#include "cpu/exec_context.hh" 39754SN/A#include "kern/kernel_stats.hh" 401108SN/A#include "kern/tru64/tru64_syscalls.hh" 412235SN/A#include "sim/system.hh" 42754SN/A 43754SN/Ausing namespace std; 44754SN/Ausing namespace Stats; 45754SN/A 461070SN/Anamespace Kernel { 471070SN/A 481082SN/Aconst char *modestr[] = { "kernel", "user", "idle", "interrupt" }; 491070SN/A 502190SN/AStatistics::Statistics(System *system) 512190SN/A : idleProcess((Addr)-1), themode(kernel), lastModeTick(0), 521070SN/A iplLast(0), iplLastTick(0) 53754SN/A{ 542234SN/A bin_int = system->params()->bin_int; 551070SN/A} 56754SN/A 57754SN/Avoid 581070SN/AStatistics::regStats(const string &_name) 59754SN/A{ 601070SN/A myname = _name; 61754SN/A 62754SN/A _arm 631070SN/A .name(name() + ".inst.arm") 64754SN/A .desc("number of arm instructions executed") 65754SN/A ; 66754SN/A 67754SN/A _quiesce 681070SN/A .name(name() + ".inst.quiesce") 69754SN/A .desc("number of quiesce instructions executed") 70754SN/A ; 71754SN/A 72754SN/A _ivlb 731070SN/A .name(name() + ".inst.ivlb") 74754SN/A .desc("number of ivlb instructions executed") 75754SN/A ; 76754SN/A 77754SN/A _ivle 781070SN/A .name(name() + ".inst.ivle") 79754SN/A .desc("number of ivle instructions executed") 80754SN/A ; 81754SN/A 82754SN/A _hwrei 831070SN/A .name(name() + ".inst.hwrei") 84754SN/A .desc("number of hwrei instructions executed") 85754SN/A ; 86754SN/A 87754SN/A _iplCount 88754SN/A .init(32) 891070SN/A .name(name() + ".ipl_count") 90754SN/A .desc("number of times we switched to this ipl") 91754SN/A .flags(total | pdf | nozero | nonan) 92754SN/A ; 93754SN/A 94754SN/A _iplGood 95754SN/A .init(32) 961070SN/A .name(name() + ".ipl_good") 97754SN/A .desc("number of times we switched to this ipl from a different ipl") 98754SN/A .flags(total | pdf | nozero | nonan) 99754SN/A ; 100754SN/A 101754SN/A _iplTicks 102754SN/A .init(32) 1031070SN/A .name(name() + ".ipl_ticks") 104754SN/A .desc("number of cycles we spent at this ipl") 105754SN/A .flags(total | pdf | nozero | nonan) 106754SN/A ; 107754SN/A 108754SN/A _iplUsed 1091070SN/A .name(name() + ".ipl_used") 110754SN/A .desc("fraction of swpipl calls that actually changed the ipl") 111754SN/A .flags(total | nozero | nonan) 112754SN/A ; 113754SN/A 114754SN/A _iplUsed = _iplGood / _iplCount; 115754SN/A 116754SN/A _callpal 117754SN/A .init(256) 1181070SN/A .name(name() + ".callpal") 119754SN/A .desc("number of callpals executed") 120754SN/A .flags(total | pdf | nozero | nonan) 121754SN/A ; 122754SN/A 123754SN/A for (int i = 0; i < PAL::NumCodes; ++i) { 124754SN/A const char *str = PAL::name(i); 125754SN/A if (str) 126754SN/A _callpal.subname(i, str); 127754SN/A } 128754SN/A 129754SN/A _syscall 130754SN/A .init(SystemCalls<Tru64>::Number) 1311070SN/A .name(name() + ".syscall") 132754SN/A .desc("number of syscalls executed") 133754SN/A .flags(total | pdf | nozero | nonan) 134754SN/A ; 135754SN/A 136754SN/A for (int i = 0; i < SystemCalls<Tru64>::Number; ++i) { 137754SN/A const char *str = SystemCalls<Tru64>::name(i); 138754SN/A if (str) { 139754SN/A _syscall.subname(i, str); 140754SN/A } 141754SN/A } 142754SN/A 143754SN/A _mode 1441082SN/A .init(cpu_mode_num) 1451070SN/A .name(name() + ".mode_switch") 146754SN/A .desc("number of protection mode switches") 147754SN/A ; 148754SN/A 1491082SN/A for (int i = 0; i < cpu_mode_num; ++i) 1501070SN/A _mode.subname(i, modestr[i]); 1511070SN/A 152754SN/A _modeGood 1531082SN/A .init(cpu_mode_num) 1541070SN/A .name(name() + ".mode_good") 155754SN/A ; 156754SN/A 1571082SN/A for (int i = 0; i < cpu_mode_num; ++i) 1581070SN/A _modeGood.subname(i, modestr[i]); 1591070SN/A 160754SN/A _modeFraction 1611070SN/A .name(name() + ".mode_switch_good") 162754SN/A .desc("fraction of useful protection mode switches") 163754SN/A .flags(total) 164754SN/A ; 1651070SN/A 1661082SN/A for (int i = 0; i < cpu_mode_num; ++i) 1671070SN/A _modeFraction.subname(i, modestr[i]); 1681070SN/A 169754SN/A _modeFraction = _modeGood / _mode; 170754SN/A 171754SN/A _modeTicks 1721082SN/A .init(cpu_mode_num) 1731070SN/A .name(name() + ".mode_ticks") 174754SN/A .desc("number of ticks spent at the given mode") 175754SN/A .flags(pdf) 176754SN/A ; 1771082SN/A for (int i = 0; i < cpu_mode_num; ++i) 1781070SN/A _modeTicks.subname(i, modestr[i]); 179754SN/A 180754SN/A _swap_context 1811070SN/A .name(name() + ".swap_context") 182754SN/A .desc("number of times the context was actually changed") 183754SN/A ; 184754SN/A} 185754SN/A 186754SN/Avoid 1872190SN/AStatistics::setIdleProcess(Addr idlepcbb, ExecContext *xc) 1881070SN/A{ 1891082SN/A assert(themode == kernel || themode == interrupt); 1901070SN/A idleProcess = idlepcbb; 1911070SN/A themode = idle; 1922190SN/A changeMode(themode, xc); 1931070SN/A} 194754SN/A 195754SN/Avoid 1962190SN/AStatistics::changeMode(cpu_mode newmode, ExecContext *xc) 1971070SN/A{ 1981070SN/A _mode[newmode]++; 1991070SN/A 2001070SN/A if (newmode == themode) 2011070SN/A return; 2021070SN/A 2031070SN/A DPRINTF(Context, "old mode=%-8s new mode=%-8s\n", 2041070SN/A modestr[themode], modestr[newmode]); 2051070SN/A 2061070SN/A _modeGood[newmode]++; 2071070SN/A _modeTicks[themode] += curTick - lastModeTick; 2081070SN/A 2092190SN/A xc->getSystemPtr()->kernelBinning->changeMode(newmode); 2101070SN/A 2111070SN/A lastModeTick = curTick; 2121070SN/A themode = newmode; 2131070SN/A} 214754SN/A 215754SN/Avoid 2161070SN/AStatistics::swpipl(int ipl) 217754SN/A{ 218754SN/A assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n"); 219754SN/A 220754SN/A _iplCount[ipl]++; 221754SN/A 222754SN/A if (ipl == iplLast) 223754SN/A return; 224754SN/A 225754SN/A _iplGood[ipl]++; 226754SN/A _iplTicks[iplLast] += curTick - iplLastTick; 227754SN/A iplLastTick = curTick; 228754SN/A iplLast = ipl; 229754SN/A} 230754SN/A 231754SN/Avoid 2322190SN/AStatistics::mode(cpu_mode newmode, ExecContext *xc) 233754SN/A{ 2342159SN/A Addr pcbb = xc->readMiscReg(AlphaISA::IPR_PALtemp23); 235754SN/A 2361082SN/A if ((newmode == kernel || newmode == interrupt) && 2371082SN/A pcbb == idleProcess) 2381070SN/A newmode = idle; 239754SN/A 2401082SN/A if (bin_int == false && newmode == interrupt) 2411082SN/A newmode = kernel; 2421082SN/A 2432190SN/A changeMode(newmode, xc); 244754SN/A} 245754SN/A 246754SN/Avoid 2472190SN/AStatistics::context(Addr oldpcbb, Addr newpcbb, ExecContext *xc) 2481070SN/A{ 2491070SN/A assert(themode != user); 2501070SN/A 2511070SN/A _swap_context++; 2522190SN/A changeMode(newpcbb == idleProcess ? idle : kernel, xc); 2531070SN/A} 2541070SN/A 2551070SN/Avoid 2562190SN/AStatistics::callpal(int code, ExecContext *xc) 257754SN/A{ 258754SN/A if (!PAL::name(code)) 259754SN/A return; 260754SN/A 261754SN/A _callpal[code]++; 262754SN/A 263754SN/A switch (code) { 2641070SN/A case PAL::callsys: { 2652190SN/A int number = xc->readIntReg(0); 2661070SN/A if (SystemCalls<Tru64>::validSyscallNumber(number)) { 2671070SN/A int cvtnum = SystemCalls<Tru64>::convert(number); 2681070SN/A _syscall[cvtnum]++; 2691070SN/A } 2701070SN/A } break; 2711070SN/A 2721070SN/A case PAL::swpctx: 2732190SN/A if (xc->getSystemPtr()->kernelBinning) 2742190SN/A xc->getSystemPtr()->kernelBinning->palSwapContext(xc); 275754SN/A break; 276754SN/A } 2771070SN/A} 278754SN/A 2791070SN/Avoid 2801070SN/AStatistics::serialize(ostream &os) 2811070SN/A{ 2821070SN/A int exemode = themode; 2831070SN/A SERIALIZE_SCALAR(exemode); 2841096SN/A SERIALIZE_SCALAR(idleProcess); 2851097SN/A SERIALIZE_SCALAR(iplLast); 2861097SN/A SERIALIZE_SCALAR(iplLastTick); 2871097SN/A SERIALIZE_SCALAR(lastModeTick); 2881070SN/A} 289754SN/A 2901070SN/Avoid 2911070SN/AStatistics::unserialize(Checkpoint *cp, const string §ion) 2921070SN/A{ 2931070SN/A int exemode; 2941070SN/A UNSERIALIZE_SCALAR(exemode); 2951096SN/A UNSERIALIZE_SCALAR(idleProcess); 2961097SN/A UNSERIALIZE_SCALAR(iplLast); 2971097SN/A UNSERIALIZE_SCALAR(iplLastTick); 2981097SN/A UNSERIALIZE_SCALAR(lastModeTick); 2991070SN/A themode = (cpu_mode)exemode; 3001070SN/A} 301754SN/A 3021070SN/A/* end namespace Kernel */ } 303