statistics.cc revision 5886
1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Nathan Binkert 29 */ 30 31#include <iomanip> 32#include <fstream> 33#include <list> 34#include <map> 35#include <string> 36 37#include "base/callback.hh" 38#include "base/cprintf.hh" 39#include "base/hostinfo.hh" 40#include "base/misc.hh" 41#include "base/statistics.hh" 42#include "base/str.hh" 43#include "base/time.hh" 44#include "base/trace.hh" 45#include "base/stats/statdb.hh" 46 47using namespace std; 48 49namespace Stats { 50 51Info * 52InfoAccess::find() const 53{ 54 return Database::find(const_cast<void *>((const void *)this)); 55} 56 57const Info * 58getInfo(const void *stat) 59{ 60 return Database::find(const_cast<void *>(stat)); 61} 62 63void 64InfoAccess::setInfo(Info *info) 65{ 66 Database::regStat(this, info); 67} 68 69void 70InfoAccess::setInit() 71{ 72 info()->flags |= init; 73} 74 75Info * 76InfoAccess::info() 77{ 78 Info *info = find(); 79 assert(info); 80 return info; 81} 82 83const Info * 84InfoAccess::info() const 85{ 86 const Info *info = find(); 87 assert(info); 88 return info; 89} 90 91Info::Info() 92 : flags(none), precision(-1), prereq(0) 93{ 94 static int count = 0; 95 id = count++; 96} 97 98Info::~Info() 99{ 100} 101 102bool 103Info::less(Info *stat1, Info *stat2) 104{ 105 const string &name1 = stat1->name; 106 const string &name2 = stat2->name; 107 108 vector<string> v1; 109 vector<string> v2; 110 111 tokenize(v1, name1, '.'); 112 tokenize(v2, name2, '.'); 113 114 size_type last = min(v1.size(), v2.size()) - 1; 115 for (off_type i = 0; i < last; ++i) 116 if (v1[i] != v2[i]) 117 return v1[i] < v2[i]; 118 119 // Special compare for last element. 120 if (v1[last] == v2[last]) 121 return v1.size() < v2.size(); 122 else 123 return v1[last] < v2[last]; 124 125 return false; 126} 127 128bool 129Info::baseCheck() const 130{ 131 if (!(flags & init)) { 132#ifdef DEBUG 133 cprintf("this is stat number %d\n", id); 134#endif 135 panic("Not all stats have been initialized"); 136 return false; 137 } 138 139 if ((flags & print) && name.empty()) { 140 panic("all printable stats must be named"); 141 return false; 142 } 143 144 return true; 145} 146 147 148void 149FormulaBase::result(VResult &vec) const 150{ 151 if (root) 152 vec = root->result(); 153} 154 155Result 156FormulaBase::total() const 157{ 158 return root ? root->total() : 0.0; 159} 160 161size_type 162FormulaBase::size() const 163{ 164 if (!root) 165 return 0; 166 else 167 return root->size(); 168} 169 170void 171FormulaBase::reset() 172{ 173} 174 175bool 176FormulaBase::zero() const 177{ 178 VResult vec; 179 result(vec); 180 for (off_t i = 0; i < vec.size(); ++i) 181 if (vec[i] != 0.0) 182 return false; 183 return true; 184} 185 186void 187FormulaBase::update(Info *) 188{ 189} 190 191string 192FormulaBase::str() const 193{ 194 return root ? root->str() : ""; 195} 196 197Formula::Formula() 198{ 199 setInit(); 200} 201 202Formula::Formula(Temp r) 203{ 204 root = r; 205 assert(size()); 206} 207 208const Formula & 209Formula::operator=(Temp r) 210{ 211 assert(!root && "Can't change formulas"); 212 root = r; 213 assert(size()); 214 return *this; 215} 216 217const Formula & 218Formula::operator+=(Temp r) 219{ 220 if (root) 221 root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 222 else 223 root = r; 224 assert(size()); 225 return *this; 226} 227 228void 229check() 230{ 231 typedef Database::stat_list_t::iterator iter_t; 232 233 iter_t i, end = Database::stats().end(); 234 for (i = Database::stats().begin(); i != end; ++i) { 235 Info *info = *i; 236 assert(info); 237 if (!info->check() || !info->baseCheck()) 238 panic("stat check failed for %s\n", info->name); 239 } 240 241 off_t j = 0; 242 for (i = Database::stats().begin(); i != end; ++i) { 243 Info *info = *i; 244 if (!(info->flags & print)) 245 info->name = "__Stat" + to_string(j++); 246 } 247 248 Database::stats().sort(Info::less); 249 250 if (i == end) 251 return; 252 253 iter_t last = i; 254 ++i; 255 256 for (i = Database::stats().begin(); i != end; ++i) { 257 if ((*i)->name == (*last)->name) 258 panic("same name used twice! name=%s\n", (*i)->name); 259 260 last = i; 261 } 262} 263 264CallbackQueue resetQueue; 265 266void 267reset() 268{ 269 Database::stat_list_t::iterator i = Database::stats().begin(); 270 Database::stat_list_t::iterator end = Database::stats().end(); 271 while (i != end) { 272 Info *info = *i; 273 info->reset(); 274 ++i; 275 } 276 277 resetQueue.process(); 278} 279 280void 281registerResetCallback(Callback *cb) 282{ 283 resetQueue.add(cb); 284} 285 286/* namespace Stats */ } 287