kernel_stats.cc revision 10905
12SN/A/* 21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/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 302SN/A */ 312SN/A 322SN/A#include <map> 332SN/A#include <stack> 342SN/A#include <string> 357678Sgblack@eecs.umich.edu 368229Snate@binkert.org#include "arch/generic/linux/threadinfo.hh" 372147SN/A#include "arch/alpha/kernel_stats.hh" 382147SN/A#include "arch/alpha/osfpal.hh" 392680Sktlim@umich.edu#include "base/trace.hh" 402132SN/A#include "cpu/thread_context.hh" 412147SN/A#include "debug/Context.hh" 425999Snate@binkert.org#include "kern/tru64/tru64_syscalls.hh" 432147SN/A#include "sim/system.hh" 4410474Sandreas.hansson@arm.com 452090SN/Ausing namespace std; 462147SN/Ausing namespace Stats; 474695Sgblack@eecs.umich.edu 4810417Sandreas.hansson@arm.comnamespace AlphaISA { 4910417Sandreas.hansson@arm.comnamespace Kernel { 5013475Snikos.nikoleris@arm.com 5113475Snikos.nikoleris@arm.comconst char *modestr[] = { "kernel", "user", "idle" }; 522SN/A 532SN/AStatistics::Statistics(System *system) 542612SN/A : ::Kernel::Statistics(system), 552612SN/A idleProcess((Addr)-1), themode(kernel), lastModeTick(0) 562612SN/A{ 572612SN/A} 582612SN/A 592612SN/Avoid 602612SN/AStatistics::regStats(const string &_name) 612612SN/A{ 622612SN/A ::Kernel::Statistics::regStats(_name); 6311876Sbrandon.potter@amd.com 6410417Sandreas.hansson@arm.com _callpal 6510417Sandreas.hansson@arm.com .init(256) 662612SN/A .name(name() + ".callpal") 672612SN/A .desc("number of callpals executed") 688545Ssaidi@eecs.umich.edu .flags(total | pdf | nozero | nonan) 698545Ssaidi@eecs.umich.edu ; 708545Ssaidi@eecs.umich.edu 7111876Sbrandon.potter@amd.com for (int i = 0; i < PAL::NumCodes; ++i) { 728545Ssaidi@eecs.umich.edu const char *str = PAL::name(i); 7310417Sandreas.hansson@arm.com if (str) 7410417Sandreas.hansson@arm.com _callpal.subname(i, str); 758545Ssaidi@eecs.umich.edu } 768545Ssaidi@eecs.umich.edu 7711877Sbrandon.potter@amd.com _hwrei 7811877Sbrandon.potter@amd.com .name(name() + ".inst.hwrei") 7911877Sbrandon.potter@amd.com .desc("number of hwrei instructions executed") 8011877Sbrandon.potter@amd.com ; 8111877Sbrandon.potter@amd.com 8211877Sbrandon.potter@amd.com _mode 8311877Sbrandon.potter@amd.com .init(cpu_mode_num) 8411877Sbrandon.potter@amd.com .name(name() + ".mode_switch") 8511877Sbrandon.potter@amd.com .desc("number of protection mode switches") 8611877Sbrandon.potter@amd.com ; 8711877Sbrandon.potter@amd.com 8811877Sbrandon.potter@amd.com for (int i = 0; i < cpu_mode_num; ++i) 8911877Sbrandon.potter@amd.com _mode.subname(i, modestr[i]); 9011877Sbrandon.potter@amd.com 9111877Sbrandon.potter@amd.com _modeGood 9211877Sbrandon.potter@amd.com .init(cpu_mode_num) 935004Sgblack@eecs.umich.edu .name(name() + ".mode_good") 944183Sgblack@eecs.umich.edu ; 954183Sgblack@eecs.umich.edu 964183Sgblack@eecs.umich.edu for (int i = 0; i < cpu_mode_num; ++i) 974183Sgblack@eecs.umich.edu _modeGood.subname(i, modestr[i]); 9811876Sbrandon.potter@amd.com 995004Sgblack@eecs.umich.edu _modeFraction 10010417Sandreas.hansson@arm.com .name(name() + ".mode_switch_good") 10110417Sandreas.hansson@arm.com .desc("fraction of useful protection mode switches") 1025004Sgblack@eecs.umich.edu .flags(total) 1035004Sgblack@eecs.umich.edu ; 1045004Sgblack@eecs.umich.edu 1055004Sgblack@eecs.umich.edu for (int i = 0; i < cpu_mode_num; ++i) 1065004Sgblack@eecs.umich.edu _modeFraction.subname(i, modestr[i]); 1075004Sgblack@eecs.umich.edu 1085004Sgblack@eecs.umich.edu _modeFraction = _modeGood / _mode; 10911876Sbrandon.potter@amd.com 1105004Sgblack@eecs.umich.edu _modeTicks 11110417Sandreas.hansson@arm.com .init(cpu_mode_num) 11210417Sandreas.hansson@arm.com .name(name() + ".mode_ticks") 1134183Sgblack@eecs.umich.edu .desc("number of ticks spent at the given mode") 1144183Sgblack@eecs.umich.edu .flags(pdf) 1152SN/A ; 116 for (int i = 0; i < cpu_mode_num; ++i) 117 _modeTicks.subname(i, modestr[i]); 118 119 _swap_context 120 .name(name() + ".swap_context") 121 .desc("number of times the context was actually changed") 122 ; 123} 124 125void 126Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) 127{ 128 assert(themode == kernel); 129 idleProcess = idlepcbb; 130 themode = idle; 131 changeMode(themode, tc); 132} 133 134void 135Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) 136{ 137 _mode[newmode]++; 138 139 if (newmode == themode) 140 return; 141 142 DPRINTF(Context, "old mode=%s new mode=%s pid=%d\n", 143 modestr[themode], modestr[newmode], 144 Linux::ThreadInfo(tc).curTaskPID()); 145 146 _modeGood[newmode]++; 147 _modeTicks[themode] += curTick() - lastModeTick; 148 149 lastModeTick = curTick(); 150 themode = newmode; 151} 152 153void 154Statistics::mode(cpu_mode newmode, ThreadContext *tc) 155{ 156 Addr pcbb = tc->readMiscRegNoEffect(IPR_PALtemp23); 157 158 if (newmode == kernel && pcbb == idleProcess) 159 newmode = idle; 160 161 changeMode(newmode, tc); 162} 163 164void 165Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) 166{ 167 assert(themode != user); 168 169 _swap_context++; 170 changeMode(newpcbb == idleProcess ? idle : kernel, tc); 171 172 DPRINTF(Context, "Context Switch old pid=%d new pid=%d\n", 173 Linux::ThreadInfo(tc, oldpcbb).curTaskPID(), 174 Linux::ThreadInfo(tc, newpcbb).curTaskPID()); 175} 176 177void 178Statistics::callpal(int code, ThreadContext *tc) 179{ 180 if (!PAL::name(code)) 181 return; 182 183 _callpal[code]++; 184 185 switch (code) { 186 case PAL::callsys: { 187 int number = tc->readIntReg(0); 188 if (SystemCalls<Tru64>::validSyscallNumber(number)) { 189 int cvtnum = SystemCalls<Tru64>::convert(number); 190 _syscall[cvtnum]++; 191 } 192 } break; 193 } 194} 195 196void 197Statistics::serialize(CheckpointOut &cp) const 198{ 199 ::Kernel::Statistics::serialize(cp); 200 int exemode = themode; 201 SERIALIZE_SCALAR(exemode); 202 SERIALIZE_SCALAR(idleProcess); 203 SERIALIZE_SCALAR(lastModeTick); 204} 205 206void 207Statistics::unserialize(CheckpointIn &cp) 208{ 209 ::Kernel::Statistics::unserialize(cp); 210 int exemode; 211 UNSERIALIZE_SCALAR(exemode); 212 UNSERIALIZE_SCALAR(idleProcess); 213 UNSERIALIZE_SCALAR(lastModeTick); 214 themode = (cpu_mode)exemode; 215} 216 217} // namespace Kernel 218} // namespace AlphaISA 219