kernel_stats.cc revision 5191
12405SN/A/* 22405SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 32405SN/A * All rights reserved. 42405SN/A * 52405SN/A * Redistribution and use in source and binary forms, with or without 62405SN/A * modification, are permitted provided that the following conditions are 72405SN/A * met: redistributions of source code must retain the above copyright 82405SN/A * notice, this list of conditions and the following disclaimer; 92405SN/A * redistributions in binary form must reproduce the above copyright 102405SN/A * notice, this list of conditions and the following disclaimer in the 112405SN/A * documentation and/or other materials provided with the distribution; 122405SN/A * neither the name of the copyright holders nor the names of its 132405SN/A * contributors may be used to endorse or promote products derived from 142405SN/A * this software without specific prior written permission. 152405SN/A * 162405SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172405SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182405SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192405SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202405SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212405SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222405SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232405SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242405SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252405SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262405SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Lisa Hsu 292405SN/A * Nathan Binkert 302405SN/A */ 312405SN/A 322982Sstever@eecs.umich.edu#include <map> 332982Sstever@eecs.umich.edu#include <stack> 342405SN/A#include <string> 353918Ssaidi@eecs.umich.edu 362405SN/A#include "arch/alpha/linux/threadinfo.hh" 372405SN/A#include "arch/alpha/kernel_stats.hh" 382642Sstever@eecs.umich.edu#include "arch/alpha/osfpal.hh" 394190Ssaidi@eecs.umich.edu#include "base/trace.hh" 402405SN/A#include "cpu/thread_context.hh" 412405SN/A#include "kern/tru64/tru64_syscalls.hh" 422405SN/A#include "sim/system.hh" 432642Sstever@eecs.umich.edu 442642Sstever@eecs.umich.eduusing namespace std; 452642Sstever@eecs.umich.eduusing namespace Stats; 462642Sstever@eecs.umich.edu 472642Sstever@eecs.umich.edunamespace AlphaISA { 482642Sstever@eecs.umich.edunamespace Kernel { 492642Sstever@eecs.umich.edu 504190Ssaidi@eecs.umich.educonst char *modestr[] = { "kernel", "user", "idle" }; 514190Ssaidi@eecs.umich.edu 524190Ssaidi@eecs.umich.eduStatistics::Statistics(System *system) 534190Ssaidi@eecs.umich.edu : ::Kernel::Statistics(system), 544190Ssaidi@eecs.umich.edu idleProcess((Addr)-1), themode(kernel), lastModeTick(0) 554190Ssaidi@eecs.umich.edu{ 564190Ssaidi@eecs.umich.edu} 574190Ssaidi@eecs.umich.edu 584190Ssaidi@eecs.umich.eduvoid 594022Sstever@eecs.umich.eduStatistics::regStats(const string &_name) 602405SN/A{ 612663Sstever@eecs.umich.edu ::Kernel::Statistics::regStats(_name); 622641Sstever@eecs.umich.edu 632405SN/A _callpal 642406SN/A .init(256) 652406SN/A .name(name() + ".callpal") 662663Sstever@eecs.umich.edu .desc("number of callpals executed") 672641Sstever@eecs.umich.edu .flags(total | pdf | nozero | nonan) 682566SN/A ; 692630SN/A 702405SN/A for (int i = 0; i < PAL::NumCodes; ++i) { 712405SN/A const char *str = PAL::name(i); 722405SN/A if (str) 732405SN/A _callpal.subname(i, str); 742405SN/A } 752461SN/A 762405SN/A _hwrei 774022Sstever@eecs.umich.edu .name(name() + ".inst.hwrei") 782405SN/A .desc("number of hwrei instructions executed") 792405SN/A ; 802405SN/A 812461SN/A _mode 822405SN/A .init(cpu_mode_num) 834022Sstever@eecs.umich.edu .name(name() + ".mode_switch") 842405SN/A .desc("number of protection mode switches") 852405SN/A ; 862420SN/A 872461SN/A for (int i = 0; i < cpu_mode_num; ++i) 882420SN/A _mode.subname(i, modestr[i]); 892420SN/A 902420SN/A _modeGood 912420SN/A .init(cpu_mode_num) 923918Ssaidi@eecs.umich.edu .name(name() + ".mode_good") 934022Sstever@eecs.umich.edu ; 942421SN/A 952548SN/A for (int i = 0; i < cpu_mode_num; ++i) 962420SN/A _modeGood.subname(i, modestr[i]); 97 98 _modeFraction 99 .name(name() + ".mode_switch_good") 100 .desc("fraction of useful protection mode switches") 101 .flags(total) 102 ; 103 104 for (int i = 0; i < cpu_mode_num; ++i) 105 _modeFraction.subname(i, modestr[i]); 106 107 _modeFraction = _modeGood / _mode; 108 109 _modeTicks 110 .init(cpu_mode_num) 111 .name(name() + ".mode_ticks") 112 .desc("number of ticks spent at the given mode") 113 .flags(pdf) 114 ; 115 for (int i = 0; i < cpu_mode_num; ++i) 116 _modeTicks.subname(i, modestr[i]); 117 118 _swap_context 119 .name(name() + ".swap_context") 120 .desc("number of times the context was actually changed") 121 ; 122} 123 124void 125Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) 126{ 127 assert(themode == kernel); 128 idleProcess = idlepcbb; 129 themode = idle; 130 changeMode(themode, tc); 131} 132 133void 134Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) 135{ 136 _mode[newmode]++; 137 138 if (newmode == themode) 139 return; 140 141 DPRINTF(Context, "old mode=%s new mode=%s pid=%d\n", 142 modestr[themode], modestr[newmode], 143 Linux::ThreadInfo(tc).curTaskPID()); 144 145 _modeGood[newmode]++; 146 _modeTicks[themode] += curTick - lastModeTick; 147 148 lastModeTick = curTick; 149 themode = newmode; 150} 151 152void 153Statistics::mode(cpu_mode newmode, ThreadContext *tc) 154{ 155 Addr pcbb = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23); 156 157 if (newmode == kernel && pcbb == idleProcess) 158 newmode = idle; 159 160 changeMode(newmode, tc); 161} 162 163void 164Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) 165{ 166 assert(themode != user); 167 168 _swap_context++; 169 changeMode(newpcbb == idleProcess ? idle : kernel, tc); 170 171 DPRINTF(Context, "Context Switch old pid=%d new pid=%d\n", 172 Linux::ThreadInfo(tc, oldpcbb).curTaskPID(), 173 Linux::ThreadInfo(tc, newpcbb).curTaskPID()); 174} 175 176void 177Statistics::callpal(int code, ThreadContext *tc) 178{ 179 if (!PAL::name(code)) 180 return; 181 182 _callpal[code]++; 183 184 switch (code) { 185 case PAL::callsys: { 186 int number = tc->readIntReg(0); 187 if (SystemCalls<Tru64>::validSyscallNumber(number)) { 188 int cvtnum = SystemCalls<Tru64>::convert(number); 189 _syscall[cvtnum]++; 190 } 191 } break; 192 } 193} 194 195void 196Statistics::serialize(ostream &os) 197{ 198 ::Kernel::Statistics::serialize(os); 199 int exemode = themode; 200 SERIALIZE_SCALAR(exemode); 201 SERIALIZE_SCALAR(idleProcess); 202 SERIALIZE_SCALAR(lastModeTick); 203} 204 205void 206Statistics::unserialize(Checkpoint *cp, const string §ion) 207{ 208 ::Kernel::Statistics::unserialize(cp, section); 209 int exemode; 210 UNSERIALIZE_SCALAR(exemode); 211 UNSERIALIZE_SCALAR(idleProcess); 212 UNSERIALIZE_SCALAR(lastModeTick); 213 themode = (cpu_mode)exemode; 214} 215 216} /* end namespace AlphaISA::Kernel */ 217} /* end namespace AlphaISA */ 218