statistics.cc revision 12334:e0ab29a34764
112239Sandreas.sandberg@arm.com/* 214249Sgiacomo.travaglini@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 314249Sgiacomo.travaglini@arm.com * All rights reserved. 414249Sgiacomo.travaglini@arm.com * 514249Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without 614249Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are 714249Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright 814249Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer; 914249Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright 1014249Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the 1114249Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution; 1214249Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its 1314249Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from 1412239Sandreas.sandberg@arm.com * this software without specific prior written permission. 1512239Sandreas.sandberg@arm.com * 1612239Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712239Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812239Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912239Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012239Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112239Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212239Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312239Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412239Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512239Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612239Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712239Sandreas.sandberg@arm.com * 2812239Sandreas.sandberg@arm.com * Authors: Nathan Binkert 2912239Sandreas.sandberg@arm.com */ 3012239Sandreas.sandberg@arm.com 3112239Sandreas.sandberg@arm.com#include "base/statistics.hh" 3212239Sandreas.sandberg@arm.com 3312239Sandreas.sandberg@arm.com#include <fstream> 3412239Sandreas.sandberg@arm.com#include <iomanip> 3512239Sandreas.sandberg@arm.com#include <list> 3612239Sandreas.sandberg@arm.com#include <map> 3712239Sandreas.sandberg@arm.com#include <string> 3812239Sandreas.sandberg@arm.com 3912239Sandreas.sandberg@arm.com#include "base/callback.hh" 4012239Sandreas.sandberg@arm.com#include "base/cprintf.hh" 4112239Sandreas.sandberg@arm.com#include "base/debug.hh" 4212239Sandreas.sandberg@arm.com#include "base/hostinfo.hh" 4312239Sandreas.sandberg@arm.com#include "base/logging.hh" 4412239Sandreas.sandberg@arm.com#include "base/str.hh" 4512239Sandreas.sandberg@arm.com#include "base/time.hh" 4612239Sandreas.sandberg@arm.com#include "base/trace.hh" 4712239Sandreas.sandberg@arm.com 4812239Sandreas.sandberg@arm.comusing namespace std; 4912239Sandreas.sandberg@arm.com 5012239Sandreas.sandberg@arm.comnamespace Stats { 5112239Sandreas.sandberg@arm.com 5212239Sandreas.sandberg@arm.comstd::string Info::separatorString = "::"; 5312239Sandreas.sandberg@arm.com 5412239Sandreas.sandberg@arm.com// We wrap these in a function to make sure they're built in time. 5512239Sandreas.sandberg@arm.comlist<Info *> & 5612239Sandreas.sandberg@arm.comstatsList() 5712239Sandreas.sandberg@arm.com{ 5812239Sandreas.sandberg@arm.com static list<Info *> the_list; 5912239Sandreas.sandberg@arm.com return the_list; 6012239Sandreas.sandberg@arm.com} 6112239Sandreas.sandberg@arm.com 6212239Sandreas.sandberg@arm.comMapType & 6312239Sandreas.sandberg@arm.comstatsMap() 6412239Sandreas.sandberg@arm.com{ 6512239Sandreas.sandberg@arm.com static MapType the_map; 6612239Sandreas.sandberg@arm.com return the_map; 6712239Sandreas.sandberg@arm.com} 6812239Sandreas.sandberg@arm.com 6912239Sandreas.sandberg@arm.comvoid 7012334Sgabeblack@google.comInfoAccess::setInfo(Info *info) 7112239Sandreas.sandberg@arm.com{ 7212239Sandreas.sandberg@arm.com if (statsMap().find(this) != statsMap().end()) 7312239Sandreas.sandberg@arm.com panic("shouldn't register stat twice!"); 7412239Sandreas.sandberg@arm.com 7512239Sandreas.sandberg@arm.com statsList().push_back(info); 7612239Sandreas.sandberg@arm.com 7712239Sandreas.sandberg@arm.com#ifndef NDEBUG 7812239Sandreas.sandberg@arm.com pair<MapType::iterator, bool> result = 7912239Sandreas.sandberg@arm.com#endif 8012239Sandreas.sandberg@arm.com statsMap().insert(make_pair(this, info)); 8112239Sandreas.sandberg@arm.com assert(result.second && "this should never fail"); 8212239Sandreas.sandberg@arm.com assert(statsMap().find(this) != statsMap().end()); 8312239Sandreas.sandberg@arm.com} 8412239Sandreas.sandberg@arm.com 8512239Sandreas.sandberg@arm.comvoid 8612239Sandreas.sandberg@arm.comInfoAccess::setParams(const StorageParams *params) 8712239Sandreas.sandberg@arm.com{ 8812239Sandreas.sandberg@arm.com info()->storageParams = params; 8912239Sandreas.sandberg@arm.com} 9012239Sandreas.sandberg@arm.com 9112239Sandreas.sandberg@arm.comvoid 9212239Sandreas.sandberg@arm.comInfoAccess::setInit() 9312239Sandreas.sandberg@arm.com{ 9412239Sandreas.sandberg@arm.com info()->flags.set(init); 9512239Sandreas.sandberg@arm.com} 9612239Sandreas.sandberg@arm.com 9712239Sandreas.sandberg@arm.comInfo * 9812239Sandreas.sandberg@arm.comInfoAccess::info() 9912239Sandreas.sandberg@arm.com{ 10012239Sandreas.sandberg@arm.com MapType::const_iterator i = statsMap().find(this); 10112239Sandreas.sandberg@arm.com assert(i != statsMap().end()); 10212239Sandreas.sandberg@arm.com return (*i).second; 10312239Sandreas.sandberg@arm.com} 10412239Sandreas.sandberg@arm.com 10512239Sandreas.sandberg@arm.comconst Info * 10612239Sandreas.sandberg@arm.comInfoAccess::info() const 10712239Sandreas.sandberg@arm.com{ 10812239Sandreas.sandberg@arm.com MapType::const_iterator i = statsMap().find(this); 10912239Sandreas.sandberg@arm.com assert(i != statsMap().end()); 11012239Sandreas.sandberg@arm.com return (*i).second; 11112239Sandreas.sandberg@arm.com} 11212239Sandreas.sandberg@arm.com 11312239Sandreas.sandberg@arm.comStorageParams::~StorageParams() 11412239Sandreas.sandberg@arm.com{ 11512239Sandreas.sandberg@arm.com} 11612239Sandreas.sandberg@arm.com 11712239Sandreas.sandberg@arm.comNameMapType & 11812239Sandreas.sandberg@arm.comnameMap() 11912239Sandreas.sandberg@arm.com{ 12012239Sandreas.sandberg@arm.com static NameMapType the_map; 12112239Sandreas.sandberg@arm.com return the_map; 12212239Sandreas.sandberg@arm.com} 12312239Sandreas.sandberg@arm.com 12414249Sgiacomo.travaglini@arm.comint Info::id_count = 0; 12512239Sandreas.sandberg@arm.com 12612239Sandreas.sandberg@arm.comint debug_break_id = -1; 12712239Sandreas.sandberg@arm.com 12812239Sandreas.sandberg@arm.comInfo::Info() 12912239Sandreas.sandberg@arm.com : flags(none), precision(-1), prereq(0), storageParams(NULL) 13012239Sandreas.sandberg@arm.com{ 13112239Sandreas.sandberg@arm.com id = id_count++; 13212239Sandreas.sandberg@arm.com if (debug_break_id >= 0 and debug_break_id == id) 13312239Sandreas.sandberg@arm.com Debug::breakpoint(); 13412239Sandreas.sandberg@arm.com} 13512239Sandreas.sandberg@arm.com 13612239Sandreas.sandberg@arm.comInfo::~Info() 13712239Sandreas.sandberg@arm.com{ 13812239Sandreas.sandberg@arm.com} 13912239Sandreas.sandberg@arm.com 14012239Sandreas.sandberg@arm.combool 14112239Sandreas.sandberg@arm.comvalidateStatName(const string &name) 14212239Sandreas.sandberg@arm.com{ 14312239Sandreas.sandberg@arm.com if (name.empty()) 14412239Sandreas.sandberg@arm.com return false; 14512239Sandreas.sandberg@arm.com 14612239Sandreas.sandberg@arm.com vector<string> vec; 14712239Sandreas.sandberg@arm.com tokenize(vec, name, '.'); 14814249Sgiacomo.travaglini@arm.com vector<string>::const_iterator item = vec.begin(); 14914249Sgiacomo.travaglini@arm.com while (item != vec.end()) { 15014249Sgiacomo.travaglini@arm.com if (item->empty()) 15114249Sgiacomo.travaglini@arm.com return false; 15214249Sgiacomo.travaglini@arm.com 15314249Sgiacomo.travaglini@arm.com string::const_iterator c = item->begin(); 15414288SAndrea.Mondelli@ucf.edu 15514249Sgiacomo.travaglini@arm.com // The first character is different 15614288SAndrea.Mondelli@ucf.edu if (!isalpha(*c) && *c != '_') 15714249Sgiacomo.travaglini@arm.com return false; 15814249Sgiacomo.travaglini@arm.com 15914249Sgiacomo.travaglini@arm.com // The rest of the characters have different rules. 16014249Sgiacomo.travaglini@arm.com while (++c != item->end()) { 16114249Sgiacomo.travaglini@arm.com if (!isalnum(*c) && *c != '_') 16214249Sgiacomo.travaglini@arm.com return false; 16314249Sgiacomo.travaglini@arm.com } 16412239Sandreas.sandberg@arm.com 16512239Sandreas.sandberg@arm.com ++item; 16612239Sandreas.sandberg@arm.com } 16712239Sandreas.sandberg@arm.com 16812239Sandreas.sandberg@arm.com return true; 16912239Sandreas.sandberg@arm.com} 17012239Sandreas.sandberg@arm.com 17112239Sandreas.sandberg@arm.comvoid 17212239Sandreas.sandberg@arm.comInfo::setName(const string &name) 17312239Sandreas.sandberg@arm.com{ 17412239Sandreas.sandberg@arm.com if (!validateStatName(name)) 17512239Sandreas.sandberg@arm.com panic("invalid stat name '%s'", name); 17612239Sandreas.sandberg@arm.com 17712239Sandreas.sandberg@arm.com pair<NameMapType::iterator, bool> p = 17812239Sandreas.sandberg@arm.com nameMap().insert(make_pair(name, this)); 17912239Sandreas.sandberg@arm.com 18012239Sandreas.sandberg@arm.com Info *other = p.first->second; 18112239Sandreas.sandberg@arm.com bool result = p.second; 18212239Sandreas.sandberg@arm.com 18312239Sandreas.sandberg@arm.com if (!result) { 18412693Sandreas.sandberg@arm.com // using other->name instead of just name to avoid a compiler 18512693Sandreas.sandberg@arm.com // warning. They should be the same. 18612239Sandreas.sandberg@arm.com panic("same statistic name used twice! name=%s\n", other->name); 18712239Sandreas.sandberg@arm.com } 18812239Sandreas.sandberg@arm.com 18912239Sandreas.sandberg@arm.com this->name = name; 19012239Sandreas.sandberg@arm.com} 19112239Sandreas.sandberg@arm.com 19212239Sandreas.sandberg@arm.combool 19312239Sandreas.sandberg@arm.comInfo::less(Info *stat1, Info *stat2) 19412239Sandreas.sandberg@arm.com{ 19512239Sandreas.sandberg@arm.com const string &name1 = stat1->name; 19612239Sandreas.sandberg@arm.com const string &name2 = stat2->name; 19712239Sandreas.sandberg@arm.com 19812239Sandreas.sandberg@arm.com vector<string> v1; 19912239Sandreas.sandberg@arm.com vector<string> v2; 20012239Sandreas.sandberg@arm.com 20112239Sandreas.sandberg@arm.com tokenize(v1, name1, '.'); 20212239Sandreas.sandberg@arm.com tokenize(v2, name2, '.'); 20312239Sandreas.sandberg@arm.com 20412239Sandreas.sandberg@arm.com size_type last = min(v1.size(), v2.size()) - 1; 20512239Sandreas.sandberg@arm.com for (off_type i = 0; i < last; ++i) 20612239Sandreas.sandberg@arm.com if (v1[i] != v2[i]) 20712239Sandreas.sandberg@arm.com return v1[i] < v2[i]; 20812239Sandreas.sandberg@arm.com 20912239Sandreas.sandberg@arm.com // Special compare for last element. 21012239Sandreas.sandberg@arm.com if (v1[last] == v2[last]) 21112239Sandreas.sandberg@arm.com return v1.size() < v2.size(); 21212239Sandreas.sandberg@arm.com else 21312239Sandreas.sandberg@arm.com return v1[last] < v2[last]; 21412239Sandreas.sandberg@arm.com 21512239Sandreas.sandberg@arm.com return false; 21612239Sandreas.sandberg@arm.com} 21712239Sandreas.sandberg@arm.com 21812239Sandreas.sandberg@arm.combool 21912239Sandreas.sandberg@arm.comInfo::baseCheck() const 22012239Sandreas.sandberg@arm.com{ 22112239Sandreas.sandberg@arm.com if (!(flags & Stats::init)) { 22212239Sandreas.sandberg@arm.com#ifdef DEBUG 22312239Sandreas.sandberg@arm.com cprintf("this is stat number %d\n", id); 22412239Sandreas.sandberg@arm.com#endif 22512239Sandreas.sandberg@arm.com panic("Not all stats have been initialized.\n" 22612239Sandreas.sandberg@arm.com "You may need to add <ParentClass>::regStats() to a" 22712239Sandreas.sandberg@arm.com " new SimObject's regStats() function."); 22812239Sandreas.sandberg@arm.com return false; 22912239Sandreas.sandberg@arm.com } 23012239Sandreas.sandberg@arm.com 23112239Sandreas.sandberg@arm.com if ((flags & display) && name.empty()) { 23212239Sandreas.sandberg@arm.com panic("all printable stats must be named"); 23312239Sandreas.sandberg@arm.com return false; 23412239Sandreas.sandberg@arm.com } 23512239Sandreas.sandberg@arm.com 23612239Sandreas.sandberg@arm.com return true; 23712239Sandreas.sandberg@arm.com} 23812239Sandreas.sandberg@arm.com 23912239Sandreas.sandberg@arm.comvoid 24012239Sandreas.sandberg@arm.comInfo::enable() 24112239Sandreas.sandberg@arm.com{ 24212239Sandreas.sandberg@arm.com} 24312239Sandreas.sandberg@arm.com 24412239Sandreas.sandberg@arm.comvoid 24512239Sandreas.sandberg@arm.comVectorInfo::enable() 24612239Sandreas.sandberg@arm.com{ 24712239Sandreas.sandberg@arm.com size_type s = size(); 24812239Sandreas.sandberg@arm.com if (subnames.size() < s) 24912239Sandreas.sandberg@arm.com subnames.resize(s); 25012239Sandreas.sandberg@arm.com if (subdescs.size() < s) 25112239Sandreas.sandberg@arm.com subdescs.resize(s); 25212239Sandreas.sandberg@arm.com} 25312239Sandreas.sandberg@arm.com 25412239Sandreas.sandberg@arm.comvoid 25512239Sandreas.sandberg@arm.comVectorDistInfo::enable() 25612239Sandreas.sandberg@arm.com{ 25712239Sandreas.sandberg@arm.com size_type s = size(); 25812239Sandreas.sandberg@arm.com if (subnames.size() < s) 25912239Sandreas.sandberg@arm.com subnames.resize(s); 26012239Sandreas.sandberg@arm.com if (subdescs.size() < s) 26112239Sandreas.sandberg@arm.com subdescs.resize(s); 26212239Sandreas.sandberg@arm.com} 26312239Sandreas.sandberg@arm.com 26412239Sandreas.sandberg@arm.comvoid 26512239Sandreas.sandberg@arm.comVector2dInfo::enable() 26612239Sandreas.sandberg@arm.com{ 26712239Sandreas.sandberg@arm.com if (subnames.size() < x) 26812239Sandreas.sandberg@arm.com subnames.resize(x); 26912239Sandreas.sandberg@arm.com if (subdescs.size() < x) 27012239Sandreas.sandberg@arm.com subdescs.resize(x); 27112239Sandreas.sandberg@arm.com if (y_subnames.size() < y) 27212239Sandreas.sandberg@arm.com y_subnames.resize(y); 27312239Sandreas.sandberg@arm.com} 27412239Sandreas.sandberg@arm.com 27512239Sandreas.sandberg@arm.comvoid 27612239Sandreas.sandberg@arm.comHistStor::grow_out() 27712239Sandreas.sandberg@arm.com{ 27812239Sandreas.sandberg@arm.com int size = cvec.size(); 27912239Sandreas.sandberg@arm.com int zero = size / 2; // round down! 28012239Sandreas.sandberg@arm.com int top_half = zero + (size - zero + 1) / 2; // round up! 28112239Sandreas.sandberg@arm.com int bottom_half = (size - zero) / 2; // round down! 28212239Sandreas.sandberg@arm.com 28312239Sandreas.sandberg@arm.com // grow down 28412239Sandreas.sandberg@arm.com int low_pair = zero - 1; 28512239Sandreas.sandberg@arm.com for (int i = zero - 1; i >= bottom_half; i--) { 28612239Sandreas.sandberg@arm.com cvec[i] = cvec[low_pair]; 28712239Sandreas.sandberg@arm.com if (low_pair - 1 >= 0) 28812239Sandreas.sandberg@arm.com cvec[i] += cvec[low_pair - 1]; 28912239Sandreas.sandberg@arm.com low_pair -= 2; 29012239Sandreas.sandberg@arm.com } 29112239Sandreas.sandberg@arm.com assert(low_pair == 0 || low_pair == -1 || low_pair == -2); 29212239Sandreas.sandberg@arm.com 29312239Sandreas.sandberg@arm.com for (int i = bottom_half - 1; i >= 0; i--) 29412239Sandreas.sandberg@arm.com cvec[i] = Counter(); 29512239Sandreas.sandberg@arm.com 29612239Sandreas.sandberg@arm.com // grow up 29712239Sandreas.sandberg@arm.com int high_pair = zero; 29812239Sandreas.sandberg@arm.com for (int i = zero; i < top_half; i++) { 29912239Sandreas.sandberg@arm.com cvec[i] = cvec[high_pair]; 30012239Sandreas.sandberg@arm.com if (high_pair + 1 < size) 30112239Sandreas.sandberg@arm.com cvec[i] += cvec[high_pair + 1]; 30212239Sandreas.sandberg@arm.com high_pair += 2; 30312239Sandreas.sandberg@arm.com } 30412239Sandreas.sandberg@arm.com assert(high_pair == size || high_pair == size + 1); 30512239Sandreas.sandberg@arm.com 30612239Sandreas.sandberg@arm.com for (int i = top_half; i < size; i++) 30712239Sandreas.sandberg@arm.com cvec[i] = Counter(); 30812239Sandreas.sandberg@arm.com 30912239Sandreas.sandberg@arm.com max_bucket *= 2; 31012239Sandreas.sandberg@arm.com min_bucket *= 2; 31112239Sandreas.sandberg@arm.com bucket_size *= 2; 31212239Sandreas.sandberg@arm.com} 31312239Sandreas.sandberg@arm.com 31412239Sandreas.sandberg@arm.comvoid 31512239Sandreas.sandberg@arm.comHistStor::grow_convert() 31612239Sandreas.sandberg@arm.com{ 31712239Sandreas.sandberg@arm.com int size = cvec.size(); 31812239Sandreas.sandberg@arm.com int half = (size + 1) / 2; // round up! 31912239Sandreas.sandberg@arm.com //bool even = (size & 1) == 0; 32012239Sandreas.sandberg@arm.com 32112239Sandreas.sandberg@arm.com int pair = size - 1; 32212239Sandreas.sandberg@arm.com for (int i = size - 1; i >= half; --i) { 32312239Sandreas.sandberg@arm.com cvec[i] = cvec[pair]; 32412239Sandreas.sandberg@arm.com if (pair - 1 >= 0) 32512239Sandreas.sandberg@arm.com cvec[i] += cvec[pair - 1]; 32612239Sandreas.sandberg@arm.com pair -= 2; 32712239Sandreas.sandberg@arm.com } 32812239Sandreas.sandberg@arm.com 32912239Sandreas.sandberg@arm.com for (int i = half - 1; i >= 0; i--) 33012239Sandreas.sandberg@arm.com cvec[i] = Counter(); 33112239Sandreas.sandberg@arm.com 33212239Sandreas.sandberg@arm.com min_bucket = -max_bucket;// - (even ? bucket_size : 0); 33312239Sandreas.sandberg@arm.com bucket_size *= 2; 33412239Sandreas.sandberg@arm.com} 33512239Sandreas.sandberg@arm.com 33612239Sandreas.sandberg@arm.comvoid 33712239Sandreas.sandberg@arm.comHistStor::grow_up() 33812239Sandreas.sandberg@arm.com{ 33912239Sandreas.sandberg@arm.com int size = cvec.size(); 34012239Sandreas.sandberg@arm.com int half = (size + 1) / 2; // round up! 34112239Sandreas.sandberg@arm.com 34212239Sandreas.sandberg@arm.com int pair = 0; 34312239Sandreas.sandberg@arm.com for (int i = 0; i < half; i++) { 34412239Sandreas.sandberg@arm.com cvec[i] = cvec[pair]; 34512239Sandreas.sandberg@arm.com if (pair + 1 < size) 34612239Sandreas.sandberg@arm.com cvec[i] += cvec[pair + 1]; 34712239Sandreas.sandberg@arm.com pair += 2; 34812239Sandreas.sandberg@arm.com } 34912239Sandreas.sandberg@arm.com assert(pair == size || pair == size + 1); 35012239Sandreas.sandberg@arm.com 35112239Sandreas.sandberg@arm.com for (int i = half; i < size; i++) 35212239Sandreas.sandberg@arm.com cvec[i] = Counter(); 35312239Sandreas.sandberg@arm.com 35412239Sandreas.sandberg@arm.com max_bucket *= 2; 35512239Sandreas.sandberg@arm.com bucket_size *= 2; 35612239Sandreas.sandberg@arm.com} 35712239Sandreas.sandberg@arm.com 35812239Sandreas.sandberg@arm.comvoid 35912239Sandreas.sandberg@arm.comHistStor::add(HistStor *hs) 36012239Sandreas.sandberg@arm.com{ 36112239Sandreas.sandberg@arm.com int b_size = hs->size(); 36212239Sandreas.sandberg@arm.com assert(size() == b_size); 36312239Sandreas.sandberg@arm.com assert(min_bucket == hs->min_bucket); 36412239Sandreas.sandberg@arm.com 36512239Sandreas.sandberg@arm.com sum += hs->sum; 36612239Sandreas.sandberg@arm.com logs += hs->logs; 36712239Sandreas.sandberg@arm.com squares += hs->squares; 36812239Sandreas.sandberg@arm.com samples += hs->samples; 36912239Sandreas.sandberg@arm.com 37012239Sandreas.sandberg@arm.com while (bucket_size > hs->bucket_size) 371 hs->grow_up(); 372 while (bucket_size < hs->bucket_size) 373 grow_up(); 374 375 for (uint32_t i = 0; i < b_size; i++) 376 cvec[i] += hs->cvec[i]; 377} 378 379Formula::Formula() 380{ 381} 382 383Formula::Formula(Temp r) 384{ 385 root = r.getNodePtr(); 386 setInit(); 387 assert(size()); 388} 389 390const Formula & 391Formula::operator=(Temp r) 392{ 393 assert(!root && "Can't change formulas"); 394 root = r.getNodePtr(); 395 setInit(); 396 assert(size()); 397 return *this; 398} 399 400const Formula & 401Formula::operator+=(Temp r) 402{ 403 if (root) 404 root = NodePtr(new BinaryNode<std::plus<Result> >(root, r)); 405 else { 406 root = r.getNodePtr(); 407 setInit(); 408 } 409 410 assert(size()); 411 return *this; 412} 413 414const Formula & 415Formula::operator/=(Temp r) 416{ 417 assert (root); 418 root = NodePtr(new BinaryNode<std::divides<Result> >(root, r)); 419 420 assert(size()); 421 return *this; 422} 423 424void 425Formula::result(VResult &vec) const 426{ 427 if (root) 428 vec = root->result(); 429} 430 431Result 432Formula::total() const 433{ 434 return root ? root->total() : 0.0; 435} 436 437size_type 438Formula::size() const 439{ 440 if (!root) 441 return 0; 442 else 443 return root->size(); 444} 445 446void 447Formula::reset() 448{ 449} 450 451bool 452Formula::zero() const 453{ 454 VResult vec; 455 result(vec); 456 for (VResult::size_type i = 0; i < vec.size(); ++i) 457 if (vec[i] != 0.0) 458 return false; 459 return true; 460} 461 462string 463Formula::str() const 464{ 465 return root ? root->str() : ""; 466} 467 468Handler resetHandler = NULL; 469Handler dumpHandler = NULL; 470 471void 472registerHandlers(Handler reset_handler, Handler dump_handler) 473{ 474 resetHandler = reset_handler; 475 dumpHandler = dump_handler; 476} 477 478CallbackQueue dumpQueue; 479CallbackQueue resetQueue; 480 481void 482processResetQueue() 483{ 484 resetQueue.process(); 485} 486 487void 488processDumpQueue() 489{ 490 dumpQueue.process(); 491} 492 493void 494registerResetCallback(Callback *cb) 495{ 496 resetQueue.add(cb); 497} 498 499bool _enabled = false; 500 501bool 502enabled() 503{ 504 return _enabled; 505} 506 507void 508enable() 509{ 510 if (_enabled) 511 fatal("Stats are already enabled"); 512 513 _enabled = true; 514} 515 516void 517dump() 518{ 519 if (dumpHandler) 520 dumpHandler(); 521 else 522 fatal("No registered Stats::dump handler"); 523} 524 525void 526reset() 527{ 528 if (resetHandler) 529 resetHandler(); 530 else 531 fatal("No registered Stats::reset handler"); 532} 533 534void 535registerDumpCallback(Callback *cb) 536{ 537 dumpQueue.add(cb); 538} 539 540} // namespace Stats 541 542void 543debugDumpStats() 544{ 545 Stats::dump(); 546} 547