kernel_stats.cc revision 4172
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Lisa Hsu 29 * Nathan Binkert 30 */ 31 32#include <map> 33#include <stack> 34#include <string> 35 36#include "arch/alpha/kernel_stats.hh" 37#include "arch/alpha/osfpal.hh" 38#include "base/trace.hh" 39#include "cpu/thread_context.hh" 40#include "kern/tru64/tru64_syscalls.hh" 41#include "sim/system.hh" 42 43using namespace std; 44using namespace Stats; 45 46namespace AlphaISA { 47namespace Kernel { 48 49const char *modestr[] = { "kernel", "user", "idle" }; 50 51Statistics::Statistics(System *system) 52 : ::Kernel::Statistics(system), 53 idleProcess((Addr)-1), themode(kernel), lastModeTick(0) 54{ 55} 56 57void 58Statistics::regStats(const string &_name) 59{ 60 ::Kernel::Statistics::regStats(_name); 61 62 _callpal 63 .init(256) 64 .name(name() + ".callpal") 65 .desc("number of callpals executed") 66 .flags(total | pdf | nozero | nonan) 67 ; 68 69 for (int i = 0; i < PAL::NumCodes; ++i) { 70 const char *str = PAL::name(i); 71 if (str) 72 _callpal.subname(i, str); 73 } 74 75 _hwrei 76 .name(name() + ".inst.hwrei") 77 .desc("number of hwrei instructions executed") 78 ; 79 80 _mode 81 .init(cpu_mode_num) 82 .name(name() + ".mode_switch") 83 .desc("number of protection mode switches") 84 ; 85 86 for (int i = 0; i < cpu_mode_num; ++i) 87 _mode.subname(i, modestr[i]); 88 89 _modeGood 90 .init(cpu_mode_num) 91 .name(name() + ".mode_good") 92 ; 93 94 for (int i = 0; i < cpu_mode_num; ++i) 95 _modeGood.subname(i, modestr[i]); 96 97 _modeFraction 98 .name(name() + ".mode_switch_good") 99 .desc("fraction of useful protection mode switches") 100 .flags(total) 101 ; 102 103 for (int i = 0; i < cpu_mode_num; ++i) 104 _modeFraction.subname(i, modestr[i]); 105 106 _modeFraction = _modeGood / _mode; 107 108 _modeTicks 109 .init(cpu_mode_num) 110 .name(name() + ".mode_ticks") 111 .desc("number of ticks spent at the given mode") 112 .flags(pdf) 113 ; 114 for (int i = 0; i < cpu_mode_num; ++i) 115 _modeTicks.subname(i, modestr[i]); 116 117 _swap_context 118 .name(name() + ".swap_context") 119 .desc("number of times the context was actually changed") 120 ; 121} 122 123void 124Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) 125{ 126 assert(themode == kernel); 127 idleProcess = idlepcbb; 128 themode = idle; 129 changeMode(themode, tc); 130} 131 132void 133Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) 134{ 135 _mode[newmode]++; 136 137 if (newmode == themode) 138 return; 139 140 DPRINTF(Context, "old mode=%-8s new mode=%-8s\n", 141 modestr[themode], modestr[newmode]); 142 143 _modeGood[newmode]++; 144 _modeTicks[themode] += curTick - lastModeTick; 145 146 lastModeTick = curTick; 147 themode = newmode; 148} 149 150void 151Statistics::mode(cpu_mode newmode, ThreadContext *tc) 152{ 153 Addr pcbb = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23); 154 155 if (newmode == kernel && pcbb == idleProcess) 156 newmode = idle; 157 158 changeMode(newmode, tc); 159} 160 161void 162Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) 163{ 164 assert(themode != user); 165 166 _swap_context++; 167 changeMode(newpcbb == idleProcess ? idle : kernel, tc); 168} 169 170void 171Statistics::callpal(int code, ThreadContext *tc) 172{ 173 if (!PAL::name(code)) 174 return; 175 176 _callpal[code]++; 177 178 switch (code) { 179 case PAL::callsys: { 180 int number = tc->readIntReg(0); 181 if (SystemCalls<Tru64>::validSyscallNumber(number)) { 182 int cvtnum = SystemCalls<Tru64>::convert(number); 183 _syscall[cvtnum]++; 184 } 185 } break; 186 } 187} 188 189void 190Statistics::serialize(ostream &os) 191{ 192 ::Kernel::Statistics::serialize(os); 193 int exemode = themode; 194 SERIALIZE_SCALAR(exemode); 195 SERIALIZE_SCALAR(idleProcess); 196 SERIALIZE_SCALAR(lastModeTick); 197} 198 199void 200Statistics::unserialize(Checkpoint *cp, const string §ion) 201{ 202 ::Kernel::Statistics::unserialize(cp, section); 203 int exemode; 204 UNSERIALIZE_SCALAR(exemode); 205 UNSERIALIZE_SCALAR(idleProcess); 206 UNSERIALIZE_SCALAR(lastModeTick); 207 themode = (cpu_mode)exemode; 208} 209 210} /* end namespace AlphaISA::Kernel */ 211} /* end namespace AlphaISA */ 212