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 "arch/alpha/kernel_stats.hh" 33 34#include <map> 35#include <stack> 36#include <string> 37 38#include "arch/alpha/osfpal.hh" 39#include "arch/generic/linux/threadinfo.hh" 40#include "base/trace.hh" 41#include "cpu/thread_context.hh" 42#include "debug/Context.hh" 43#include "sim/system.hh" 44 45using namespace std; 46using namespace Stats; 47 48namespace AlphaISA { 49namespace Kernel { 50 51const char *modestr[] = { "kernel", "user", "idle" }; 52 53Statistics::Statistics() 54 : ::Kernel::Statistics(),
| 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 "arch/alpha/kernel_stats.hh" 33 34#include <map> 35#include <stack> 36#include <string> 37 38#include "arch/alpha/osfpal.hh" 39#include "arch/generic/linux/threadinfo.hh" 40#include "base/trace.hh" 41#include "cpu/thread_context.hh" 42#include "debug/Context.hh" 43#include "sim/system.hh" 44 45using namespace std; 46using namespace Stats; 47 48namespace AlphaISA { 49namespace Kernel { 50 51const char *modestr[] = { "kernel", "user", "idle" }; 52 53Statistics::Statistics() 54 : ::Kernel::Statistics(),
|
55 idleProcess((Addr)-1), themode(kernel), lastModeTick(0)
| 55 idleProcess((Addr)-1), themode(kernel), lastModeTick(0), 56 iplLast(0), iplLastTick(0)
|
56{ 57} 58 59void 60Statistics::regStats(const string &_name) 61{ 62 ::Kernel::Statistics::regStats(_name); 63 64 _callpal 65 .init(256) 66 .name(name() + ".callpal") 67 .desc("number of callpals executed") 68 .flags(total | pdf | nozero | nonan) 69 ; 70 71 for (int i = 0; i < PAL::NumCodes; ++i) { 72 const char *str = PAL::name(i); 73 if (str) 74 _callpal.subname(i, str); 75 } 76 77 _hwrei 78 .name(name() + ".inst.hwrei") 79 .desc("number of hwrei instructions executed") 80 ; 81 82 _mode 83 .init(cpu_mode_num) 84 .name(name() + ".mode_switch") 85 .desc("number of protection mode switches") 86 ; 87 88 for (int i = 0; i < cpu_mode_num; ++i) 89 _mode.subname(i, modestr[i]); 90 91 _modeGood 92 .init(cpu_mode_num) 93 .name(name() + ".mode_good") 94 ; 95 96 for (int i = 0; i < cpu_mode_num; ++i) 97 _modeGood.subname(i, modestr[i]); 98 99 _modeFraction 100 .name(name() + ".mode_switch_good") 101 .desc("fraction of useful protection mode switches") 102 .flags(total) 103 ; 104 105 for (int i = 0; i < cpu_mode_num; ++i) 106 _modeFraction.subname(i, modestr[i]); 107 108 _modeFraction = _modeGood / _mode; 109 110 _modeTicks 111 .init(cpu_mode_num) 112 .name(name() + ".mode_ticks") 113 .desc("number of ticks spent at the given mode") 114 .flags(pdf) 115 ; 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 ;
| 57{ 58} 59 60void 61Statistics::regStats(const string &_name) 62{ 63 ::Kernel::Statistics::regStats(_name); 64 65 _callpal 66 .init(256) 67 .name(name() + ".callpal") 68 .desc("number of callpals executed") 69 .flags(total | pdf | nozero | nonan) 70 ; 71 72 for (int i = 0; i < PAL::NumCodes; ++i) { 73 const char *str = PAL::name(i); 74 if (str) 75 _callpal.subname(i, str); 76 } 77 78 _hwrei 79 .name(name() + ".inst.hwrei") 80 .desc("number of hwrei instructions executed") 81 ; 82 83 _mode 84 .init(cpu_mode_num) 85 .name(name() + ".mode_switch") 86 .desc("number of protection mode switches") 87 ; 88 89 for (int i = 0; i < cpu_mode_num; ++i) 90 _mode.subname(i, modestr[i]); 91 92 _modeGood 93 .init(cpu_mode_num) 94 .name(name() + ".mode_good") 95 ; 96 97 for (int i = 0; i < cpu_mode_num; ++i) 98 _modeGood.subname(i, modestr[i]); 99 100 _modeFraction 101 .name(name() + ".mode_switch_good") 102 .desc("fraction of useful protection mode switches") 103 .flags(total) 104 ; 105 106 for (int i = 0; i < cpu_mode_num; ++i) 107 _modeFraction.subname(i, modestr[i]); 108 109 _modeFraction = _modeGood / _mode; 110 111 _modeTicks 112 .init(cpu_mode_num) 113 .name(name() + ".mode_ticks") 114 .desc("number of ticks spent at the given mode") 115 .flags(pdf) 116 ; 117 for (int i = 0; i < cpu_mode_num; ++i) 118 _modeTicks.subname(i, modestr[i]); 119 120 _swap_context 121 .name(name() + ".swap_context") 122 .desc("number of times the context was actually changed") 123 ;
|
| 124 125 _iplCount 126 .init(32) 127 .name(name() + ".ipl_count") 128 .desc("number of times we switched to this ipl") 129 .flags(total | pdf | nozero | nonan) 130 ; 131 132 _iplGood 133 .init(32) 134 .name(name() + ".ipl_good") 135 .desc("number of times we switched to this ipl from a different ipl") 136 .flags(total | pdf | nozero | nonan) 137 ; 138 139 _iplTicks 140 .init(32) 141 .name(name() + ".ipl_ticks") 142 .desc("number of cycles we spent at this ipl") 143 .flags(total | pdf | nozero | nonan) 144 ; 145 146 _iplUsed 147 .name(name() + ".ipl_used") 148 .desc("fraction of swpipl calls that actually changed the ipl") 149 .flags(total | nozero | nonan) 150 ; 151 152 _iplUsed = _iplGood / _iplCount;
|
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 186void
| 153} 154 155void 156Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) 157{ 158 assert(themode == kernel); 159 idleProcess = idlepcbb; 160 themode = idle; 161 changeMode(themode, tc); 162} 163 164void 165Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) 166{ 167 _mode[newmode]++; 168 169 if (newmode == themode) 170 return; 171 172 DPRINTF(Context, "old mode=%s new mode=%s pid=%d\n", 173 modestr[themode], modestr[newmode], 174 Linux::ThreadInfo(tc).curTaskPID()); 175 176 _modeGood[newmode]++; 177 _modeTicks[themode] += curTick() - lastModeTick; 178 179 lastModeTick = curTick(); 180 themode = newmode; 181} 182 183void 184Statistics::mode(cpu_mode newmode, ThreadContext *tc) 185{ 186 Addr pcbb = tc->readMiscRegNoEffect(IPR_PALtemp23); 187 188 if (newmode == kernel && pcbb == idleProcess) 189 newmode = idle; 190 191 changeMode(newmode, tc); 192} 193 194void 195Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) 196{ 197 assert(themode != user); 198 199 _swap_context++; 200 changeMode(newpcbb == idleProcess ? idle : kernel, tc); 201 202 DPRINTF(Context, "Context Switch old pid=%d new pid=%d\n", 203 Linux::ThreadInfo(tc, oldpcbb).curTaskPID(), 204 Linux::ThreadInfo(tc, newpcbb).curTaskPID()); 205} 206 207void 208Statistics::callpal(int code, ThreadContext *tc) 209{ 210 if (!PAL::name(code)) 211 return; 212 213 _callpal[code]++; 214} 215 216void
|
| 217Statistics::swpipl(int ipl) 218{ 219 assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n"); 220 221 _iplCount[ipl]++; 222 223 if (ipl == iplLast) 224 return; 225 226 _iplGood[ipl]++; 227 _iplTicks[iplLast] += curTick() - iplLastTick; 228 iplLastTick = curTick(); 229 iplLast = ipl; 230} 231 232void
|
187Statistics::serialize(CheckpointOut &cp) const 188{ 189 ::Kernel::Statistics::serialize(cp); 190 int exemode = themode; 191 SERIALIZE_SCALAR(exemode); 192 SERIALIZE_SCALAR(idleProcess); 193 SERIALIZE_SCALAR(lastModeTick);
| 233Statistics::serialize(CheckpointOut &cp) const 234{ 235 ::Kernel::Statistics::serialize(cp); 236 int exemode = themode; 237 SERIALIZE_SCALAR(exemode); 238 SERIALIZE_SCALAR(idleProcess); 239 SERIALIZE_SCALAR(lastModeTick);
|
| 240 SERIALIZE_SCALAR(iplLast); 241 SERIALIZE_SCALAR(iplLastTick);
|
194} 195 196void 197Statistics::unserialize(CheckpointIn &cp) 198{ 199 ::Kernel::Statistics::unserialize(cp); 200 int exemode; 201 UNSERIALIZE_SCALAR(exemode); 202 UNSERIALIZE_SCALAR(idleProcess); 203 UNSERIALIZE_SCALAR(lastModeTick); 204 themode = (cpu_mode)exemode;
| 242} 243 244void 245Statistics::unserialize(CheckpointIn &cp) 246{ 247 ::Kernel::Statistics::unserialize(cp); 248 int exemode; 249 UNSERIALIZE_SCALAR(exemode); 250 UNSERIALIZE_SCALAR(idleProcess); 251 UNSERIALIZE_SCALAR(lastModeTick); 252 themode = (cpu_mode)exemode;
|
| 253 UNSERIALIZE_SCALAR(iplLast); 254 UNSERIALIZE_SCALAR(iplLastTick);
|
205} 206 207} // namespace Kernel 208} // namespace AlphaISA
| 255} 256 257} // namespace Kernel 258} // namespace AlphaISA
|