statistics.cc revision 5599
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 51388SN/AStatData * 52388SN/ADataAccess::find() const 53388SN/A{ 54695SN/A return Database::find(const_cast<void *>((const void *)this)); 55388SN/A} 56388SN/A 57441SN/Aconst StatData * 58441SN/AgetStatData(const void *stat) 59441SN/A{ 60695SN/A return Database::find(const_cast<void *>(stat)); 61441SN/A} 62441SN/A 63388SN/Avoid 64388SN/ADataAccess::map(StatData *data) 65388SN/A{ 66695SN/A Database::regStat(this, data); 67388SN/A} 68388SN/A 69388SN/AStatData * 70388SN/ADataAccess::statData() 71388SN/A{ 72388SN/A StatData *ptr = find(); 73388SN/A assert(ptr); 74388SN/A return ptr; 75388SN/A} 76388SN/A 77388SN/Aconst StatData * 78388SN/ADataAccess::statData() const 79388SN/A{ 80388SN/A const StatData *ptr = find(); 81388SN/A assert(ptr); 82388SN/A return ptr; 83388SN/A} 84388SN/A 85388SN/Avoid 86388SN/ADataAccess::setInit() 87388SN/A{ 88434SN/A statData()->flags |= init; 89388SN/A} 90388SN/A 91388SN/Avoid 92388SN/ADataAccess::setPrint() 93388SN/A{ 94695SN/A Database::regPrint(this); 95388SN/A} 96388SN/A 97582SN/AStatData::StatData() 98582SN/A : flags(none), precision(-1), prereq(0) 99582SN/A{ 100695SN/A static int count = 0; 101695SN/A id = count++; 102582SN/A} 103582SN/A 104388SN/AStatData::~StatData() 105388SN/A{ 106388SN/A} 107388SN/A 1082SN/Abool 109388SN/AStatData::less(StatData *stat1, StatData *stat2) 1102SN/A{ 111388SN/A const string &name1 = stat1->name; 112388SN/A const string &name2 = stat2->name; 1132SN/A 1142SN/A vector<string> v1; 1152SN/A vector<string> v2; 1162SN/A 1172SN/A tokenize(v1, name1, '.'); 1182SN/A tokenize(v2, name2, '.'); 1192SN/A 1205599Snate@binkert.org size_type last = min(v1.size(), v2.size()) - 1; 1215599Snate@binkert.org for (off_type i = 0; i < last; ++i) 1222SN/A if (v1[i] != v2[i]) 1232SN/A return v1[i] < v2[i]; 1242SN/A 1252SN/A // Special compare for last element. 1262SN/A if (v1[last] == v2[last]) 1272SN/A return v1.size() < v2.size(); 1282SN/A else 1292SN/A return v1[last] < v2[last]; 1302SN/A 1312SN/A return false; 1322SN/A} 1332SN/A 134388SN/Abool 135414SN/AStatData::baseCheck() const 1362SN/A{ 137434SN/A if (!(flags & init)) { 138582SN/A#ifdef DEBUG 139695SN/A cprintf("this is stat number %d\n", id); 140388SN/A#endif 141388SN/A panic("Not all stats have been initialized"); 142388SN/A return false; 143388SN/A } 1442SN/A 145434SN/A if ((flags & print) && name.empty()) { 146388SN/A panic("all printable stats must be named"); 147388SN/A return false; 148388SN/A } 1492SN/A 150388SN/A return true; 1512SN/A} 1522SN/A 153695SN/A 154695SN/Avoid 155695SN/AFormulaBase::result(VResult &vec) const 1562SN/A{ 157695SN/A if (root) 158695SN/A vec = root->result(); 1592SN/A} 1602SN/A 161695SN/AResult 162388SN/AFormulaBase::total() const 163388SN/A{ 164456SN/A return root ? root->total() : 0.0; 165388SN/A} 166388SN/A 1675599Snate@binkert.orgsize_type 168388SN/AFormulaBase::size() const 169388SN/A{ 170388SN/A if (!root) 171388SN/A return 0; 172388SN/A else 173388SN/A return root->size(); 174388SN/A} 175388SN/A 176388SN/Avoid 177388SN/AFormulaBase::reset() 178388SN/A{ 179388SN/A} 180388SN/A 181388SN/Abool 182388SN/AFormulaBase::zero() const 183388SN/A{ 184695SN/A VResult vec; 185695SN/A result(vec); 1865599Snate@binkert.org for (off_t i = 0; i < vec.size(); ++i) 187388SN/A if (vec[i] != 0.0) 188388SN/A return false; 189388SN/A return true; 190388SN/A} 191388SN/A 192388SN/Avoid 193388SN/AFormulaBase::update(StatData *) 194388SN/A{ 195388SN/A} 196388SN/A 197441SN/Astring 198441SN/AFormulaBase::str() const 199441SN/A{ 200441SN/A return root ? root->str() : ""; 201441SN/A} 202441SN/A 203388SN/AFormula::Formula() 204388SN/A{ 205388SN/A setInit(); 206388SN/A} 207388SN/A 208388SN/AFormula::Formula(Temp r) 209388SN/A{ 210388SN/A root = r; 211388SN/A assert(size()); 212388SN/A} 213388SN/A 214388SN/Aconst Formula & 215388SN/AFormula::operator=(Temp r) 216388SN/A{ 217388SN/A assert(!root && "Can't change formulas"); 218388SN/A root = r; 219388SN/A assert(size()); 220388SN/A return *this; 221388SN/A} 222388SN/A 223388SN/Aconst Formula & 224388SN/AFormula::operator+=(Temp r) 225388SN/A{ 226388SN/A if (root) 227695SN/A root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 228388SN/A else 229388SN/A root = r; 230388SN/A assert(size()); 231388SN/A return *this; 232388SN/A} 233388SN/A 234142SN/Avoid 2352SN/Acheck() 2362SN/A{ 237695SN/A typedef Database::stat_list_t::iterator iter_t; 238695SN/A 239695SN/A iter_t i, end = Database::stats().end(); 240695SN/A for (i = Database::stats().begin(); i != end; ++i) { 241695SN/A StatData *data = *i; 242695SN/A assert(data); 2431014SN/A if (!data->check() || !data->baseCheck()) 2441014SN/A panic("stat check failed for %s\n", data->name); 245695SN/A } 246695SN/A 2475599Snate@binkert.org off_t j = 0; 248695SN/A for (i = Database::stats().begin(); i != end; ++i) { 249695SN/A StatData *data = *i; 250695SN/A if (!(data->flags & print)) 251695SN/A data->name = "__Stat" + to_string(j++); 252695SN/A } 253695SN/A 254695SN/A Database::stats().sort(StatData::less); 255695SN/A 256695SN/A if (i == end) 257695SN/A return; 258695SN/A 259695SN/A iter_t last = i; 260695SN/A ++i; 261695SN/A 262695SN/A for (i = Database::stats().begin(); i != end; ++i) { 263695SN/A if ((*i)->name == (*last)->name) 264695SN/A panic("same name used twice! name=%s\n", (*i)->name); 265695SN/A 266695SN/A last = i; 267695SN/A } 2682SN/A} 2692SN/A 270695SN/ACallbackQueue resetQueue; 2712SN/A 272456SN/Avoid 273695SN/Areset() 274456SN/A{ 275695SN/A Database::stat_list_t::iterator i = Database::stats().begin(); 276695SN/A Database::stat_list_t::iterator end = Database::stats().end(); 277695SN/A while (i != end) { 278695SN/A StatData *data = *i; 2792343SN/A data->reset(); 280695SN/A ++i; 281695SN/A } 282695SN/A 283695SN/A resetQueue.process(); 284456SN/A} 285456SN/A 286456SN/Avoid 287394SN/AregisterResetCallback(Callback *cb) 288148SN/A{ 289148SN/A resetQueue.add(cb); 290148SN/A} 291148SN/A 292729SN/A/* namespace Stats */ } 293