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