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