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>
| 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 <set>
|
35#include <string> 36 37#include "base/callback.hh" 38#include "base/cprintf.hh" 39#include "base/debug.hh" 40#include "base/hostinfo.hh" 41#include "base/misc.hh" 42#include "base/statistics.hh" 43#include "base/str.hh" 44#include "base/time.hh" 45#include "base/trace.hh" 46 47using namespace std; 48 49namespace Stats { 50 51typedef map<const void *, Info *> MapType; 52 53// We wrap these in a function to make sure they're built in time. 54list<Info *> & 55statsList() 56{ 57 static list<Info *> the_list; 58 return the_list; 59} 60 61MapType & 62statsMap() 63{ 64 static MapType the_map; 65 return the_map; 66} 67 68void 69InfoAccess::setInfo(Info *info) 70{ 71 if (statsMap().find(this) != statsMap().end()) 72 panic("shouldn't register stat twice!"); 73 74 statsList().push_back(info); 75 76#ifndef NDEBUG 77 pair<MapType::iterator, bool> result = 78#endif 79 statsMap().insert(make_pair(this, info)); 80 assert(result.second && "this should never fail"); 81 assert(statsMap().find(this) != statsMap().end()); 82} 83 84void 85InfoAccess::setParams(const StorageParams *params) 86{ 87 info()->storageParams = params; 88} 89 90void 91InfoAccess::setInit() 92{ 93 info()->flags |= init; 94} 95 96Info * 97InfoAccess::info() 98{ 99 MapType::const_iterator i = statsMap().find(this); 100 assert(i != statsMap().end()); 101 return (*i).second; 102} 103 104const Info * 105InfoAccess::info() const 106{ 107 MapType::const_iterator i = statsMap().find(this); 108 assert(i != statsMap().end()); 109 return (*i).second; 110} 111 112StorageParams::~StorageParams() 113{ 114} 115 116int Info::id_count = 0; 117 118int debug_break_id = -1; 119 120Info::Info() 121 : flags(none), precision(-1), prereq(0), storageParams(NULL) 122{ 123 id = id_count++; 124 if (debug_break_id >= 0 and debug_break_id == id) 125 debug_break(); 126} 127 128Info::~Info() 129{ 130} 131 132bool 133Info::less(Info *stat1, Info *stat2) 134{ 135 const string &name1 = stat1->name; 136 const string &name2 = stat2->name; 137 138 vector<string> v1; 139 vector<string> v2; 140 141 tokenize(v1, name1, '.'); 142 tokenize(v2, name2, '.'); 143 144 size_type last = min(v1.size(), v2.size()) - 1; 145 for (off_type i = 0; i < last; ++i) 146 if (v1[i] != v2[i]) 147 return v1[i] < v2[i]; 148 149 // Special compare for last element. 150 if (v1[last] == v2[last]) 151 return v1.size() < v2.size(); 152 else 153 return v1[last] < v2[last]; 154 155 return false; 156} 157 158bool 159Info::baseCheck() const 160{ 161 if (!(flags & Stats::init)) { 162#ifdef DEBUG 163 cprintf("this is stat number %d\n", id); 164#endif 165 panic("Not all stats have been initialized"); 166 return false; 167 } 168 169 if ((flags & print) && name.empty()) { 170 panic("all printable stats must be named"); 171 return false; 172 } 173 174 return true; 175} 176
| 36#include <string> 37 38#include "base/callback.hh" 39#include "base/cprintf.hh" 40#include "base/debug.hh" 41#include "base/hostinfo.hh" 42#include "base/misc.hh" 43#include "base/statistics.hh" 44#include "base/str.hh" 45#include "base/time.hh" 46#include "base/trace.hh" 47 48using namespace std; 49 50namespace Stats { 51 52typedef map<const void *, Info *> MapType; 53 54// We wrap these in a function to make sure they're built in time. 55list<Info *> & 56statsList() 57{ 58 static list<Info *> the_list; 59 return the_list; 60} 61 62MapType & 63statsMap() 64{ 65 static MapType the_map; 66 return the_map; 67} 68 69void 70InfoAccess::setInfo(Info *info) 71{ 72 if (statsMap().find(this) != statsMap().end()) 73 panic("shouldn't register stat twice!"); 74 75 statsList().push_back(info); 76 77#ifndef NDEBUG 78 pair<MapType::iterator, bool> result = 79#endif 80 statsMap().insert(make_pair(this, info)); 81 assert(result.second && "this should never fail"); 82 assert(statsMap().find(this) != statsMap().end()); 83} 84 85void 86InfoAccess::setParams(const StorageParams *params) 87{ 88 info()->storageParams = params; 89} 90 91void 92InfoAccess::setInit() 93{ 94 info()->flags |= init; 95} 96 97Info * 98InfoAccess::info() 99{ 100 MapType::const_iterator i = statsMap().find(this); 101 assert(i != statsMap().end()); 102 return (*i).second; 103} 104 105const Info * 106InfoAccess::info() const 107{ 108 MapType::const_iterator i = statsMap().find(this); 109 assert(i != statsMap().end()); 110 return (*i).second; 111} 112 113StorageParams::~StorageParams() 114{ 115} 116 117int Info::id_count = 0; 118 119int debug_break_id = -1; 120 121Info::Info() 122 : flags(none), precision(-1), prereq(0), storageParams(NULL) 123{ 124 id = id_count++; 125 if (debug_break_id >= 0 and debug_break_id == id) 126 debug_break(); 127} 128 129Info::~Info() 130{ 131} 132 133bool 134Info::less(Info *stat1, Info *stat2) 135{ 136 const string &name1 = stat1->name; 137 const string &name2 = stat2->name; 138 139 vector<string> v1; 140 vector<string> v2; 141 142 tokenize(v1, name1, '.'); 143 tokenize(v2, name2, '.'); 144 145 size_type last = min(v1.size(), v2.size()) - 1; 146 for (off_type i = 0; i < last; ++i) 147 if (v1[i] != v2[i]) 148 return v1[i] < v2[i]; 149 150 // Special compare for last element. 151 if (v1[last] == v2[last]) 152 return v1.size() < v2.size(); 153 else 154 return v1[last] < v2[last]; 155 156 return false; 157} 158 159bool 160Info::baseCheck() const 161{ 162 if (!(flags & Stats::init)) { 163#ifdef DEBUG 164 cprintf("this is stat number %d\n", id); 165#endif 166 panic("Not all stats have been initialized"); 167 return false; 168 } 169 170 if ((flags & print) && name.empty()) { 171 panic("all printable stats must be named"); 172 return false; 173 } 174 175 return true; 176} 177
|
| 178void 179Info::enable() 180{ 181}
|
177
| 182
|
| 183void 184VectorInfoBase::enable() 185{ 186 size_type s = size(); 187 if (subnames.size() < s) 188 subnames.resize(s); 189 if (subdescs.size() < s) 190 subdescs.resize(s); 191} 192 193void 194VectorDistInfoBase::enable() 195{ 196 size_type s = size(); 197 if (subnames.size() < s) 198 subnames.resize(s); 199 if (subdescs.size() < s) 200 subdescs.resize(s); 201} 202 203void 204Vector2dInfoBase::enable() 205{ 206 if (subnames.size() < x) 207 subnames.resize(x); 208 if (subdescs.size() < x) 209 subdescs.resize(x); 210 if (y_subnames.size() < y) 211 y_subnames.resize(y); 212} 213
|
178Formula::Formula() 179{ 180 setInit(); 181} 182 183Formula::Formula(Temp r) 184{ 185 root = r; 186 assert(size()); 187} 188 189const Formula & 190Formula::operator=(Temp r) 191{ 192 assert(!root && "Can't change formulas"); 193 root = r; 194 assert(size()); 195 return *this; 196} 197 198const Formula & 199Formula::operator+=(Temp r) 200{ 201 if (root) 202 root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 203 else 204 root = r; 205 assert(size()); 206 return *this; 207} 208 209void 210Formula::result(VResult &vec) const 211{ 212 if (root) 213 vec = root->result(); 214} 215 216Result 217Formula::total() const 218{ 219 return root ? root->total() : 0.0; 220} 221 222size_type 223Formula::size() const 224{ 225 if (!root) 226 return 0; 227 else 228 return root->size(); 229} 230 231void 232Formula::reset() 233{ 234} 235 236bool 237Formula::zero() const 238{ 239 VResult vec; 240 result(vec); 241 for (off_t i = 0; i < vec.size(); ++i) 242 if (vec[i] != 0.0) 243 return false; 244 return true; 245} 246
| 214Formula::Formula() 215{ 216 setInit(); 217} 218 219Formula::Formula(Temp r) 220{ 221 root = r; 222 assert(size()); 223} 224 225const Formula & 226Formula::operator=(Temp r) 227{ 228 assert(!root && "Can't change formulas"); 229 root = r; 230 assert(size()); 231 return *this; 232} 233 234const Formula & 235Formula::operator+=(Temp r) 236{ 237 if (root) 238 root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 239 else 240 root = r; 241 assert(size()); 242 return *this; 243} 244 245void 246Formula::result(VResult &vec) const 247{ 248 if (root) 249 vec = root->result(); 250} 251 252Result 253Formula::total() const 254{ 255 return root ? root->total() : 0.0; 256} 257 258size_type 259Formula::size() const 260{ 261 if (!root) 262 return 0; 263 else 264 return root->size(); 265} 266 267void 268Formula::reset() 269{ 270} 271 272bool 273Formula::zero() const 274{ 275 VResult vec; 276 result(vec); 277 for (off_t i = 0; i < vec.size(); ++i) 278 if (vec[i] != 0.0) 279 return false; 280 return true; 281} 282
|
247void 248Formula::update() 249{ 250} 251
| |
252string 253Formula::str() const 254{ 255 return root ? root->str() : ""; 256} 257 258void
| 283string 284Formula::str() const 285{ 286 return root ? root->str() : ""; 287} 288 289void
|
259check()
| 290enable()
|
260{ 261 typedef list<Info *>::iterator iter_t; 262 263 iter_t i, end = statsList().end(); 264 for (i = statsList().begin(); i != end; ++i) { 265 Info *info = *i; 266 assert(info); 267 if (!info->check() || !info->baseCheck()) 268 panic("stat check failed for '%s' %d\n", info->name, info->id); 269 } 270 271 off_t j = 0; 272 for (i = statsList().begin(); i != end; ++i) { 273 Info *info = *i; 274 if (!(info->flags & print)) 275 info->name = "__Stat" + to_string(j++); 276 } 277 278 statsList().sort(Info::less); 279
| 291{ 292 typedef list<Info *>::iterator iter_t; 293 294 iter_t i, end = statsList().end(); 295 for (i = statsList().begin(); i != end; ++i) { 296 Info *info = *i; 297 assert(info); 298 if (!info->check() || !info->baseCheck()) 299 panic("stat check failed for '%s' %d\n", info->name, info->id); 300 } 301 302 off_t j = 0; 303 for (i = statsList().begin(); i != end; ++i) { 304 Info *info = *i; 305 if (!(info->flags & print)) 306 info->name = "__Stat" + to_string(j++); 307 } 308 309 statsList().sort(Info::less); 310
|
280 if (i == end) 281 return; 282 283 iter_t last = i; 284 ++i; 285
| |
286 for (i = statsList().begin(); i != end; ++i) {
| 311 for (i = statsList().begin(); i != end; ++i) {
|
287 if ((*i)->name == (*last)->name) 288 panic("same name used twice! name=%s\n", (*i)->name);
| 312 Info *info = *i; 313 info->enable(); 314 } 315}
|
289
| 316
|
290 last = i;
| 317void 318prepare() 319{ 320 list<Info *>::iterator i = statsList().begin(); 321 list<Info *>::iterator end = statsList().end(); 322 while (i != end) { 323 Info *info = *i; 324 info->prepare(); 325 ++i;
|
291 } 292} 293 294CallbackQueue resetQueue; 295 296void 297reset() 298{ 299 list<Info *>::iterator i = statsList().begin(); 300 list<Info *>::iterator end = statsList().end(); 301 while (i != end) { 302 Info *info = *i; 303 info->reset(); 304 ++i; 305 } 306 307 resetQueue.process(); 308} 309 310void 311registerResetCallback(Callback *cb) 312{ 313 resetQueue.add(cb); 314} 315 316/* namespace Stats */ }
| 326 } 327} 328 329CallbackQueue resetQueue; 330 331void 332reset() 333{ 334 list<Info *>::iterator i = statsList().begin(); 335 list<Info *>::iterator end = statsList().end(); 336 while (i != end) { 337 Info *info = *i; 338 info->reset(); 339 ++i; 340 } 341 342 resetQueue.process(); 343} 344 345void 346registerResetCallback(Callback *cb) 347{ 348 resetQueue.add(cb); 349} 350 351/* namespace Stats */ }
|