statistics.cc revision 5886
12SN/A/* 21762SN/A * Copyright (c) 2003-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: Nathan Binkert 292SN/A */ 302SN/A 312SN/A#include <iomanip> 32456SN/A#include <fstream> 332SN/A#include <list> 342SN/A#include <map> 352SN/A#include <string> 362SN/A 37148SN/A#include "base/callback.hh" 3856SN/A#include "base/cprintf.hh" 39441SN/A#include "base/hostinfo.hh" 4056SN/A#include "base/misc.hh" 4156SN/A#include "base/statistics.hh" 4256SN/A#include "base/str.hh" 43441SN/A#include "base/time.hh" 44433SN/A#include "base/trace.hh" 45695SN/A#include "base/stats/statdb.hh" 462SN/A 472SN/Ausing namespace std; 482SN/A 49729SN/Anamespace Stats { 50388SN/A 515886Snate@binkert.orgInfo * 525886Snate@binkert.orgInfoAccess::find() const 53388SN/A{ 54695SN/A return Database::find(const_cast<void *>((const void *)this)); 55388SN/A} 56388SN/A 575886Snate@binkert.orgconst Info * 585886Snate@binkert.orggetInfo(const void *stat) 59441SN/A{ 60695SN/A return Database::find(const_cast<void *>(stat)); 61441SN/A} 62441SN/A 63388SN/Avoid 645886Snate@binkert.orgInfoAccess::setInfo(Info *info) 65388SN/A{ 665886Snate@binkert.org Database::regStat(this, info); 67388SN/A} 68388SN/A 69388SN/Avoid 705886Snate@binkert.orgInfoAccess::setInit() 71388SN/A{ 725886Snate@binkert.org info()->flags |= init; 73388SN/A} 74388SN/A 755886Snate@binkert.orgInfo * 765886Snate@binkert.orgInfoAccess::info() 77388SN/A{ 785886Snate@binkert.org Info *info = find(); 795886Snate@binkert.org assert(info); 805886Snate@binkert.org return info; 81388SN/A} 82388SN/A 835886Snate@binkert.orgconst Info * 845886Snate@binkert.orgInfoAccess::info() const 855886Snate@binkert.org{ 865886Snate@binkert.org const Info *info = find(); 875886Snate@binkert.org assert(info); 885886Snate@binkert.org return info; 895886Snate@binkert.org} 905886Snate@binkert.org 915886Snate@binkert.orgInfo::Info() 92582SN/A : flags(none), precision(-1), prereq(0) 93582SN/A{ 94695SN/A static int count = 0; 95695SN/A id = count++; 96582SN/A} 97582SN/A 985886Snate@binkert.orgInfo::~Info() 99388SN/A{ 100388SN/A} 101388SN/A 1022SN/Abool 1035886Snate@binkert.orgInfo::less(Info *stat1, Info *stat2) 1042SN/A{ 105388SN/A const string &name1 = stat1->name; 106388SN/A const string &name2 = stat2->name; 1072SN/A 1082SN/A vector<string> v1; 1092SN/A vector<string> v2; 1102SN/A 1112SN/A tokenize(v1, name1, '.'); 1122SN/A tokenize(v2, name2, '.'); 1132SN/A 1145599Snate@binkert.org size_type last = min(v1.size(), v2.size()) - 1; 1155599Snate@binkert.org for (off_type i = 0; i < last; ++i) 1162SN/A if (v1[i] != v2[i]) 1172SN/A return v1[i] < v2[i]; 1182SN/A 1192SN/A // Special compare for last element. 1202SN/A if (v1[last] == v2[last]) 1212SN/A return v1.size() < v2.size(); 1222SN/A else 1232SN/A return v1[last] < v2[last]; 1242SN/A 1252SN/A return false; 1262SN/A} 1272SN/A 128388SN/Abool 1295886Snate@binkert.orgInfo::baseCheck() const 1302SN/A{ 131434SN/A if (!(flags & init)) { 132582SN/A#ifdef DEBUG 133695SN/A cprintf("this is stat number %d\n", id); 134388SN/A#endif 135388SN/A panic("Not all stats have been initialized"); 136388SN/A return false; 137388SN/A } 1382SN/A 139434SN/A if ((flags & print) && name.empty()) { 140388SN/A panic("all printable stats must be named"); 141388SN/A return false; 142388SN/A } 1432SN/A 144388SN/A return true; 1452SN/A} 1462SN/A 147695SN/A 148695SN/Avoid 149695SN/AFormulaBase::result(VResult &vec) const 1502SN/A{ 151695SN/A if (root) 152695SN/A vec = root->result(); 1532SN/A} 1542SN/A 155695SN/AResult 156388SN/AFormulaBase::total() const 157388SN/A{ 158456SN/A return root ? root->total() : 0.0; 159388SN/A} 160388SN/A 1615599Snate@binkert.orgsize_type 162388SN/AFormulaBase::size() const 163388SN/A{ 164388SN/A if (!root) 165388SN/A return 0; 166388SN/A else 167388SN/A return root->size(); 168388SN/A} 169388SN/A 170388SN/Avoid 171388SN/AFormulaBase::reset() 172388SN/A{ 173388SN/A} 174388SN/A 175388SN/Abool 176388SN/AFormulaBase::zero() const 177388SN/A{ 178695SN/A VResult vec; 179695SN/A result(vec); 1805599Snate@binkert.org for (off_t i = 0; i < vec.size(); ++i) 181388SN/A if (vec[i] != 0.0) 182388SN/A return false; 183388SN/A return true; 184388SN/A} 185388SN/A 186388SN/Avoid 1875886Snate@binkert.orgFormulaBase::update(Info *) 188388SN/A{ 189388SN/A} 190388SN/A 191441SN/Astring 192441SN/AFormulaBase::str() const 193441SN/A{ 194441SN/A return root ? root->str() : ""; 195441SN/A} 196441SN/A 197388SN/AFormula::Formula() 198388SN/A{ 199388SN/A setInit(); 200388SN/A} 201388SN/A 202388SN/AFormula::Formula(Temp r) 203388SN/A{ 204388SN/A root = r; 205388SN/A assert(size()); 206388SN/A} 207388SN/A 208388SN/Aconst Formula & 209388SN/AFormula::operator=(Temp r) 210388SN/A{ 211388SN/A assert(!root && "Can't change formulas"); 212388SN/A root = r; 213388SN/A assert(size()); 214388SN/A return *this; 215388SN/A} 216388SN/A 217388SN/Aconst Formula & 218388SN/AFormula::operator+=(Temp r) 219388SN/A{ 220388SN/A if (root) 221695SN/A root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 222388SN/A else 223388SN/A root = r; 224388SN/A assert(size()); 225388SN/A return *this; 226388SN/A} 227388SN/A 228142SN/Avoid 2292SN/Acheck() 2302SN/A{ 231695SN/A typedef Database::stat_list_t::iterator iter_t; 232695SN/A 233695SN/A iter_t i, end = Database::stats().end(); 234695SN/A for (i = Database::stats().begin(); i != end; ++i) { 2355886Snate@binkert.org Info *info = *i; 2365886Snate@binkert.org assert(info); 2375886Snate@binkert.org if (!info->check() || !info->baseCheck()) 2385886Snate@binkert.org panic("stat check failed for %s\n", info->name); 239695SN/A } 240695SN/A 2415599Snate@binkert.org off_t j = 0; 242695SN/A for (i = Database::stats().begin(); i != end; ++i) { 2435886Snate@binkert.org Info *info = *i; 2445886Snate@binkert.org if (!(info->flags & print)) 2455886Snate@binkert.org info->name = "__Stat" + to_string(j++); 246695SN/A } 247695SN/A 2485886Snate@binkert.org Database::stats().sort(Info::less); 249695SN/A 250695SN/A if (i == end) 251695SN/A return; 252695SN/A 253695SN/A iter_t last = i; 254695SN/A ++i; 255695SN/A 256695SN/A for (i = Database::stats().begin(); i != end; ++i) { 257695SN/A if ((*i)->name == (*last)->name) 258695SN/A panic("same name used twice! name=%s\n", (*i)->name); 259695SN/A 260695SN/A last = i; 261695SN/A } 2622SN/A} 2632SN/A 264695SN/ACallbackQueue resetQueue; 2652SN/A 266456SN/Avoid 267695SN/Areset() 268456SN/A{ 269695SN/A Database::stat_list_t::iterator i = Database::stats().begin(); 270695SN/A Database::stat_list_t::iterator end = Database::stats().end(); 271695SN/A while (i != end) { 2725886Snate@binkert.org Info *info = *i; 2735886Snate@binkert.org info->reset(); 274695SN/A ++i; 275695SN/A } 276695SN/A 277695SN/A resetQueue.process(); 278456SN/A} 279456SN/A 280456SN/Avoid 281394SN/AregisterResetCallback(Callback *cb) 282148SN/A{ 283148SN/A resetQueue.add(cb); 284148SN/A} 285148SN/A 286729SN/A/* namespace Stats */ } 287