statistics.cc revision 7462:0c61c3cf7639
113511Sgabeblack@google.com/* 213511Sgabeblack@google.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 313511Sgabeblack@google.com * All rights reserved. 413511Sgabeblack@google.com * 513511Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 613511Sgabeblack@google.com * modification, are permitted provided that the following conditions are 713511Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 813511Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 913511Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1013511Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1113511Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1213511Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1313511Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1413511Sgabeblack@google.com * this software without specific prior written permission. 1513511Sgabeblack@google.com * 1613511Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1713511Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1813511Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1913511Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2013513Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2113513Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2213511Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2313513Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2413511Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2513586Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2613586Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2713586Sgabeblack@google.com * 2813586Sgabeblack@google.com * Authors: Nathan Binkert 2913586Sgabeblack@google.com */ 3013586Sgabeblack@google.com 3113513Sgabeblack@google.com#include <iomanip> 3213513Sgabeblack@google.com#include <fstream> 3313511Sgabeblack@google.com#include <list> 3413511Sgabeblack@google.com#include <map> 3513511Sgabeblack@google.com#include <string> 3613511Sgabeblack@google.com 3713513Sgabeblack@google.com#include "base/callback.hh" 3813513Sgabeblack@google.com#include "base/cprintf.hh" 3913513Sgabeblack@google.com#include "base/debug.hh" 4013513Sgabeblack@google.com#include "base/hostinfo.hh" 4113513Sgabeblack@google.com#include "base/misc.hh" 4213513Sgabeblack@google.com#include "base/statistics.hh" 4313513Sgabeblack@google.com#include "base/str.hh" 4413513Sgabeblack@google.com#include "base/time.hh" 4513513Sgabeblack@google.com#include "base/trace.hh" 4613513Sgabeblack@google.com 4713513Sgabeblack@google.comusing namespace std; 4813513Sgabeblack@google.com 4913511Sgabeblack@google.comnamespace Stats { 5013513Sgabeblack@google.com 5113513Sgabeblack@google.comtypedef map<const void *, Info *> MapType; 5213513Sgabeblack@google.com 5313513Sgabeblack@google.com// We wrap these in a function to make sure they're built in time. 5413511Sgabeblack@google.comlist<Info *> & 5513513Sgabeblack@google.comstatsList() 5613513Sgabeblack@google.com{ 5713513Sgabeblack@google.com static list<Info *> the_list; 5813511Sgabeblack@google.com return the_list; 5913513Sgabeblack@google.com} 6013513Sgabeblack@google.com 6113513Sgabeblack@google.comMapType & 6213513Sgabeblack@google.comstatsMap() 6313513Sgabeblack@google.com{ 6413513Sgabeblack@google.com static MapType the_map; 6513513Sgabeblack@google.com return the_map; 6613513Sgabeblack@google.com} 6713513Sgabeblack@google.com 6813511Sgabeblack@google.comvoid 6913511Sgabeblack@google.comInfoAccess::setInfo(Info *info) 7013513Sgabeblack@google.com{ 7113513Sgabeblack@google.com if (statsMap().find(this) != statsMap().end()) 7213513Sgabeblack@google.com panic("shouldn't register stat twice!"); 7313513Sgabeblack@google.com 7413513Sgabeblack@google.com statsList().push_back(info); 7513513Sgabeblack@google.com 7613513Sgabeblack@google.com#ifndef NDEBUG 7713511Sgabeblack@google.com pair<MapType::iterator, bool> result = 7813513Sgabeblack@google.com#endif 7913513Sgabeblack@google.com statsMap().insert(make_pair(this, info)); 8013513Sgabeblack@google.com assert(result.second && "this should never fail"); 8113513Sgabeblack@google.com assert(statsMap().find(this) != statsMap().end()); 8213513Sgabeblack@google.com} 8313513Sgabeblack@google.com 8413513Sgabeblack@google.comvoid 8513513Sgabeblack@google.comInfoAccess::setParams(const StorageParams *params) 8613513Sgabeblack@google.com{ 8713513Sgabeblack@google.com info()->storageParams = params; 8813513Sgabeblack@google.com} 8913513Sgabeblack@google.com 9013513Sgabeblack@google.comvoid 9113513Sgabeblack@google.comInfoAccess::setInit() 9213513Sgabeblack@google.com{ 9313513Sgabeblack@google.com info()->flags.set(init); 9413513Sgabeblack@google.com} 9513513Sgabeblack@google.com 9613513Sgabeblack@google.comInfo * 9713513Sgabeblack@google.comInfoAccess::info() 9813513Sgabeblack@google.com{ 9913513Sgabeblack@google.com MapType::const_iterator i = statsMap().find(this); 10013513Sgabeblack@google.com assert(i != statsMap().end()); 10113513Sgabeblack@google.com return (*i).second; 10213513Sgabeblack@google.com} 10313513Sgabeblack@google.com 10413513Sgabeblack@google.comconst Info * 10513513Sgabeblack@google.comInfoAccess::info() const 10613511Sgabeblack@google.com{ 10713513Sgabeblack@google.com MapType::const_iterator i = statsMap().find(this); 10813513Sgabeblack@google.com assert(i != statsMap().end()); 10913513Sgabeblack@google.com return (*i).second; 11013513Sgabeblack@google.com} 11113513Sgabeblack@google.com 11213513Sgabeblack@google.comStorageParams::~StorageParams() 11313513Sgabeblack@google.com{ 11413513Sgabeblack@google.com} 11513513Sgabeblack@google.com 11613513Sgabeblack@google.comtypedef map<std::string, Info *> NameMapType; 11713513Sgabeblack@google.comNameMapType & 11813511Sgabeblack@google.comnameMap() 11913511Sgabeblack@google.com{ 12013513Sgabeblack@google.com static NameMapType the_map; 12113513Sgabeblack@google.com return the_map; 12213513Sgabeblack@google.com} 12313513Sgabeblack@google.com 12413513Sgabeblack@google.comint Info::id_count = 0; 12513511Sgabeblack@google.com 12613511Sgabeblack@google.comint debug_break_id = -1; 12713511Sgabeblack@google.com 12813511Sgabeblack@google.comInfo::Info() 12913511Sgabeblack@google.com : flags(none), precision(-1), prereq(0), storageParams(NULL) 13013511Sgabeblack@google.com{ 13113511Sgabeblack@google.com id = id_count++; 13213511Sgabeblack@google.com if (debug_break_id >= 0 and debug_break_id == id) 13313513Sgabeblack@google.com debug_break(); 13413513Sgabeblack@google.com} 13513511Sgabeblack@google.com 13613513Sgabeblack@google.comInfo::~Info() 13713513Sgabeblack@google.com{ 13813513Sgabeblack@google.com} 13913513Sgabeblack@google.com 14013511Sgabeblack@google.comvoid 14113513Sgabeblack@google.comInfo::setName(const string &name) 14213513Sgabeblack@google.com{ 14313513Sgabeblack@google.com pair<NameMapType::iterator, bool> p = 14413513Sgabeblack@google.com nameMap().insert(make_pair(name, this)); 14513513Sgabeblack@google.com 14613513Sgabeblack@google.com Info *other = p.first->second; 14713513Sgabeblack@google.com bool result = p.second; 14813513Sgabeblack@google.com 14913511Sgabeblack@google.com if (!result) { 15013513Sgabeblack@google.com // using other->name instead of just name to avoid a compiler 15113513Sgabeblack@google.com // warning. They should be the same. 15213513Sgabeblack@google.com panic("same statistic name used twice! name=%s\n", other->name); 15313513Sgabeblack@google.com } 15413513Sgabeblack@google.com 15513513Sgabeblack@google.com this->name = name; 15613513Sgabeblack@google.com} 15713513Sgabeblack@google.com 15813513Sgabeblack@google.combool 15913513Sgabeblack@google.comInfo::less(Info *stat1, Info *stat2) 16013513Sgabeblack@google.com{ 16113513Sgabeblack@google.com const string &name1 = stat1->name; 16213513Sgabeblack@google.com const string &name2 = stat2->name; 16313513Sgabeblack@google.com 16413513Sgabeblack@google.com vector<string> v1; 16513513Sgabeblack@google.com vector<string> v2; 16613513Sgabeblack@google.com 16713513Sgabeblack@google.com tokenize(v1, name1, '.'); 16813513Sgabeblack@google.com tokenize(v2, name2, '.'); 16913513Sgabeblack@google.com 17013513Sgabeblack@google.com size_type last = min(v1.size(), v2.size()) - 1; 17113513Sgabeblack@google.com for (off_type i = 0; i < last; ++i) 17213513Sgabeblack@google.com if (v1[i] != v2[i]) 17313513Sgabeblack@google.com return v1[i] < v2[i]; 17413513Sgabeblack@google.com 17513513Sgabeblack@google.com // Special compare for last element. 17613511Sgabeblack@google.com if (v1[last] == v2[last]) 17713513Sgabeblack@google.com return v1.size() < v2.size(); 17813513Sgabeblack@google.com else 17913513Sgabeblack@google.com return v1[last] < v2[last]; 18013513Sgabeblack@google.com 18113513Sgabeblack@google.com return false; 18213513Sgabeblack@google.com} 18313513Sgabeblack@google.com 18413513Sgabeblack@google.combool 18513513Sgabeblack@google.comInfo::baseCheck() const 18613513Sgabeblack@google.com{ 18713513Sgabeblack@google.com if (!(flags & Stats::init)) { 18813511Sgabeblack@google.com#ifdef DEBUG 18913511Sgabeblack@google.com cprintf("this is stat number %d\n", id); 19013513Sgabeblack@google.com#endif 19113513Sgabeblack@google.com panic("Not all stats have been initialized"); 19213513Sgabeblack@google.com return false; 19313513Sgabeblack@google.com } 19413513Sgabeblack@google.com 19513513Sgabeblack@google.com if ((flags & display) && name.empty()) { 19613513Sgabeblack@google.com panic("all printable stats must be named"); 19713513Sgabeblack@google.com return false; 19813513Sgabeblack@google.com } 19913511Sgabeblack@google.com 20013511Sgabeblack@google.com return true; 20113513Sgabeblack@google.com} 20213513Sgabeblack@google.com 20313513Sgabeblack@google.comvoid 20413513Sgabeblack@google.comInfo::enable() 20513513Sgabeblack@google.com{ 20613513Sgabeblack@google.com} 20713513Sgabeblack@google.com 20813513Sgabeblack@google.comvoid 20913513Sgabeblack@google.comVectorInfo::enable() 21013513Sgabeblack@google.com{ 21113513Sgabeblack@google.com size_type s = size(); 21213513Sgabeblack@google.com if (subnames.size() < s) 21313513Sgabeblack@google.com subnames.resize(s); 21413513Sgabeblack@google.com if (subdescs.size() < s) 21513513Sgabeblack@google.com subdescs.resize(s); 21613513Sgabeblack@google.com} 21713513Sgabeblack@google.com 21813513Sgabeblack@google.comvoid 21913513Sgabeblack@google.comVectorDistInfo::enable() 22013513Sgabeblack@google.com{ 22113511Sgabeblack@google.com size_type s = size(); 22213511Sgabeblack@google.com if (subnames.size() < s) 22313513Sgabeblack@google.com subnames.resize(s); 22413513Sgabeblack@google.com if (subdescs.size() < s) 22513513Sgabeblack@google.com subdescs.resize(s); 22613513Sgabeblack@google.com} 22713513Sgabeblack@google.com 22813511Sgabeblack@google.comvoid 22913511Sgabeblack@google.comVector2dInfo::enable() 23013513Sgabeblack@google.com{ 23113513Sgabeblack@google.com if (subnames.size() < x) 23213513Sgabeblack@google.com subnames.resize(x); 23313513Sgabeblack@google.com if (subdescs.size() < x) 23413513Sgabeblack@google.com subdescs.resize(x); 23513513Sgabeblack@google.com if (y_subnames.size() < y) 23613513Sgabeblack@google.com y_subnames.resize(y); 23713513Sgabeblack@google.com} 23813513Sgabeblack@google.com 23913511Sgabeblack@google.comFormula::Formula() 24013511Sgabeblack@google.com{ 24113513Sgabeblack@google.com} 24213513Sgabeblack@google.com 24313513Sgabeblack@google.comFormula::Formula(Temp r) 24413513Sgabeblack@google.com{ 24513513Sgabeblack@google.com root = r; 24613513Sgabeblack@google.com setInit(); 24713513Sgabeblack@google.com assert(size()); 24813513Sgabeblack@google.com} 24913513Sgabeblack@google.com 25013513Sgabeblack@google.comconst Formula & 25113511Sgabeblack@google.comFormula::operator=(Temp r) 25213513Sgabeblack@google.com{ 25313513Sgabeblack@google.com assert(!root && "Can't change formulas"); 25413513Sgabeblack@google.com root = r; 25513513Sgabeblack@google.com setInit(); 25613513Sgabeblack@google.com assert(size()); 25713513Sgabeblack@google.com return *this; 25813513Sgabeblack@google.com} 25913513Sgabeblack@google.com 26013513Sgabeblack@google.comconst Formula & 26113513Sgabeblack@google.comFormula::operator+=(Temp r) 26213513Sgabeblack@google.com{ 26313513Sgabeblack@google.com if (root) 26413513Sgabeblack@google.com root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 26513513Sgabeblack@google.com else { 26613513Sgabeblack@google.com root = r; 26713513Sgabeblack@google.com setInit(); 26813513Sgabeblack@google.com } 26913513Sgabeblack@google.com 27013513Sgabeblack@google.com assert(size()); 27113513Sgabeblack@google.com return *this; 27213513Sgabeblack@google.com} 27313511Sgabeblack@google.com 27413513Sgabeblack@google.comvoid 27513513Sgabeblack@google.comFormula::result(VResult &vec) const 27613513Sgabeblack@google.com{ 27713511Sgabeblack@google.com if (root) 27813513Sgabeblack@google.com vec = root->result(); 27913513Sgabeblack@google.com} 28013513Sgabeblack@google.com 28113513Sgabeblack@google.comResult 28213513Sgabeblack@google.comFormula::total() const 28313513Sgabeblack@google.com{ 28413513Sgabeblack@google.com return root ? root->total() : 0.0; 28513513Sgabeblack@google.com} 28613513Sgabeblack@google.com 28713513Sgabeblack@google.comsize_type 28813513Sgabeblack@google.comFormula::size() const 28913513Sgabeblack@google.com{ 29013513Sgabeblack@google.com if (!root) 29113513Sgabeblack@google.com return 0; 29213513Sgabeblack@google.com else 29313513Sgabeblack@google.com return root->size(); 29413513Sgabeblack@google.com} 29513513Sgabeblack@google.com 29613513Sgabeblack@google.comvoid 29713513Sgabeblack@google.comFormula::reset() 29813513Sgabeblack@google.com{ 29913511Sgabeblack@google.com} 30013511Sgabeblack@google.com 30113513Sgabeblack@google.combool 30213511Sgabeblack@google.comFormula::zero() const 30313513Sgabeblack@google.com{ 304 VResult vec; 305 result(vec); 306 for (VResult::size_type i = 0; i < vec.size(); ++i) 307 if (vec[i] != 0.0) 308 return false; 309 return true; 310} 311 312string 313Formula::str() const 314{ 315 return root ? root->str() : ""; 316} 317 318void 319enable() 320{ 321 typedef list<Info *>::iterator iter_t; 322 323 iter_t i, end = statsList().end(); 324 for (i = statsList().begin(); i != end; ++i) { 325 Info *info = *i; 326 assert(info); 327 if (!info->check() || !info->baseCheck()) 328 panic("stat check failed for '%s' %d\n", info->name, info->id); 329 } 330 331 off_t j = 0; 332 for (i = statsList().begin(); i != end; ++i) { 333 Info *info = *i; 334 if (!(info->flags & display)) 335 info->name = "__Stat" + to_string(j++); 336 } 337 338 statsList().sort(Info::less); 339 340 for (i = statsList().begin(); i != end; ++i) { 341 Info *info = *i; 342 info->enable(); 343 } 344} 345 346void 347prepare() 348{ 349 list<Info *>::iterator i = statsList().begin(); 350 list<Info *>::iterator end = statsList().end(); 351 while (i != end) { 352 Info *info = *i; 353 info->prepare(); 354 ++i; 355 } 356} 357 358CallbackQueue resetQueue; 359 360void 361reset() 362{ 363 list<Info *>::iterator i = statsList().begin(); 364 list<Info *>::iterator end = statsList().end(); 365 while (i != end) { 366 Info *info = *i; 367 info->reset(); 368 ++i; 369 } 370 371 resetQueue.process(); 372} 373 374void 375registerResetCallback(Callback *cb) 376{ 377 resetQueue.add(cb); 378} 379 380/* namespace Stats */ } 381