statistics.cc revision 11793:ef606668d247
16145Snate@binkert.org/* 26145Snate@binkert.org * Copyright (c) 2003-2005 The Regents of The University of Michigan 36145Snate@binkert.org * All rights reserved. 46145Snate@binkert.org * 56145Snate@binkert.org * Redistribution and use in source and binary forms, with or without 66145Snate@binkert.org * modification, are permitted provided that the following conditions are 76145Snate@binkert.org * met: redistributions of source code must retain the above copyright 86145Snate@binkert.org * notice, this list of conditions and the following disclaimer; 96145Snate@binkert.org * redistributions in binary form must reproduce the above copyright 106145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 116145Snate@binkert.org * documentation and/or other materials provided with the distribution; 126145Snate@binkert.org * neither the name of the copyright holders nor the names of its 136145Snate@binkert.org * contributors may be used to endorse or promote products derived from 146145Snate@binkert.org * this software without specific prior written permission. 156145Snate@binkert.org * 166145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276145Snate@binkert.org * 286145Snate@binkert.org * Authors: Nathan Binkert 296145Snate@binkert.org */ 306145Snate@binkert.org 316145Snate@binkert.org#include "base/statistics.hh" 326145Snate@binkert.org 336145Snate@binkert.org#include <fstream> 346145Snate@binkert.org#include <iomanip> 356145Snate@binkert.org#include <list> 366145Snate@binkert.org#include <map> 376145Snate@binkert.org#include <string> 386145Snate@binkert.org 396145Snate@binkert.org#include "base/callback.hh" 406145Snate@binkert.org#include "base/cprintf.hh" 416145Snate@binkert.org#include "base/debug.hh" 426145Snate@binkert.org#include "base/hostinfo.hh" 436145Snate@binkert.org#include "base/misc.hh" 446145Snate@binkert.org#include "base/str.hh" 457002Snate@binkert.org#include "base/time.hh" 467002Snate@binkert.org#include "base/trace.hh" 477002Snate@binkert.org 487002Snate@binkert.orgusing namespace std; 497048Snate@binkert.org 507048Snate@binkert.orgnamespace Stats { 517048Snate@binkert.org 527048Snate@binkert.orgstd::string Info::separatorString = "::"; 537048Snate@binkert.org 547048Snate@binkert.org// We wrap these in a function to make sure they're built in time. 557048Snate@binkert.orglist<Info *> & 567048Snate@binkert.orgstatsList() 577048Snate@binkert.org{ 586154Snate@binkert.org static list<Info *> the_list; 596154Snate@binkert.org return the_list; 606876Ssteve.reinhardt@amd.com} 616876Ssteve.reinhardt@amd.com 627048Snate@binkert.orgMapType & 636145Snate@binkert.orgstatsMap() 646145Snate@binkert.org{ 656145Snate@binkert.org static MapType the_map; 666145Snate@binkert.org return the_map; 676876Ssteve.reinhardt@amd.com} 686876Ssteve.reinhardt@amd.com 696145Snate@binkert.orgvoid 707048Snate@binkert.orgInfoAccess::setInfo(Info *info) 716145Snate@binkert.org{ 727048Snate@binkert.org if (statsMap().find(this) != statsMap().end()) 737048Snate@binkert.org panic("shouldn't register stat twice!"); 746285Snate@binkert.org 757048Snate@binkert.org statsList().push_back(info); 767048Snate@binkert.org 777048Snate@binkert.org#ifndef NDEBUG 786145Snate@binkert.org pair<MapType::iterator, bool> result = 797048Snate@binkert.org#endif 807048Snate@binkert.org statsMap().insert(make_pair(this, info)); 816876Ssteve.reinhardt@amd.com assert(result.second && "this should never fail"); 827048Snate@binkert.org assert(statsMap().find(this) != statsMap().end()); 836896SBrad.Beckmann@amd.com} 847048Snate@binkert.org 857048Snate@binkert.orgvoid 866285Snate@binkert.orgInfoAccess::setParams(const StorageParams *params) 877048Snate@binkert.org{ 887048Snate@binkert.org info()->storageParams = params; 897048Snate@binkert.org} 906285Snate@binkert.org 917048Snate@binkert.orgvoid 927048Snate@binkert.orgInfoAccess::setInit() 937048Snate@binkert.org{ 947048Snate@binkert.org info()->flags.set(init); 957048Snate@binkert.org} 966285Snate@binkert.org 976285Snate@binkert.orgInfo * 986889SBrad.Beckmann@amd.comInfoAccess::info() 996889SBrad.Beckmann@amd.com{ 1007048Snate@binkert.org MapType::const_iterator i = statsMap().find(this); 1017048Snate@binkert.org assert(i != statsMap().end()); 1027048Snate@binkert.org return (*i).second; 1036889SBrad.Beckmann@amd.com} 1047048Snate@binkert.org 1056889SBrad.Beckmann@amd.comconst Info * 1066889SBrad.Beckmann@amd.comInfoAccess::info() const 1077048Snate@binkert.org{ 1087048Snate@binkert.org MapType::const_iterator i = statsMap().find(this); 1096145Snate@binkert.org assert(i != statsMap().end()); 1107048Snate@binkert.org return (*i).second; 1116145Snate@binkert.org} 1127048Snate@binkert.org 1137048Snate@binkert.orgStorageParams::~StorageParams() 1146145Snate@binkert.org{ 1157048Snate@binkert.org} 1167048Snate@binkert.org 1177048Snate@binkert.orgNameMapType & 1187048Snate@binkert.orgnameMap() 1197048Snate@binkert.org{ 1206145Snate@binkert.org static NameMapType the_map; 1217048Snate@binkert.org return the_map; 1226889SBrad.Beckmann@amd.com} 1237048Snate@binkert.org 1247048Snate@binkert.orgint Info::id_count = 0; 1257048Snate@binkert.org 1266889SBrad.Beckmann@amd.comint debug_break_id = -1; 1277048Snate@binkert.org 1287048Snate@binkert.orgInfo::Info() 1297048Snate@binkert.org : flags(none), precision(-1), prereq(0), storageParams(NULL) 1307048Snate@binkert.org{ 1316889SBrad.Beckmann@amd.com id = id_count++; 1326145Snate@binkert.org if (debug_break_id >= 0 and debug_break_id == id) 1336145Snate@binkert.org Debug::breakpoint(); 1346145Snate@binkert.org} 1356145Snate@binkert.org 1367048Snate@binkert.orgInfo::~Info() 1377048Snate@binkert.org{ 1386145Snate@binkert.org} 1396145Snate@binkert.org 1407048Snate@binkert.orgbool 1417048Snate@binkert.orgvalidateStatName(const string &name) 1427048Snate@binkert.org{ 1437048Snate@binkert.org if (name.empty()) 1447048Snate@binkert.org return false; 1457048Snate@binkert.org 1467048Snate@binkert.org vector<string> vec; 1477048Snate@binkert.org tokenize(vec, name, '.'); 1487048Snate@binkert.org vector<string>::const_iterator item = vec.begin(); 1497048Snate@binkert.org while (item != vec.end()) { 1507048Snate@binkert.org if (item->empty()) 1517048Snate@binkert.org return false; 1526145Snate@binkert.org 1536145Snate@binkert.org string::const_iterator c = item->begin(); 1547048Snate@binkert.org 1557048Snate@binkert.org // The first character is different 1567048Snate@binkert.org if (!isalpha(*c) && *c != '_') 1577048Snate@binkert.org return false; 1587048Snate@binkert.org 1597048Snate@binkert.org // The rest of the characters have different rules. 1607048Snate@binkert.org while (++c != item->end()) { 1617048Snate@binkert.org if (!isalnum(*c) && *c != '_') 1627048Snate@binkert.org return false; 1637048Snate@binkert.org } 1647048Snate@binkert.org 1657048Snate@binkert.org ++item; 1667048Snate@binkert.org } 1677048Snate@binkert.org 1687048Snate@binkert.org return true; 1697048Snate@binkert.org} 1707048Snate@binkert.org 1717048Snate@binkert.orgvoid 1727048Snate@binkert.orgInfo::setName(const string &name) 1737048Snate@binkert.org{ 1747048Snate@binkert.org if (!validateStatName(name)) 1757048Snate@binkert.org panic("invalid stat name '%s'", name); 1767048Snate@binkert.org 1777048Snate@binkert.org pair<NameMapType::iterator, bool> p = 1787048Snate@binkert.org nameMap().insert(make_pair(name, this)); 1797048Snate@binkert.org 1807048Snate@binkert.org Info *other = p.first->second; 1817048Snate@binkert.org bool result = p.second; 1827048Snate@binkert.org 1837048Snate@binkert.org if (!result) { 1847048Snate@binkert.org // using other->name instead of just name to avoid a compiler 1857048Snate@binkert.org // warning. They should be the same. 1867048Snate@binkert.org panic("same statistic name used twice! name=%s\n", other->name); 1877048Snate@binkert.org } 1887048Snate@binkert.org 1897048Snate@binkert.org this->name = name; 1907048Snate@binkert.org} 1917048Snate@binkert.org 1927048Snate@binkert.orgbool 1937048Snate@binkert.orgInfo::less(Info *stat1, Info *stat2) 1947048Snate@binkert.org{ 1957048Snate@binkert.org const string &name1 = stat1->name; 1967048Snate@binkert.org const string &name2 = stat2->name; 1977048Snate@binkert.org 1987048Snate@binkert.org vector<string> v1; 1997048Snate@binkert.org vector<string> v2; 2007048Snate@binkert.org 2017048Snate@binkert.org tokenize(v1, name1, '.'); 2027048Snate@binkert.org tokenize(v2, name2, '.'); 2037048Snate@binkert.org 2047048Snate@binkert.org size_type last = min(v1.size(), v2.size()) - 1; 2057048Snate@binkert.org for (off_type i = 0; i < last; ++i) 2067048Snate@binkert.org if (v1[i] != v2[i]) 2077048Snate@binkert.org return v1[i] < v2[i]; 2087048Snate@binkert.org 2097048Snate@binkert.org // Special compare for last element. 2107048Snate@binkert.org if (v1[last] == v2[last]) 2117048Snate@binkert.org return v1.size() < v2.size(); 2127048Snate@binkert.org else 2137048Snate@binkert.org return v1[last] < v2[last]; 2147048Snate@binkert.org 2157048Snate@binkert.org return false; 2167048Snate@binkert.org} 2177048Snate@binkert.org 2187048Snate@binkert.orgbool 2196145Snate@binkert.orgInfo::baseCheck() const 2206145Snate@binkert.org{ 2217048Snate@binkert.org if (!(flags & Stats::init)) { 2227048Snate@binkert.org#ifdef DEBUG 2237048Snate@binkert.org cprintf("this is stat number %d\n", id); 2246145Snate@binkert.org#endif 2256145Snate@binkert.org panic("Not all stats have been initialized.\n" 2267048Snate@binkert.org "You may need to add <ParentClass>::regStats() to a" 2277048Snate@binkert.org " new SimObject's regStats() function."); 2287048Snate@binkert.org return false; 2297048Snate@binkert.org } 2307048Snate@binkert.org 2317048Snate@binkert.org if ((flags & display) && name.empty()) { 2327048Snate@binkert.org panic("all printable stats must be named"); 2337048Snate@binkert.org return false; 2346145Snate@binkert.org } 2356145Snate@binkert.org 2367048Snate@binkert.org return true; 2377048Snate@binkert.org} 2387048Snate@binkert.org 2397048Snate@binkert.orgvoid 2407048Snate@binkert.orgInfo::enable() 2417048Snate@binkert.org{ 2427048Snate@binkert.org} 2436145Snate@binkert.org 2446145Snate@binkert.orgvoid 2457048Snate@binkert.orgVectorInfo::enable() 2467048Snate@binkert.org{ 2476145Snate@binkert.org size_type s = size(); 2487048Snate@binkert.org if (subnames.size() < s) 2497048Snate@binkert.org subnames.resize(s); 2507048Snate@binkert.org if (subdescs.size() < s) 2517048Snate@binkert.org subdescs.resize(s); 2527048Snate@binkert.org} 2537048Snate@binkert.org 2547048Snate@binkert.orgvoid 2557048Snate@binkert.orgVectorDistInfo::enable() 2567048Snate@binkert.org{ 2577048Snate@binkert.org size_type s = size(); 2587048Snate@binkert.org if (subnames.size() < s) 2597048Snate@binkert.org subnames.resize(s); 2607048Snate@binkert.org if (subdescs.size() < s) 2617048Snate@binkert.org subdescs.resize(s); 2627048Snate@binkert.org} 2637048Snate@binkert.org 2647048Snate@binkert.orgvoid 2657048Snate@binkert.orgVector2dInfo::enable() 2667048Snate@binkert.org{ 2677048Snate@binkert.org if (subnames.size() < x) 2687048Snate@binkert.org subnames.resize(x); 2697048Snate@binkert.org if (subdescs.size() < x) 2707048Snate@binkert.org subdescs.resize(x); 2717048Snate@binkert.org if (y_subnames.size() < y) 2726145Snate@binkert.org y_subnames.resize(y); 2736145Snate@binkert.org} 2747048Snate@binkert.org 2757048Snate@binkert.orgvoid 2767048Snate@binkert.orgHistStor::grow_out() 2777048Snate@binkert.org{ 2787048Snate@binkert.org int size = cvec.size(); 2797048Snate@binkert.org int zero = size / 2; // round down! 2807048Snate@binkert.org int top_half = zero + (size - zero + 1) / 2; // round up! 2817048Snate@binkert.org int bottom_half = (size - zero) / 2; // round down! 2827048Snate@binkert.org 2837048Snate@binkert.org // grow down 2847048Snate@binkert.org int low_pair = zero - 1; 2857048Snate@binkert.org for (int i = zero - 1; i >= bottom_half; i--) { 2867048Snate@binkert.org cvec[i] = cvec[low_pair]; 2877048Snate@binkert.org if (low_pair - 1 >= 0) 2887048Snate@binkert.org cvec[i] += cvec[low_pair - 1]; 2897048Snate@binkert.org low_pair -= 2; 2906145Snate@binkert.org } 2917048Snate@binkert.org assert(low_pair == 0 || low_pair == -1 || low_pair == -2); 2927048Snate@binkert.org 2937048Snate@binkert.org for (int i = bottom_half - 1; i >= 0; i--) 2947048Snate@binkert.org cvec[i] = Counter(); 2957048Snate@binkert.org 2967048Snate@binkert.org // grow up 2977048Snate@binkert.org int high_pair = zero; 2987048Snate@binkert.org for (int i = zero; i < top_half; i++) { 2997048Snate@binkert.org cvec[i] = cvec[high_pair]; 3007048Snate@binkert.org if (high_pair + 1 < size) 3017048Snate@binkert.org cvec[i] += cvec[high_pair + 1]; 3027048Snate@binkert.org high_pair += 2; 3037048Snate@binkert.org } 3047048Snate@binkert.org assert(high_pair == size || high_pair == size + 1); 3057048Snate@binkert.org 3067048Snate@binkert.org for (int i = top_half; i < size; i++) 3077048Snate@binkert.org cvec[i] = Counter(); 3087048Snate@binkert.org 3097048Snate@binkert.org max_bucket *= 2; 3107048Snate@binkert.org min_bucket *= 2; 3117048Snate@binkert.org bucket_size *= 2; 3127048Snate@binkert.org} 3137048Snate@binkert.org 3147048Snate@binkert.orgvoid 3157048Snate@binkert.orgHistStor::grow_convert() 3167048Snate@binkert.org{ 3177048Snate@binkert.org int size = cvec.size(); 3187048Snate@binkert.org int half = (size + 1) / 2; // round up! 3197048Snate@binkert.org //bool even = (size & 1) == 0; 3207048Snate@binkert.org 3217048Snate@binkert.org int pair = size - 1; 3227048Snate@binkert.org for (int i = size - 1; i >= half; --i) { 3237048Snate@binkert.org cvec[i] = cvec[pair]; 3247048Snate@binkert.org if (pair - 1 >= 0) 3257048Snate@binkert.org cvec[i] += cvec[pair - 1]; 3267048Snate@binkert.org pair -= 2; 3277048Snate@binkert.org } 3287048Snate@binkert.org 3297048Snate@binkert.org for (int i = half - 1; i >= 0; i--) 3307048Snate@binkert.org cvec[i] = Counter(); 3317048Snate@binkert.org 3327048Snate@binkert.org min_bucket = -max_bucket;// - (even ? bucket_size : 0); 3337048Snate@binkert.org bucket_size *= 2; 3347048Snate@binkert.org} 3357048Snate@binkert.org 3367048Snate@binkert.orgvoid 3377048Snate@binkert.orgHistStor::grow_up() 3387048Snate@binkert.org{ 3397048Snate@binkert.org int size = cvec.size(); 3407048Snate@binkert.org int half = (size + 1) / 2; // round up! 3417048Snate@binkert.org 3427048Snate@binkert.org int pair = 0; 3437048Snate@binkert.org for (int i = 0; i < half; i++) { 3447048Snate@binkert.org cvec[i] = cvec[pair]; 3457048Snate@binkert.org if (pair + 1 < size) 3467048Snate@binkert.org cvec[i] += cvec[pair + 1]; 3477048Snate@binkert.org pair += 2; 3487048Snate@binkert.org } 3497048Snate@binkert.org assert(pair == size || pair == size + 1); 3507048Snate@binkert.org 3517048Snate@binkert.org for (int i = half; i < size; i++) 3527048Snate@binkert.org cvec[i] = Counter(); 3537048Snate@binkert.org 3547048Snate@binkert.org max_bucket *= 2; 3557048Snate@binkert.org bucket_size *= 2; 3567048Snate@binkert.org} 3577048Snate@binkert.org 3587048Snate@binkert.orgvoid 3597048Snate@binkert.orgHistStor::add(HistStor *hs) 3607048Snate@binkert.org{ 3617048Snate@binkert.org int b_size = hs->size(); 3627048Snate@binkert.org assert(size() == b_size); 3637048Snate@binkert.org assert(min_bucket == hs->min_bucket); 3647048Snate@binkert.org 3657048Snate@binkert.org sum += hs->sum; 3667048Snate@binkert.org logs += hs->logs; 3677048Snate@binkert.org squares += hs->squares; 3687048Snate@binkert.org samples += hs->samples; 3697048Snate@binkert.org 3707048Snate@binkert.org while (bucket_size > hs->bucket_size) 3717048Snate@binkert.org hs->grow_up(); 3727048Snate@binkert.org while (bucket_size < hs->bucket_size) 3737048Snate@binkert.org grow_up(); 3747048Snate@binkert.org 3757048Snate@binkert.org for (uint32_t i = 0; i < b_size; i++) 3767048Snate@binkert.org cvec[i] += hs->cvec[i]; 3777048Snate@binkert.org} 3787048Snate@binkert.org 3797048Snate@binkert.orgFormula::Formula() 3807048Snate@binkert.org{ 3817048Snate@binkert.org} 3827048Snate@binkert.org 3837048Snate@binkert.orgFormula::Formula(Temp r) 3847048Snate@binkert.org{ 3857048Snate@binkert.org root = r.getNodePtr(); 3867048Snate@binkert.org setInit(); 3877048Snate@binkert.org assert(size()); 3887048Snate@binkert.org} 3897048Snate@binkert.org 3907048Snate@binkert.orgconst Formula & 3917048Snate@binkert.orgFormula::operator=(Temp r) 3926145Snate@binkert.org{ 3936145Snate@binkert.org assert(!root && "Can't change formulas"); 3947048Snate@binkert.org root = r.getNodePtr(); 3957048Snate@binkert.org setInit(); 3966145Snate@binkert.org assert(size()); 3977048Snate@binkert.org return *this; 3987048Snate@binkert.org} 3997048Snate@binkert.org 4006145Snate@binkert.orgconst Formula & 4017048Snate@binkert.orgFormula::operator+=(Temp r) 4027048Snate@binkert.org{ 4036145Snate@binkert.org if (root) 4047048Snate@binkert.org root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 4057048Snate@binkert.org else { 4066145Snate@binkert.org root = r.getNodePtr(); 4077048Snate@binkert.org setInit(); 4087048Snate@binkert.org } 4097048Snate@binkert.org 4107048Snate@binkert.org assert(size()); 4117048Snate@binkert.org return *this; 4127048Snate@binkert.org} 4137048Snate@binkert.org 4146145Snate@binkert.orgconst Formula & 4156145Snate@binkert.orgFormula::operator/=(Temp r) 4167048Snate@binkert.org{ 4177048Snate@binkert.org assert (root); 4186145Snate@binkert.org root = NodePtr(new BinaryNode<std::divides<Result> >(root, r)); 4197048Snate@binkert.org 4206145Snate@binkert.org assert(size()); 4217048Snate@binkert.org return *this; 4227048Snate@binkert.org} 4237048Snate@binkert.org 4247048Snate@binkert.orgvoid 4257048Snate@binkert.orgFormula::result(VResult &vec) const 4267048Snate@binkert.org{ 4277048Snate@binkert.org if (root) 4286145Snate@binkert.org vec = root->result(); 4296145Snate@binkert.org} 4307048Snate@binkert.org 4317048Snate@binkert.orgResult 4327048Snate@binkert.orgFormula::total() const 4337048Snate@binkert.org{ 4347048Snate@binkert.org return root ? root->total() : 0.0; 4357048Snate@binkert.org} 4367048Snate@binkert.org 4376145Snate@binkert.orgsize_type 4387048Snate@binkert.orgFormula::size() const 4396145Snate@binkert.org{ 4407048Snate@binkert.org if (!root) 4417048Snate@binkert.org return 0; 4427048Snate@binkert.org else 4437048Snate@binkert.org return root->size(); 4447048Snate@binkert.org} 4457048Snate@binkert.org 4467048Snate@binkert.orgvoid 4476145Snate@binkert.orgFormula::reset() 4487048Snate@binkert.org{ 4497048Snate@binkert.org} 4507048Snate@binkert.org 4517048Snate@binkert.orgbool 4527048Snate@binkert.orgFormula::zero() const 4537048Snate@binkert.org{ 4547048Snate@binkert.org VResult vec; 4557048Snate@binkert.org result(vec); 4567048Snate@binkert.org for (VResult::size_type i = 0; i < vec.size(); ++i) 4576145Snate@binkert.org if (vec[i] != 0.0) 4587048Snate@binkert.org return false; 4597048Snate@binkert.org return true; 4607048Snate@binkert.org} 4617048Snate@binkert.org 4627048Snate@binkert.orgstring 4637048Snate@binkert.orgFormula::str() const 4647048Snate@binkert.org{ 4657048Snate@binkert.org return root ? root->str() : ""; 4667048Snate@binkert.org} 4676145Snate@binkert.org 4687048Snate@binkert.orgHandler resetHandler = NULL; 4697048Snate@binkert.orgHandler dumpHandler = NULL; 4707048Snate@binkert.org 4717048Snate@binkert.orgvoid 4727048Snate@binkert.orgregisterHandlers(Handler reset_handler, Handler dump_handler) 4737048Snate@binkert.org{ 4746145Snate@binkert.org resetHandler = reset_handler; 4757048Snate@binkert.org dumpHandler = dump_handler; 4767048Snate@binkert.org} 4776145Snate@binkert.org 4787048Snate@binkert.orgCallbackQueue dumpQueue; 4797048Snate@binkert.orgCallbackQueue resetQueue; 4806145Snate@binkert.org 4817048Snate@binkert.orgvoid 4827048Snate@binkert.orgprocessResetQueue() 4836145Snate@binkert.org{ 4847048Snate@binkert.org resetQueue.process(); 4857048Snate@binkert.org} 4867048Snate@binkert.org 4876145Snate@binkert.orgvoid 4887048Snate@binkert.orgprocessDumpQueue() 4897048Snate@binkert.org{ 4906145Snate@binkert.org dumpQueue.process(); 4916145Snate@binkert.org} 4927048Snate@binkert.org 4937048Snate@binkert.orgvoid 4946145Snate@binkert.orgregisterResetCallback(Callback *cb) 4957048Snate@binkert.org{ 4967048Snate@binkert.org resetQueue.add(cb); 4977048Snate@binkert.org} 4987048Snate@binkert.org 4996145Snate@binkert.orgbool _enabled = false; 5007048Snate@binkert.org 5017048Snate@binkert.orgbool 5027048Snate@binkert.orgenabled() 5037048Snate@binkert.org{ 5047048Snate@binkert.org return _enabled; 5057048Snate@binkert.org} 5066145Snate@binkert.org 5076145Snate@binkert.orgvoid 5087048Snate@binkert.orgenable() 5097048Snate@binkert.org{ 5107048Snate@binkert.org if (_enabled) 5117048Snate@binkert.org fatal("Stats are already enabled"); 5126145Snate@binkert.org 5137048Snate@binkert.org _enabled = true; 5147048Snate@binkert.org} 5157048Snate@binkert.org 5167048Snate@binkert.orgvoid 5177048Snate@binkert.orgdump() 5187048Snate@binkert.org{ 5196145Snate@binkert.org if (dumpHandler) 5207048Snate@binkert.org dumpHandler(); 5217048Snate@binkert.org else 5227048Snate@binkert.org fatal("No registered Stats::dump handler"); 5237048Snate@binkert.org} 5247048Snate@binkert.org 5257048Snate@binkert.orgvoid 5266145Snate@binkert.orgreset() 5277048Snate@binkert.org{ 5287048Snate@binkert.org if (resetHandler) 5297048Snate@binkert.org resetHandler(); 5307048Snate@binkert.org else 5317048Snate@binkert.org fatal("No registered Stats::reset handler"); 5326145Snate@binkert.org} 5336145Snate@binkert.org 5347048Snate@binkert.orgvoid 5357048Snate@binkert.orgregisterDumpCallback(Callback *cb) 5367048Snate@binkert.org{ 5377048Snate@binkert.org dumpQueue.add(cb); 5387048Snate@binkert.org} 5397048Snate@binkert.org 5407048Snate@binkert.org} // namespace Stats 5417048Snate@binkert.org 5427048Snate@binkert.orgvoid 5436145Snate@binkert.orgdebugDumpStats() 5446145Snate@binkert.org{ 5456145Snate@binkert.org Stats::dump(); 5467048Snate@binkert.org} 5477048Snate@binkert.org