statistics.cc revision 6000
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" 395889Snate@binkert.org#include "base/debug.hh" 40441SN/A#include "base/hostinfo.hh" 4156SN/A#include "base/misc.hh" 4256SN/A#include "base/statistics.hh" 4356SN/A#include "base/str.hh" 44441SN/A#include "base/time.hh" 45433SN/A#include "base/trace.hh" 462SN/A 472SN/Ausing namespace std; 482SN/A 49729SN/Anamespace Stats { 50388SN/A 515887Snate@binkert.orgtypedef map<const void *, Info *> MapType; 525887Snate@binkert.org 535887Snate@binkert.org// We wrap these in a function to make sure they're built in time. 545887Snate@binkert.orglist<Info *> & 555887Snate@binkert.orgstatsList() 56388SN/A{ 575887Snate@binkert.org static list<Info *> the_list; 585887Snate@binkert.org return the_list; 59388SN/A} 60388SN/A 615887Snate@binkert.orgMapType & 625887Snate@binkert.orgstatsMap() 63441SN/A{ 645887Snate@binkert.org static MapType the_map; 655887Snate@binkert.org return the_map; 66441SN/A} 67441SN/A 68388SN/Avoid 695886Snate@binkert.orgInfoAccess::setInfo(Info *info) 70388SN/A{ 715887Snate@binkert.org if (statsMap().find(this) != statsMap().end()) 725887Snate@binkert.org panic("shouldn't register stat twice!"); 735887Snate@binkert.org 745887Snate@binkert.org statsList().push_back(info); 755887Snate@binkert.org 765887Snate@binkert.org#ifndef NDEBUG 775887Snate@binkert.org pair<MapType::iterator, bool> result = 785887Snate@binkert.org#endif 795887Snate@binkert.org statsMap().insert(make_pair(this, info)); 805887Snate@binkert.org assert(result.second && "this should never fail"); 815887Snate@binkert.org assert(statsMap().find(this) != statsMap().end()); 82388SN/A} 83388SN/A 84388SN/Avoid 855889Snate@binkert.orgInfoAccess::setParams(const StorageParams *params) 865889Snate@binkert.org{ 875889Snate@binkert.org info()->storageParams = params; 885889Snate@binkert.org} 895889Snate@binkert.org 905889Snate@binkert.orgvoid 915886Snate@binkert.orgInfoAccess::setInit() 92388SN/A{ 935886Snate@binkert.org info()->flags |= init; 94388SN/A} 95388SN/A 965886Snate@binkert.orgInfo * 975886Snate@binkert.orgInfoAccess::info() 98388SN/A{ 995887Snate@binkert.org MapType::const_iterator i = statsMap().find(this); 1005887Snate@binkert.org assert(i != statsMap().end()); 1015887Snate@binkert.org return (*i).second; 102388SN/A} 103388SN/A 1045886Snate@binkert.orgconst Info * 1055886Snate@binkert.orgInfoAccess::info() const 1065886Snate@binkert.org{ 1075887Snate@binkert.org MapType::const_iterator i = statsMap().find(this); 1085887Snate@binkert.org assert(i != statsMap().end()); 1095887Snate@binkert.org return (*i).second; 1105886Snate@binkert.org} 1115886Snate@binkert.org 1125889Snate@binkert.orgStorageParams::~StorageParams() 1135889Snate@binkert.org{ 1145889Snate@binkert.org} 1155889Snate@binkert.org 1165889Snate@binkert.orgint Info::id_count = 0; 1175889Snate@binkert.org 1185889Snate@binkert.orgint debug_break_id = -1; 1195889Snate@binkert.org 1205886Snate@binkert.orgInfo::Info() 1215889Snate@binkert.org : flags(none), precision(-1), prereq(0), storageParams(NULL) 122582SN/A{ 1235889Snate@binkert.org id = id_count++; 1245889Snate@binkert.org if (debug_break_id >= 0 and debug_break_id == id) 1255889Snate@binkert.org debug_break(); 126582SN/A} 127582SN/A 1285886Snate@binkert.orgInfo::~Info() 129388SN/A{ 130388SN/A} 131388SN/A 1322SN/Abool 1335886Snate@binkert.orgInfo::less(Info *stat1, Info *stat2) 1342SN/A{ 135388SN/A const string &name1 = stat1->name; 136388SN/A const string &name2 = stat2->name; 1372SN/A 1382SN/A vector<string> v1; 1392SN/A vector<string> v2; 1402SN/A 1412SN/A tokenize(v1, name1, '.'); 1422SN/A tokenize(v2, name2, '.'); 1432SN/A 1445599Snate@binkert.org size_type last = min(v1.size(), v2.size()) - 1; 1455599Snate@binkert.org for (off_type i = 0; i < last; ++i) 1462SN/A if (v1[i] != v2[i]) 1472SN/A return v1[i] < v2[i]; 1482SN/A 1492SN/A // Special compare for last element. 1502SN/A if (v1[last] == v2[last]) 1512SN/A return v1.size() < v2.size(); 1522SN/A else 1532SN/A return v1[last] < v2[last]; 1542SN/A 1552SN/A return false; 1562SN/A} 1572SN/A 158388SN/Abool 1595886Snate@binkert.orgInfo::baseCheck() const 1602SN/A{ 1616000Snate@binkert.org if (!(flags & Stats::init)) { 162582SN/A#ifdef DEBUG 163695SN/A cprintf("this is stat number %d\n", id); 164388SN/A#endif 165388SN/A panic("Not all stats have been initialized"); 166388SN/A return false; 167388SN/A } 1682SN/A 169434SN/A if ((flags & print) && name.empty()) { 170388SN/A panic("all printable stats must be named"); 171388SN/A return false; 172388SN/A } 1732SN/A 174388SN/A return true; 1752SN/A} 1762SN/A 177695SN/A 178388SN/AFormula::Formula() 179388SN/A{ 180388SN/A setInit(); 181388SN/A} 182388SN/A 183388SN/AFormula::Formula(Temp r) 184388SN/A{ 185388SN/A root = r; 186388SN/A assert(size()); 187388SN/A} 188388SN/A 189388SN/Aconst Formula & 190388SN/AFormula::operator=(Temp r) 191388SN/A{ 192388SN/A assert(!root && "Can't change formulas"); 193388SN/A root = r; 194388SN/A assert(size()); 195388SN/A return *this; 196388SN/A} 197388SN/A 198388SN/Aconst Formula & 199388SN/AFormula::operator+=(Temp r) 200388SN/A{ 201388SN/A if (root) 202695SN/A root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 203388SN/A else 204388SN/A root = r; 205388SN/A assert(size()); 206388SN/A return *this; 207388SN/A} 208388SN/A 209142SN/Avoid 2106000Snate@binkert.orgFormula::result(VResult &vec) const 2116000Snate@binkert.org{ 2126000Snate@binkert.org if (root) 2136000Snate@binkert.org vec = root->result(); 2146000Snate@binkert.org} 2156000Snate@binkert.org 2166000Snate@binkert.orgResult 2176000Snate@binkert.orgFormula::total() const 2186000Snate@binkert.org{ 2196000Snate@binkert.org return root ? root->total() : 0.0; 2206000Snate@binkert.org} 2216000Snate@binkert.org 2226000Snate@binkert.orgsize_type 2236000Snate@binkert.orgFormula::size() const 2246000Snate@binkert.org{ 2256000Snate@binkert.org if (!root) 2266000Snate@binkert.org return 0; 2276000Snate@binkert.org else 2286000Snate@binkert.org return root->size(); 2296000Snate@binkert.org} 2306000Snate@binkert.org 2316000Snate@binkert.orgvoid 2326000Snate@binkert.orgFormula::reset() 2336000Snate@binkert.org{ 2346000Snate@binkert.org} 2356000Snate@binkert.org 2366000Snate@binkert.orgbool 2376000Snate@binkert.orgFormula::zero() const 2386000Snate@binkert.org{ 2396000Snate@binkert.org VResult vec; 2406000Snate@binkert.org result(vec); 2416000Snate@binkert.org for (off_t i = 0; i < vec.size(); ++i) 2426000Snate@binkert.org if (vec[i] != 0.0) 2436000Snate@binkert.org return false; 2446000Snate@binkert.org return true; 2456000Snate@binkert.org} 2466000Snate@binkert.org 2476000Snate@binkert.orgvoid 2486000Snate@binkert.orgFormula::update() 2496000Snate@binkert.org{ 2506000Snate@binkert.org} 2516000Snate@binkert.org 2526000Snate@binkert.orgstring 2536000Snate@binkert.orgFormula::str() const 2546000Snate@binkert.org{ 2556000Snate@binkert.org return root ? root->str() : ""; 2566000Snate@binkert.org} 2576000Snate@binkert.org 2586000Snate@binkert.orgvoid 2592SN/Acheck() 2602SN/A{ 2615887Snate@binkert.org typedef list<Info *>::iterator iter_t; 262695SN/A 2635887Snate@binkert.org iter_t i, end = statsList().end(); 2645887Snate@binkert.org for (i = statsList().begin(); i != end; ++i) { 2655886Snate@binkert.org Info *info = *i; 2665886Snate@binkert.org assert(info); 2675886Snate@binkert.org if (!info->check() || !info->baseCheck()) 2685889Snate@binkert.org panic("stat check failed for '%s' %d\n", info->name, info->id); 269695SN/A } 270695SN/A 2715599Snate@binkert.org off_t j = 0; 2725887Snate@binkert.org for (i = statsList().begin(); i != end; ++i) { 2735886Snate@binkert.org Info *info = *i; 2745886Snate@binkert.org if (!(info->flags & print)) 2755886Snate@binkert.org info->name = "__Stat" + to_string(j++); 276695SN/A } 277695SN/A 2785887Snate@binkert.org statsList().sort(Info::less); 279695SN/A 280695SN/A if (i == end) 281695SN/A return; 282695SN/A 283695SN/A iter_t last = i; 284695SN/A ++i; 285695SN/A 2865887Snate@binkert.org for (i = statsList().begin(); i != end; ++i) { 287695SN/A if ((*i)->name == (*last)->name) 288695SN/A panic("same name used twice! name=%s\n", (*i)->name); 289695SN/A 290695SN/A last = i; 291695SN/A } 2922SN/A} 2932SN/A 294695SN/ACallbackQueue resetQueue; 2952SN/A 296456SN/Avoid 297695SN/Areset() 298456SN/A{ 2995887Snate@binkert.org list<Info *>::iterator i = statsList().begin(); 3005887Snate@binkert.org list<Info *>::iterator end = statsList().end(); 301695SN/A while (i != end) { 3025886Snate@binkert.org Info *info = *i; 3035886Snate@binkert.org info->reset(); 304695SN/A ++i; 305695SN/A } 306695SN/A 307695SN/A resetQueue.process(); 308456SN/A} 309456SN/A 310456SN/Avoid 311394SN/AregisterResetCallback(Callback *cb) 312148SN/A{ 313148SN/A resetQueue.add(cb); 314148SN/A} 315148SN/A 316729SN/A/* namespace Stats */ } 317