kernel_stats.cc revision 12181
111986Sandreas.sandberg@arm.com/* 211986Sandreas.sandberg@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 311986Sandreas.sandberg@arm.com * All rights reserved. 411986Sandreas.sandberg@arm.com * 511986Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 611986Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 711986Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 811986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 911986Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1011986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 1111986Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 1211986Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 1311986Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 1411986Sandreas.sandberg@arm.com * this software without specific prior written permission. 1511986Sandreas.sandberg@arm.com * 1611986Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711986Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811986Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911986Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011986Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111986Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211986Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311986Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411986Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511986Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611986Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711986Sandreas.sandberg@arm.com * 2811986Sandreas.sandberg@arm.com * Authors: Lisa Hsu 2911986Sandreas.sandberg@arm.com * Nathan Binkert 3011986Sandreas.sandberg@arm.com */ 3111986Sandreas.sandberg@arm.com 3211986Sandreas.sandberg@arm.com#include "arch/alpha/kernel_stats.hh" 3311986Sandreas.sandberg@arm.com 3411986Sandreas.sandberg@arm.com#include <map> 3511986Sandreas.sandberg@arm.com#include <stack> 3611986Sandreas.sandberg@arm.com#include <string> 3711986Sandreas.sandberg@arm.com 3811986Sandreas.sandberg@arm.com#include "arch/alpha/osfpal.hh" 3911986Sandreas.sandberg@arm.com#include "arch/generic/linux/threadinfo.hh" 4011986Sandreas.sandberg@arm.com#include "base/trace.hh" 4111986Sandreas.sandberg@arm.com#include "cpu/thread_context.hh" 4211986Sandreas.sandberg@arm.com#include "debug/Context.hh" 4311986Sandreas.sandberg@arm.com#include "sim/system.hh" 4411986Sandreas.sandberg@arm.com 4511986Sandreas.sandberg@arm.comusing namespace std; 4611986Sandreas.sandberg@arm.comusing namespace Stats; 4711986Sandreas.sandberg@arm.com 4811986Sandreas.sandberg@arm.comnamespace AlphaISA { 4911986Sandreas.sandberg@arm.comnamespace Kernel { 5011986Sandreas.sandberg@arm.com 5111986Sandreas.sandberg@arm.comconst char *modestr[] = { "kernel", "user", "idle" }; 5211986Sandreas.sandberg@arm.com 5311986Sandreas.sandberg@arm.comStatistics::Statistics() 5411986Sandreas.sandberg@arm.com : ::Kernel::Statistics(), 5511986Sandreas.sandberg@arm.com idleProcess((Addr)-1), themode(kernel), lastModeTick(0) 5611986Sandreas.sandberg@arm.com{ 5711986Sandreas.sandberg@arm.com} 5811986Sandreas.sandberg@arm.com 5911986Sandreas.sandberg@arm.comvoid 6011986Sandreas.sandberg@arm.comStatistics::regStats(const string &_name) 6111986Sandreas.sandberg@arm.com{ 6211986Sandreas.sandberg@arm.com ::Kernel::Statistics::regStats(_name); 6311986Sandreas.sandberg@arm.com 6411986Sandreas.sandberg@arm.com _callpal 6511986Sandreas.sandberg@arm.com .init(256) 6611986Sandreas.sandberg@arm.com .name(name() + ".callpal") 6711986Sandreas.sandberg@arm.com .desc("number of callpals executed") 6811986Sandreas.sandberg@arm.com .flags(total | pdf | nozero | nonan) 6911986Sandreas.sandberg@arm.com ; 7011986Sandreas.sandberg@arm.com 7111986Sandreas.sandberg@arm.com for (int i = 0; i < PAL::NumCodes; ++i) { 7211986Sandreas.sandberg@arm.com const char *str = PAL::name(i); 7311986Sandreas.sandberg@arm.com if (str) 7411986Sandreas.sandberg@arm.com _callpal.subname(i, str); 7511986Sandreas.sandberg@arm.com } 7611986Sandreas.sandberg@arm.com 7711986Sandreas.sandberg@arm.com _hwrei 7811986Sandreas.sandberg@arm.com .name(name() + ".inst.hwrei") 7911986Sandreas.sandberg@arm.com .desc("number of hwrei instructions executed") 8011986Sandreas.sandberg@arm.com ; 8111986Sandreas.sandberg@arm.com 8211986Sandreas.sandberg@arm.com _mode 8311986Sandreas.sandberg@arm.com .init(cpu_mode_num) 8411986Sandreas.sandberg@arm.com .name(name() + ".mode_switch") 8511986Sandreas.sandberg@arm.com .desc("number of protection mode switches") 8611986Sandreas.sandberg@arm.com ; 8711986Sandreas.sandberg@arm.com 8811986Sandreas.sandberg@arm.com for (int i = 0; i < cpu_mode_num; ++i) 8911986Sandreas.sandberg@arm.com _mode.subname(i, modestr[i]); 9011986Sandreas.sandberg@arm.com 9111986Sandreas.sandberg@arm.com _modeGood 9211986Sandreas.sandberg@arm.com .init(cpu_mode_num) 9311986Sandreas.sandberg@arm.com .name(name() + ".mode_good") 9411986Sandreas.sandberg@arm.com ; 9511986Sandreas.sandberg@arm.com 9611986Sandreas.sandberg@arm.com for (int i = 0; i < cpu_mode_num; ++i) 9711986Sandreas.sandberg@arm.com _modeGood.subname(i, modestr[i]); 9811986Sandreas.sandberg@arm.com 9911986Sandreas.sandberg@arm.com _modeFraction 10011986Sandreas.sandberg@arm.com .name(name() + ".mode_switch_good") 10111986Sandreas.sandberg@arm.com .desc("fraction of useful protection mode switches") 10211986Sandreas.sandberg@arm.com .flags(total) 10311986Sandreas.sandberg@arm.com ; 10411986Sandreas.sandberg@arm.com 10511986Sandreas.sandberg@arm.com for (int i = 0; i < cpu_mode_num; ++i) 10611986Sandreas.sandberg@arm.com _modeFraction.subname(i, modestr[i]); 10711986Sandreas.sandberg@arm.com 10811986Sandreas.sandberg@arm.com _modeFraction = _modeGood / _mode; 10911986Sandreas.sandberg@arm.com 11011986Sandreas.sandberg@arm.com _modeTicks 11111986Sandreas.sandberg@arm.com .init(cpu_mode_num) 11211986Sandreas.sandberg@arm.com .name(name() + ".mode_ticks") 11311986Sandreas.sandberg@arm.com .desc("number of ticks spent at the given mode") 11411986Sandreas.sandberg@arm.com .flags(pdf) 11511986Sandreas.sandberg@arm.com ; 11611986Sandreas.sandberg@arm.com for (int i = 0; i < cpu_mode_num; ++i) 11711986Sandreas.sandberg@arm.com _modeTicks.subname(i, modestr[i]); 11811986Sandreas.sandberg@arm.com 11911986Sandreas.sandberg@arm.com _swap_context 12011986Sandreas.sandberg@arm.com .name(name() + ".swap_context") 12111986Sandreas.sandberg@arm.com .desc("number of times the context was actually changed") 12211986Sandreas.sandberg@arm.com ; 12311986Sandreas.sandberg@arm.com} 12411986Sandreas.sandberg@arm.com 12511986Sandreas.sandberg@arm.comvoid 12611986Sandreas.sandberg@arm.comStatistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) 12711986Sandreas.sandberg@arm.com{ 12811986Sandreas.sandberg@arm.com assert(themode == kernel); 12911986Sandreas.sandberg@arm.com idleProcess = idlepcbb; 13011986Sandreas.sandberg@arm.com themode = idle; 13111986Sandreas.sandberg@arm.com changeMode(themode, tc); 13211986Sandreas.sandberg@arm.com} 13311986Sandreas.sandberg@arm.com 13411986Sandreas.sandberg@arm.comvoid 13511986Sandreas.sandberg@arm.comStatistics::changeMode(cpu_mode newmode, ThreadContext *tc) 13611986Sandreas.sandberg@arm.com{ 13711986Sandreas.sandberg@arm.com _mode[newmode]++; 13811986Sandreas.sandberg@arm.com 13911986Sandreas.sandberg@arm.com if (newmode == themode) 14011986Sandreas.sandberg@arm.com return; 14111986Sandreas.sandberg@arm.com 14211986Sandreas.sandberg@arm.com DPRINTF(Context, "old mode=%s new mode=%s pid=%d\n", 14311986Sandreas.sandberg@arm.com modestr[themode], modestr[newmode], 14411986Sandreas.sandberg@arm.com Linux::ThreadInfo(tc).curTaskPID()); 14511986Sandreas.sandberg@arm.com 14611986Sandreas.sandberg@arm.com _modeGood[newmode]++; 14711986Sandreas.sandberg@arm.com _modeTicks[themode] += curTick() - lastModeTick; 14811986Sandreas.sandberg@arm.com 14911986Sandreas.sandberg@arm.com lastModeTick = curTick(); 15011986Sandreas.sandberg@arm.com themode = newmode; 15111986Sandreas.sandberg@arm.com} 15211986Sandreas.sandberg@arm.com 15311986Sandreas.sandberg@arm.comvoid 15411986Sandreas.sandberg@arm.comStatistics::mode(cpu_mode newmode, ThreadContext *tc) 15511986Sandreas.sandberg@arm.com{ 15611986Sandreas.sandberg@arm.com Addr pcbb = tc->readMiscRegNoEffect(IPR_PALtemp23); 15711986Sandreas.sandberg@arm.com 15811986Sandreas.sandberg@arm.com if (newmode == kernel && pcbb == idleProcess) 15911986Sandreas.sandberg@arm.com newmode = idle; 16011986Sandreas.sandberg@arm.com 16111986Sandreas.sandberg@arm.com changeMode(newmode, tc); 16211986Sandreas.sandberg@arm.com} 16311986Sandreas.sandberg@arm.com 16411986Sandreas.sandberg@arm.comvoid 16511986Sandreas.sandberg@arm.comStatistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) 16611986Sandreas.sandberg@arm.com{ 16711986Sandreas.sandberg@arm.com assert(themode != user); 16811986Sandreas.sandberg@arm.com 16911986Sandreas.sandberg@arm.com _swap_context++; 17011986Sandreas.sandberg@arm.com changeMode(newpcbb == idleProcess ? idle : kernel, tc); 17111986Sandreas.sandberg@arm.com 17211986Sandreas.sandberg@arm.com DPRINTF(Context, "Context Switch old pid=%d new pid=%d\n", 17311986Sandreas.sandberg@arm.com Linux::ThreadInfo(tc, oldpcbb).curTaskPID(), 17411986Sandreas.sandberg@arm.com Linux::ThreadInfo(tc, newpcbb).curTaskPID()); 17511986Sandreas.sandberg@arm.com} 17611986Sandreas.sandberg@arm.com 17711986Sandreas.sandberg@arm.comvoid 17811986Sandreas.sandberg@arm.comStatistics::callpal(int code, ThreadContext *tc) 17911986Sandreas.sandberg@arm.com{ 18011986Sandreas.sandberg@arm.com if (!PAL::name(code)) 18111986Sandreas.sandberg@arm.com return; 18211986Sandreas.sandberg@arm.com 18311986Sandreas.sandberg@arm.com _callpal[code]++; 18411986Sandreas.sandberg@arm.com} 18511986Sandreas.sandberg@arm.com 18611986Sandreas.sandberg@arm.comvoid 18711986Sandreas.sandberg@arm.comStatistics::serialize(CheckpointOut &cp) const 18811986Sandreas.sandberg@arm.com{ 18911986Sandreas.sandberg@arm.com ::Kernel::Statistics::serialize(cp); 19011986Sandreas.sandberg@arm.com int exemode = themode; 19111986Sandreas.sandberg@arm.com SERIALIZE_SCALAR(exemode); 19211986Sandreas.sandberg@arm.com SERIALIZE_SCALAR(idleProcess); 19311986Sandreas.sandberg@arm.com SERIALIZE_SCALAR(lastModeTick); 19411986Sandreas.sandberg@arm.com} 19511986Sandreas.sandberg@arm.com 19611986Sandreas.sandberg@arm.comvoid 19711986Sandreas.sandberg@arm.comStatistics::unserialize(CheckpointIn &cp) 19811986Sandreas.sandberg@arm.com{ 19911986Sandreas.sandberg@arm.com ::Kernel::Statistics::unserialize(cp); 20011986Sandreas.sandberg@arm.com int exemode; 20111986Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(exemode); 20211986Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(idleProcess); 20311986Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(lastModeTick); 20411986Sandreas.sandberg@arm.com themode = (cpu_mode)exemode; 20511986Sandreas.sandberg@arm.com} 20611986Sandreas.sandberg@arm.com 20711986Sandreas.sandberg@arm.com} // namespace Kernel 20811986Sandreas.sandberg@arm.com} // namespace AlphaISA 20911986Sandreas.sandberg@arm.com