kernel_stats.cc revision 10905
11689SN/A/* 22326SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Lisa Hsu 292831Sksewell@umich.edu * Nathan Binkert 301689SN/A */ 311689SN/A 322064SN/A#include <map> 331060SN/A#include <stack> 341060SN/A#include <string> 352292SN/A 361717SN/A#include "arch/generic/linux/threadinfo.hh" 374762Snate@binkert.org#include "arch/alpha/kernel_stats.hh" 384762Snate@binkert.org#include "arch/alpha/osfpal.hh" 391060SN/A#include "base/trace.hh" 401061SN/A#include "cpu/thread_context.hh" 412292SN/A#include "debug/Context.hh" 422292SN/A#include "kern/tru64/tru64_syscalls.hh" 432292SN/A#include "sim/system.hh" 442292SN/A 452326SN/Ausing namespace std; 461060SN/Ausing namespace Stats; 472292SN/A 482292SN/Anamespace AlphaISA { 492292SN/Anamespace Kernel { 502292SN/A 512292SN/Aconst char *modestr[] = { "kernel", "user", "idle" }; 522292SN/A 532292SN/AStatistics::Statistics(System *system) 542326SN/A : ::Kernel::Statistics(system), 552292SN/A idleProcess((Addr)-1), themode(kernel), lastModeTick(0) 562292SN/A{ 572292SN/A} 582292SN/A 592292SN/Avoid 602292SN/AStatistics::regStats(const string &_name) 612292SN/A{ 622292SN/A ::Kernel::Statistics::regStats(_name); 634873Sstever@eecs.umich.edu 642292SN/A _callpal 652292SN/A .init(256) 662292SN/A .name(name() + ".callpal") 674329Sktlim@umich.edu .desc("number of callpals executed") 684329Sktlim@umich.edu .flags(total | pdf | nozero | nonan) 694329Sktlim@umich.edu ; 704329Sktlim@umich.edu 714329Sktlim@umich.edu for (int i = 0; i < PAL::NumCodes; ++i) { 722292SN/A const char *str = PAL::name(i); 732292SN/A if (str) 742292SN/A _callpal.subname(i, str); 752292SN/A } 762292SN/A 772292SN/A _hwrei 782292SN/A .name(name() + ".inst.hwrei") 792292SN/A .desc("number of hwrei instructions executed") 802307SN/A ; 812307SN/A 822292SN/A _mode 831060SN/A .init(cpu_mode_num) 841060SN/A .name(name() + ".mode_switch") 851060SN/A .desc("number of protection mode switches") 861060SN/A ; 871060SN/A 881060SN/A for (int i = 0; i < cpu_mode_num; ++i) 892326SN/A _mode.subname(i, modestr[i]); 901060SN/A 911060SN/A _modeGood 921060SN/A .init(cpu_mode_num) 931060SN/A .name(name() + ".mode_good") 942292SN/A ; 952292SN/A 962292SN/A for (int i = 0; i < cpu_mode_num; ++i) 972292SN/A _modeGood.subname(i, modestr[i]); 981060SN/A 991060SN/A _modeFraction 1002307SN/A .name(name() + ".mode_switch_good") 1012292SN/A .desc("fraction of useful protection mode switches") 1022980Sgblack@eecs.umich.edu .flags(total) 1032292SN/A ; 1042292SN/A 1052292SN/A for (int i = 0; i < cpu_mode_num; ++i) 1062292SN/A _modeFraction.subname(i, modestr[i]); 1072292SN/A 1082292SN/A _modeFraction = _modeGood / _mode; 1092292SN/A 1102292SN/A _modeTicks 1112292SN/A .init(cpu_mode_num) 1122292SN/A .name(name() + ".mode_ticks") 1132292SN/A .desc("number of ticks spent at the given mode") 1142292SN/A .flags(pdf) 1152292SN/A ; 1162292SN/A for (int i = 0; i < cpu_mode_num; ++i) 1172292SN/A _modeTicks.subname(i, modestr[i]); 1182292SN/A 1192292SN/A _swap_context 1202292SN/A .name(name() + ".swap_context") 1212292SN/A .desc("number of times the context was actually changed") 1222292SN/A ; 1232292SN/A} 1242292SN/A 1252292SN/Avoid 1262292SN/AStatistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) 1272292SN/A{ 1282831Sksewell@umich.edu assert(themode == kernel); 1292292SN/A idleProcess = idlepcbb; 1302292SN/A themode = idle; 1312292SN/A changeMode(themode, tc); 1322292SN/A} 1332292SN/A 1342292SN/Avoid 1352292SN/AStatistics::changeMode(cpu_mode newmode, ThreadContext *tc) 1362292SN/A{ 1372292SN/A _mode[newmode]++; 1382292SN/A 1392292SN/A if (newmode == themode) 1402292SN/A return; 1412292SN/A 1422831Sksewell@umich.edu DPRINTF(Context, "old mode=%s new mode=%s pid=%d\n", 1432292SN/A modestr[themode], modestr[newmode], 1442292SN/A Linux::ThreadInfo(tc).curTaskPID()); 1452292SN/A 1462292SN/A _modeGood[newmode]++; 1472292SN/A _modeTicks[themode] += curTick() - lastModeTick; 1482292SN/A 1492292SN/A lastModeTick = curTick(); 1502292SN/A themode = newmode; 1512292SN/A} 1522292SN/A 1532326SN/Avoid 1542348SN/AStatistics::mode(cpu_mode newmode, ThreadContext *tc) 1552326SN/A{ 1562326SN/A Addr pcbb = tc->readMiscRegNoEffect(IPR_PALtemp23); 1572348SN/A 1582292SN/A if (newmode == kernel && pcbb == idleProcess) 1592292SN/A newmode = idle; 1602292SN/A 1612292SN/A changeMode(newmode, tc); 1622292SN/A} 1632292SN/A 1642292SN/Avoid 1651060SN/AStatistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) 1661060SN/A{ 1671061SN/A assert(themode != user); 1681060SN/A 1691062SN/A _swap_context++; 1701062SN/A changeMode(newpcbb == idleProcess ? idle : kernel, tc); 1712301SN/A 1721062SN/A DPRINTF(Context, "Context Switch old pid=%d new pid=%d\n", 1731062SN/A Linux::ThreadInfo(tc, oldpcbb).curTaskPID(), 1741062SN/A Linux::ThreadInfo(tc, newpcbb).curTaskPID()); 1751062SN/A} 1761062SN/A 1771062SN/Avoid 1781062SN/AStatistics::callpal(int code, ThreadContext *tc) 1791062SN/A{ 1801062SN/A if (!PAL::name(code)) 1811062SN/A return; 1822301SN/A 1832301SN/A _callpal[code]++; 1842301SN/A 1852301SN/A switch (code) { 1861062SN/A case PAL::callsys: { 1871062SN/A int number = tc->readIntReg(0); 1881062SN/A if (SystemCalls<Tru64>::validSyscallNumber(number)) { 1891062SN/A int cvtnum = SystemCalls<Tru64>::convert(number); 1901062SN/A _syscall[cvtnum]++; 1911062SN/A } 1921062SN/A } break; 1931062SN/A } 1941062SN/A} 1951062SN/A 1961062SN/Avoid 1971062SN/AStatistics::serialize(CheckpointOut &cp) const 1981062SN/A{ 1991062SN/A ::Kernel::Statistics::serialize(cp); 2001062SN/A int exemode = themode; 2011062SN/A SERIALIZE_SCALAR(exemode); 2021062SN/A SERIALIZE_SCALAR(idleProcess); 2031062SN/A SERIALIZE_SCALAR(lastModeTick); 2041062SN/A} 2051062SN/A 2061062SN/Avoid 2071062SN/AStatistics::unserialize(CheckpointIn &cp) 2081062SN/A{ 2091062SN/A ::Kernel::Statistics::unserialize(cp); 2101062SN/A int exemode; 2111062SN/A UNSERIALIZE_SCALAR(exemode); 2121062SN/A UNSERIALIZE_SCALAR(idleProcess); 2131062SN/A UNSERIALIZE_SCALAR(lastModeTick); 2141062SN/A themode = (cpu_mode)exemode; 2151062SN/A} 2161062SN/A 2171062SN/A} // namespace Kernel 2181062SN/A} // namespace AlphaISA 2191062SN/A