statistics.cc revision 14266
12SN/A/* 214205Sandreas.sandberg@arm.com * Copyright (c) 2019 Arm Limited 314205Sandreas.sandberg@arm.com * All rights reserved. 414205Sandreas.sandberg@arm.com * 514205Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 614205Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 714205Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 814205Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 914205Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1014205Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1114205Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1214205Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1314205Sandreas.sandberg@arm.com * 141762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 152SN/A * All rights reserved. 162SN/A * 172SN/A * Redistribution and use in source and binary forms, with or without 182SN/A * modification, are permitted provided that the following conditions are 192SN/A * met: redistributions of source code must retain the above copyright 202SN/A * notice, this list of conditions and the following disclaimer; 212SN/A * redistributions in binary form must reproduce the above copyright 222SN/A * notice, this list of conditions and the following disclaimer in the 232SN/A * documentation and/or other materials provided with the distribution; 242SN/A * neither the name of the copyright holders nor the names of its 252SN/A * contributors may be used to endorse or promote products derived from 262SN/A * this software without specific prior written permission. 272SN/A * 282SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392665Ssaidi@eecs.umich.edu * 402665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 412SN/A */ 422SN/A 4311793Sbrandon.potter@amd.com#include "base/statistics.hh" 4411793Sbrandon.potter@amd.com 458229Snate@binkert.org#include <fstream> 462SN/A#include <iomanip> 472SN/A#include <list> 482SN/A#include <map> 492SN/A#include <string> 502SN/A 51148SN/A#include "base/callback.hh" 5256SN/A#include "base/cprintf.hh" 535889Snate@binkert.org#include "base/debug.hh" 54441SN/A#include "base/hostinfo.hh" 5512334Sgabeblack@google.com#include "base/logging.hh" 5656SN/A#include "base/str.hh" 57441SN/A#include "base/time.hh" 58433SN/A#include "base/trace.hh" 592SN/A 602SN/Ausing namespace std; 612SN/A 62729SN/Anamespace Stats { 63388SN/A 648243Sbradley.danofsky@amd.comstd::string Info::separatorString = "::"; 655887Snate@binkert.org 665887Snate@binkert.org// We wrap these in a function to make sure they're built in time. 675887Snate@binkert.orglist<Info *> & 685887Snate@binkert.orgstatsList() 69388SN/A{ 705887Snate@binkert.org static list<Info *> the_list; 715887Snate@binkert.org return the_list; 72388SN/A} 73388SN/A 745887Snate@binkert.orgMapType & 755887Snate@binkert.orgstatsMap() 76441SN/A{ 775887Snate@binkert.org static MapType the_map; 785887Snate@binkert.org return the_map; 79441SN/A} 80441SN/A 81388SN/Avoid 8214205Sandreas.sandberg@arm.comInfoAccess::setInfo(Group *parent, Info *info) 83388SN/A{ 8414205Sandreas.sandberg@arm.com panic_if(statsMap().find(this) != statsMap().end() || 8514205Sandreas.sandberg@arm.com _info != nullptr, 8614205Sandreas.sandberg@arm.com "shouldn't register stat twice!"); 8714205Sandreas.sandberg@arm.com 8814205Sandreas.sandberg@arm.com // New-style stats are reachable through the hierarchy and 8914205Sandreas.sandberg@arm.com // shouldn't be added to the global lists. 9014205Sandreas.sandberg@arm.com if (parent) { 9114205Sandreas.sandberg@arm.com _info = info; 9214205Sandreas.sandberg@arm.com return; 9314205Sandreas.sandberg@arm.com } 945887Snate@binkert.org 955887Snate@binkert.org statsList().push_back(info); 965887Snate@binkert.org 975887Snate@binkert.org#ifndef NDEBUG 985887Snate@binkert.org pair<MapType::iterator, bool> result = 995887Snate@binkert.org#endif 1005887Snate@binkert.org statsMap().insert(make_pair(this, info)); 1015887Snate@binkert.org assert(result.second && "this should never fail"); 1025887Snate@binkert.org assert(statsMap().find(this) != statsMap().end()); 103388SN/A} 104388SN/A 105388SN/Avoid 1065889Snate@binkert.orgInfoAccess::setParams(const StorageParams *params) 1075889Snate@binkert.org{ 1085889Snate@binkert.org info()->storageParams = params; 1095889Snate@binkert.org} 1105889Snate@binkert.org 1115889Snate@binkert.orgvoid 1125886Snate@binkert.orgInfoAccess::setInit() 113388SN/A{ 1146130Snate@binkert.org info()->flags.set(init); 115388SN/A} 116388SN/A 1175886Snate@binkert.orgInfo * 1185886Snate@binkert.orgInfoAccess::info() 119388SN/A{ 12014205Sandreas.sandberg@arm.com if (_info) { 12114205Sandreas.sandberg@arm.com // New-style stats 12214205Sandreas.sandberg@arm.com return _info; 12314205Sandreas.sandberg@arm.com } else { 12414205Sandreas.sandberg@arm.com // Legacy stats 12514205Sandreas.sandberg@arm.com MapType::const_iterator i = statsMap().find(this); 12614205Sandreas.sandberg@arm.com assert(i != statsMap().end()); 12714205Sandreas.sandberg@arm.com return (*i).second; 12814205Sandreas.sandberg@arm.com } 129388SN/A} 130388SN/A 1315886Snate@binkert.orgconst Info * 1325886Snate@binkert.orgInfoAccess::info() const 1335886Snate@binkert.org{ 13414205Sandreas.sandberg@arm.com if (_info) { 13514205Sandreas.sandberg@arm.com // New-style stats 13614205Sandreas.sandberg@arm.com return _info; 13714205Sandreas.sandberg@arm.com } else { 13814205Sandreas.sandberg@arm.com // Legacy stats 13914205Sandreas.sandberg@arm.com MapType::const_iterator i = statsMap().find(this); 14014205Sandreas.sandberg@arm.com assert(i != statsMap().end()); 14114205Sandreas.sandberg@arm.com return (*i).second; 14214205Sandreas.sandberg@arm.com } 1435886Snate@binkert.org} 1445886Snate@binkert.org 1455889Snate@binkert.orgStorageParams::~StorageParams() 1465889Snate@binkert.org{ 1475889Snate@binkert.org} 1485889Snate@binkert.org 1496026Snate@binkert.orgNameMapType & 1506026Snate@binkert.orgnameMap() 1516026Snate@binkert.org{ 1526026Snate@binkert.org static NameMapType the_map; 1536026Snate@binkert.org return the_map; 1546026Snate@binkert.org} 1556026Snate@binkert.org 1565889Snate@binkert.orgint Info::id_count = 0; 1575889Snate@binkert.org 1585889Snate@binkert.orgint debug_break_id = -1; 1595889Snate@binkert.org 1605886Snate@binkert.orgInfo::Info() 1615889Snate@binkert.org : flags(none), precision(-1), prereq(0), storageParams(NULL) 162582SN/A{ 1635889Snate@binkert.org id = id_count++; 1645889Snate@binkert.org if (debug_break_id >= 0 and debug_break_id == id) 1658231Snate@binkert.org Debug::breakpoint(); 166582SN/A} 167582SN/A 1685886Snate@binkert.orgInfo::~Info() 169388SN/A{ 170388SN/A} 171388SN/A 1728248Snate@binkert.orgbool 1738248Snate@binkert.orgvalidateStatName(const string &name) 1748248Snate@binkert.org{ 1758248Snate@binkert.org if (name.empty()) 1768248Snate@binkert.org return false; 1778248Snate@binkert.org 1788248Snate@binkert.org vector<string> vec; 1798248Snate@binkert.org tokenize(vec, name, '.'); 1808248Snate@binkert.org vector<string>::const_iterator item = vec.begin(); 1818248Snate@binkert.org while (item != vec.end()) { 1828248Snate@binkert.org if (item->empty()) 1838248Snate@binkert.org return false; 1848248Snate@binkert.org 1858248Snate@binkert.org string::const_iterator c = item->begin(); 1868248Snate@binkert.org 1878248Snate@binkert.org // The first character is different 1888248Snate@binkert.org if (!isalpha(*c) && *c != '_') 1898248Snate@binkert.org return false; 1908248Snate@binkert.org 1918248Snate@binkert.org // The rest of the characters have different rules. 1928248Snate@binkert.org while (++c != item->end()) { 1938248Snate@binkert.org if (!isalnum(*c) && *c != '_') 1948248Snate@binkert.org return false; 1958248Snate@binkert.org } 1968248Snate@binkert.org 1978248Snate@binkert.org ++item; 1988248Snate@binkert.org } 1998248Snate@binkert.org 2008248Snate@binkert.org return true; 2018248Snate@binkert.org} 2028248Snate@binkert.org 2036026Snate@binkert.orgvoid 2046026Snate@binkert.orgInfo::setName(const string &name) 2056026Snate@binkert.org{ 20614266Sandreas.sandberg@arm.com setName(nullptr, name); 20714266Sandreas.sandberg@arm.com} 20814266Sandreas.sandberg@arm.com 20914266Sandreas.sandberg@arm.comvoid 21014266Sandreas.sandberg@arm.comInfo::setName(const Group *parent, const string &name) 21114266Sandreas.sandberg@arm.com{ 2128248Snate@binkert.org if (!validateStatName(name)) 2138248Snate@binkert.org panic("invalid stat name '%s'", name); 2148248Snate@binkert.org 21514266Sandreas.sandberg@arm.com // We only register the stat with the nameMap() if we are using 21614266Sandreas.sandberg@arm.com // old-style stats without a parent group. New-style stats should 21714266Sandreas.sandberg@arm.com // be unique since their names should correspond to a member 21814266Sandreas.sandberg@arm.com // variable. 21914266Sandreas.sandberg@arm.com if (!parent) { 22014266Sandreas.sandberg@arm.com auto p = nameMap().insert(make_pair(name, this)); 2216026Snate@binkert.org 22214266Sandreas.sandberg@arm.com if (!p.second) 22314266Sandreas.sandberg@arm.com panic("same statistic name used twice! name=%s\n", 22414266Sandreas.sandberg@arm.com name); 2256026Snate@binkert.org } 2266026Snate@binkert.org 2276026Snate@binkert.org this->name = name; 2286026Snate@binkert.org} 2296026Snate@binkert.org 2302SN/Abool 2315886Snate@binkert.orgInfo::less(Info *stat1, Info *stat2) 2322SN/A{ 233388SN/A const string &name1 = stat1->name; 234388SN/A const string &name2 = stat2->name; 2352SN/A 2362SN/A vector<string> v1; 2372SN/A vector<string> v2; 2382SN/A 2392SN/A tokenize(v1, name1, '.'); 2402SN/A tokenize(v2, name2, '.'); 2412SN/A 2425599Snate@binkert.org size_type last = min(v1.size(), v2.size()) - 1; 2435599Snate@binkert.org for (off_type i = 0; i < last; ++i) 2442SN/A if (v1[i] != v2[i]) 2452SN/A return v1[i] < v2[i]; 2462SN/A 2472SN/A // Special compare for last element. 2482SN/A if (v1[last] == v2[last]) 2492SN/A return v1.size() < v2.size(); 2502SN/A else 2512SN/A return v1[last] < v2[last]; 2522SN/A 2532SN/A return false; 2542SN/A} 2552SN/A 256388SN/Abool 2575886Snate@binkert.orgInfo::baseCheck() const 2582SN/A{ 2596000Snate@binkert.org if (!(flags & Stats::init)) { 260582SN/A#ifdef DEBUG 261695SN/A cprintf("this is stat number %d\n", id); 262388SN/A#endif 26311681Spowerjg@cs.wisc.edu panic("Not all stats have been initialized.\n" 26411681Spowerjg@cs.wisc.edu "You may need to add <ParentClass>::regStats() to a" 26514205Sandreas.sandberg@arm.com " new SimObject's regStats() function. Name: %s", 26614205Sandreas.sandberg@arm.com name); 267388SN/A return false; 268388SN/A } 2692SN/A 2707462Snate@binkert.org if ((flags & display) && name.empty()) { 271388SN/A panic("all printable stats must be named"); 272388SN/A return false; 273388SN/A } 2742SN/A 275388SN/A return true; 2762SN/A} 2772SN/A 2786001Snate@binkert.orgvoid 2796001Snate@binkert.orgInfo::enable() 2806001Snate@binkert.org{ 2816001Snate@binkert.org} 2826001Snate@binkert.org 2836001Snate@binkert.orgvoid 2846128Snate@binkert.orgVectorInfo::enable() 2856001Snate@binkert.org{ 2866001Snate@binkert.org size_type s = size(); 2876001Snate@binkert.org if (subnames.size() < s) 2886001Snate@binkert.org subnames.resize(s); 2896001Snate@binkert.org if (subdescs.size() < s) 2906001Snate@binkert.org subdescs.resize(s); 2916001Snate@binkert.org} 2926001Snate@binkert.org 2936001Snate@binkert.orgvoid 2946128Snate@binkert.orgVectorDistInfo::enable() 2956001Snate@binkert.org{ 2966001Snate@binkert.org size_type s = size(); 2976001Snate@binkert.org if (subnames.size() < s) 2986001Snate@binkert.org subnames.resize(s); 2996001Snate@binkert.org if (subdescs.size() < s) 3006001Snate@binkert.org subdescs.resize(s); 3016001Snate@binkert.org} 3026001Snate@binkert.org 3036001Snate@binkert.orgvoid 3046128Snate@binkert.orgVector2dInfo::enable() 3056001Snate@binkert.org{ 3066001Snate@binkert.org if (subnames.size() < x) 3076001Snate@binkert.org subnames.resize(x); 3086001Snate@binkert.org if (subdescs.size() < x) 3096001Snate@binkert.org subdescs.resize(x); 3106001Snate@binkert.org if (y_subnames.size() < y) 3116001Snate@binkert.org y_subnames.resize(y); 3126001Snate@binkert.org} 313695SN/A 3147831Snate@binkert.orgvoid 3157831Snate@binkert.orgHistStor::grow_out() 3167831Snate@binkert.org{ 3177831Snate@binkert.org int size = cvec.size(); 3187831Snate@binkert.org int zero = size / 2; // round down! 3197831Snate@binkert.org int top_half = zero + (size - zero + 1) / 2; // round up! 3207831Snate@binkert.org int bottom_half = (size - zero) / 2; // round down! 3217831Snate@binkert.org 3227831Snate@binkert.org // grow down 3237831Snate@binkert.org int low_pair = zero - 1; 3247831Snate@binkert.org for (int i = zero - 1; i >= bottom_half; i--) { 3257831Snate@binkert.org cvec[i] = cvec[low_pair]; 3267831Snate@binkert.org if (low_pair - 1 >= 0) 3277831Snate@binkert.org cvec[i] += cvec[low_pair - 1]; 3287831Snate@binkert.org low_pair -= 2; 3297831Snate@binkert.org } 3307831Snate@binkert.org assert(low_pair == 0 || low_pair == -1 || low_pair == -2); 3317831Snate@binkert.org 3327831Snate@binkert.org for (int i = bottom_half - 1; i >= 0; i--) 3337831Snate@binkert.org cvec[i] = Counter(); 3347831Snate@binkert.org 3357831Snate@binkert.org // grow up 3367831Snate@binkert.org int high_pair = zero; 3377831Snate@binkert.org for (int i = zero; i < top_half; i++) { 3387831Snate@binkert.org cvec[i] = cvec[high_pair]; 3397831Snate@binkert.org if (high_pair + 1 < size) 3407831Snate@binkert.org cvec[i] += cvec[high_pair + 1]; 3417831Snate@binkert.org high_pair += 2; 3427831Snate@binkert.org } 3437831Snate@binkert.org assert(high_pair == size || high_pair == size + 1); 3447831Snate@binkert.org 3457831Snate@binkert.org for (int i = top_half; i < size; i++) 3467831Snate@binkert.org cvec[i] = Counter(); 3477831Snate@binkert.org 3487831Snate@binkert.org max_bucket *= 2; 3497831Snate@binkert.org min_bucket *= 2; 3507831Snate@binkert.org bucket_size *= 2; 3517831Snate@binkert.org} 3527831Snate@binkert.org 3537831Snate@binkert.orgvoid 3547831Snate@binkert.orgHistStor::grow_convert() 3557831Snate@binkert.org{ 3567831Snate@binkert.org int size = cvec.size(); 3577831Snate@binkert.org int half = (size + 1) / 2; // round up! 3587831Snate@binkert.org //bool even = (size & 1) == 0; 3597831Snate@binkert.org 3607831Snate@binkert.org int pair = size - 1; 3617831Snate@binkert.org for (int i = size - 1; i >= half; --i) { 3627831Snate@binkert.org cvec[i] = cvec[pair]; 3637831Snate@binkert.org if (pair - 1 >= 0) 3647831Snate@binkert.org cvec[i] += cvec[pair - 1]; 3657831Snate@binkert.org pair -= 2; 3667831Snate@binkert.org } 3677831Snate@binkert.org 3687831Snate@binkert.org for (int i = half - 1; i >= 0; i--) 3697831Snate@binkert.org cvec[i] = Counter(); 3707831Snate@binkert.org 3717831Snate@binkert.org min_bucket = -max_bucket;// - (even ? bucket_size : 0); 3727831Snate@binkert.org bucket_size *= 2; 3737831Snate@binkert.org} 3747831Snate@binkert.org 3757831Snate@binkert.orgvoid 3767831Snate@binkert.orgHistStor::grow_up() 3777831Snate@binkert.org{ 3787831Snate@binkert.org int size = cvec.size(); 3797831Snate@binkert.org int half = (size + 1) / 2; // round up! 3807831Snate@binkert.org 3817831Snate@binkert.org int pair = 0; 3827831Snate@binkert.org for (int i = 0; i < half; i++) { 3837831Snate@binkert.org cvec[i] = cvec[pair]; 3847831Snate@binkert.org if (pair + 1 < size) 3857831Snate@binkert.org cvec[i] += cvec[pair + 1]; 3867831Snate@binkert.org pair += 2; 3877831Snate@binkert.org } 3887831Snate@binkert.org assert(pair == size || pair == size + 1); 3897831Snate@binkert.org 3907831Snate@binkert.org for (int i = half; i < size; i++) 3917831Snate@binkert.org cvec[i] = Counter(); 3927831Snate@binkert.org 3937831Snate@binkert.org max_bucket *= 2; 3947831Snate@binkert.org bucket_size *= 2; 3957831Snate@binkert.org} 3967831Snate@binkert.org 39710011Snilay@cs.wisc.eduvoid 39810011Snilay@cs.wisc.eduHistStor::add(HistStor *hs) 39910011Snilay@cs.wisc.edu{ 40010011Snilay@cs.wisc.edu int b_size = hs->size(); 40110011Snilay@cs.wisc.edu assert(size() == b_size); 40210011Snilay@cs.wisc.edu assert(min_bucket == hs->min_bucket); 40310011Snilay@cs.wisc.edu 40410011Snilay@cs.wisc.edu sum += hs->sum; 40510011Snilay@cs.wisc.edu logs += hs->logs; 40610011Snilay@cs.wisc.edu squares += hs->squares; 40710011Snilay@cs.wisc.edu samples += hs->samples; 40810011Snilay@cs.wisc.edu 40911321Ssteve.reinhardt@amd.com while (bucket_size > hs->bucket_size) 41010011Snilay@cs.wisc.edu hs->grow_up(); 41111321Ssteve.reinhardt@amd.com while (bucket_size < hs->bucket_size) 41210011Snilay@cs.wisc.edu grow_up(); 41310011Snilay@cs.wisc.edu 41410011Snilay@cs.wisc.edu for (uint32_t i = 0; i < b_size; i++) 41510011Snilay@cs.wisc.edu cvec[i] += hs->cvec[i]; 41610011Snilay@cs.wisc.edu} 41710011Snilay@cs.wisc.edu 41814205Sandreas.sandberg@arm.comFormula::Formula(Group *parent, const char *name, const char *desc) 41914205Sandreas.sandberg@arm.com : DataWrapVec<Formula, FormulaInfoProxy>(parent, name, desc) 42014205Sandreas.sandberg@arm.com 421388SN/A{ 422388SN/A} 423388SN/A 42414205Sandreas.sandberg@arm.com 42514205Sandreas.sandberg@arm.com 42614205Sandreas.sandberg@arm.comFormula::Formula(Group *parent, const char *name, const char *desc, 42714205Sandreas.sandberg@arm.com const Temp &r) 42814205Sandreas.sandberg@arm.com : DataWrapVec<Formula, FormulaInfoProxy>(parent, name, desc) 429388SN/A{ 43014205Sandreas.sandberg@arm.com *this = r; 431388SN/A} 432388SN/A 433388SN/Aconst Formula & 43414205Sandreas.sandberg@arm.comFormula::operator=(const Temp &r) 435388SN/A{ 436388SN/A assert(!root && "Can't change formulas"); 43710491Sandreas.hansson@arm.com root = r.getNodePtr(); 4387461Snate@binkert.org setInit(); 439388SN/A assert(size()); 440388SN/A return *this; 441388SN/A} 442388SN/A 443388SN/Aconst Formula & 444388SN/AFormula::operator+=(Temp r) 445388SN/A{ 446388SN/A if (root) 447695SN/A root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 4487461Snate@binkert.org else { 44910491Sandreas.hansson@arm.com root = r.getNodePtr(); 4507461Snate@binkert.org setInit(); 4517461Snate@binkert.org } 4527461Snate@binkert.org 453388SN/A assert(size()); 454388SN/A return *this; 455388SN/A} 456388SN/A 4579857Snilay@cs.wisc.educonst Formula & 4589857Snilay@cs.wisc.eduFormula::operator/=(Temp r) 4599857Snilay@cs.wisc.edu{ 4609857Snilay@cs.wisc.edu assert (root); 4619857Snilay@cs.wisc.edu root = NodePtr(new BinaryNode<std::divides<Result> >(root, r)); 4629857Snilay@cs.wisc.edu 4639857Snilay@cs.wisc.edu assert(size()); 4649857Snilay@cs.wisc.edu return *this; 4659857Snilay@cs.wisc.edu} 4669857Snilay@cs.wisc.edu 46714205Sandreas.sandberg@arm.com 468142SN/Avoid 4696000Snate@binkert.orgFormula::result(VResult &vec) const 4706000Snate@binkert.org{ 4716000Snate@binkert.org if (root) 4726000Snate@binkert.org vec = root->result(); 4736000Snate@binkert.org} 4746000Snate@binkert.org 4756000Snate@binkert.orgResult 4766000Snate@binkert.orgFormula::total() const 4776000Snate@binkert.org{ 4786000Snate@binkert.org return root ? root->total() : 0.0; 4796000Snate@binkert.org} 4806000Snate@binkert.org 4816000Snate@binkert.orgsize_type 4826000Snate@binkert.orgFormula::size() const 4836000Snate@binkert.org{ 4846000Snate@binkert.org if (!root) 4856000Snate@binkert.org return 0; 4866000Snate@binkert.org else 4876000Snate@binkert.org return root->size(); 4886000Snate@binkert.org} 4896000Snate@binkert.org 4906000Snate@binkert.orgvoid 4916000Snate@binkert.orgFormula::reset() 4926000Snate@binkert.org{ 4936000Snate@binkert.org} 4946000Snate@binkert.org 4956000Snate@binkert.orgbool 4966000Snate@binkert.orgFormula::zero() const 4976000Snate@binkert.org{ 4986000Snate@binkert.org VResult vec; 4996000Snate@binkert.org result(vec); 5006227Snate@binkert.org for (VResult::size_type i = 0; i < vec.size(); ++i) 5016000Snate@binkert.org if (vec[i] != 0.0) 5026000Snate@binkert.org return false; 5036000Snate@binkert.org return true; 5046000Snate@binkert.org} 5056000Snate@binkert.org 5066000Snate@binkert.orgstring 5076000Snate@binkert.orgFormula::str() const 5086000Snate@binkert.org{ 5096000Snate@binkert.org return root ? root->str() : ""; 5106000Snate@binkert.org} 5116000Snate@binkert.org 51210453SAndrew.Bardsley@arm.comHandler resetHandler = NULL; 51310453SAndrew.Bardsley@arm.comHandler dumpHandler = NULL; 51410453SAndrew.Bardsley@arm.com 51510453SAndrew.Bardsley@arm.comvoid 51610453SAndrew.Bardsley@arm.comregisterHandlers(Handler reset_handler, Handler dump_handler) 51710453SAndrew.Bardsley@arm.com{ 51810453SAndrew.Bardsley@arm.com resetHandler = reset_handler; 51910453SAndrew.Bardsley@arm.com dumpHandler = dump_handler; 52010453SAndrew.Bardsley@arm.com} 52110453SAndrew.Bardsley@arm.com 5229042SMitchell.Hayenga@ARM.comCallbackQueue dumpQueue; 523695SN/ACallbackQueue resetQueue; 5242SN/A 525456SN/Avoid 52610453SAndrew.Bardsley@arm.comprocessResetQueue() 52710453SAndrew.Bardsley@arm.com{ 52810453SAndrew.Bardsley@arm.com resetQueue.process(); 52910453SAndrew.Bardsley@arm.com} 53010453SAndrew.Bardsley@arm.com 53110453SAndrew.Bardsley@arm.comvoid 53210453SAndrew.Bardsley@arm.comprocessDumpQueue() 53310453SAndrew.Bardsley@arm.com{ 53410453SAndrew.Bardsley@arm.com dumpQueue.process(); 53510453SAndrew.Bardsley@arm.com} 53610453SAndrew.Bardsley@arm.com 53710453SAndrew.Bardsley@arm.comvoid 538394SN/AregisterResetCallback(Callback *cb) 539148SN/A{ 540148SN/A resetQueue.add(cb); 541148SN/A} 542148SN/A 5438986SAli.Saidi@ARM.combool _enabled = false; 5448986SAli.Saidi@ARM.com 5458986SAli.Saidi@ARM.combool 5468986SAli.Saidi@ARM.comenabled() 5478986SAli.Saidi@ARM.com{ 5488986SAli.Saidi@ARM.com return _enabled; 5498986SAli.Saidi@ARM.com} 5508986SAli.Saidi@ARM.com 5518986SAli.Saidi@ARM.comvoid 5528986SAli.Saidi@ARM.comenable() 5538986SAli.Saidi@ARM.com{ 5548986SAli.Saidi@ARM.com if (_enabled) 5558986SAli.Saidi@ARM.com fatal("Stats are already enabled"); 5568986SAli.Saidi@ARM.com 5578986SAli.Saidi@ARM.com _enabled = true; 5588986SAli.Saidi@ARM.com} 5598986SAli.Saidi@ARM.com 5609042SMitchell.Hayenga@ARM.comvoid 56110453SAndrew.Bardsley@arm.comdump() 56210453SAndrew.Bardsley@arm.com{ 56310453SAndrew.Bardsley@arm.com if (dumpHandler) 56410453SAndrew.Bardsley@arm.com dumpHandler(); 56510453SAndrew.Bardsley@arm.com else 56610453SAndrew.Bardsley@arm.com fatal("No registered Stats::dump handler"); 56710453SAndrew.Bardsley@arm.com} 56810453SAndrew.Bardsley@arm.com 56910453SAndrew.Bardsley@arm.comvoid 57010453SAndrew.Bardsley@arm.comreset() 57110453SAndrew.Bardsley@arm.com{ 57210453SAndrew.Bardsley@arm.com if (resetHandler) 57310453SAndrew.Bardsley@arm.com resetHandler(); 57410453SAndrew.Bardsley@arm.com else 57510453SAndrew.Bardsley@arm.com fatal("No registered Stats::reset handler"); 57610453SAndrew.Bardsley@arm.com} 57710453SAndrew.Bardsley@arm.com 57810453SAndrew.Bardsley@arm.comvoid 5799042SMitchell.Hayenga@ARM.comregisterDumpCallback(Callback *cb) 5809042SMitchell.Hayenga@ARM.com{ 5819042SMitchell.Hayenga@ARM.com dumpQueue.add(cb); 5829042SMitchell.Hayenga@ARM.com} 5839042SMitchell.Hayenga@ARM.com 5847811Ssteve.reinhardt@amd.com} // namespace Stats 5858296Snate@binkert.org 5868296Snate@binkert.orgvoid 5878296Snate@binkert.orgdebugDumpStats() 5888296Snate@binkert.org{ 5898296Snate@binkert.org Stats::dump(); 5908296Snate@binkert.org} 591