statistics.cc revision 7831
1360SN/A/*
21458SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
3360SN/A * All rights reserved.
4360SN/A *
5360SN/A * Redistribution and use in source and binary forms, with or without
6360SN/A * modification, are permitted provided that the following conditions are
7360SN/A * met: redistributions of source code must retain the above copyright
8360SN/A * notice, this list of conditions and the following disclaimer;
9360SN/A * redistributions in binary form must reproduce the above copyright
10360SN/A * notice, this list of conditions and the following disclaimer in the
11360SN/A * documentation and/or other materials provided with the distribution;
12360SN/A * neither the name of the copyright holders nor the names of its
13360SN/A * contributors may be used to endorse or promote products derived from
14360SN/A * this software without specific prior written permission.
15360SN/A *
16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
292665Ssaidi@eecs.umich.edu */
30360SN/A
31360SN/A#include <iomanip>
322093SN/A#include <fstream>
33360SN/A#include <list>
34360SN/A#include <map>
356712Snate@binkert.org#include <string>
366712Snate@binkert.org
37360SN/A#include "base/callback.hh"
38360SN/A#include "base/cprintf.hh"
397680Sgblack@eecs.umich.edu#include "base/debug.hh"
402474SN/A#include "base/hostinfo.hh"
41360SN/A#include "base/misc.hh"
426658Snate@binkert.org#include "base/statistics.hh"
438229Snate@binkert.org#include "base/str.hh"
442680Sktlim@umich.edu#include "base/time.hh"
458232Snate@binkert.org#include "base/trace.hh"
462474SN/A
47360SN/Ausing namespace std;
488229Snate@binkert.org
498229Snate@binkert.orgnamespace Stats {
506029Ssteve.reinhardt@amd.com
51360SN/Atypedef map<const void *, Info *> MapType;
52360SN/A
532107SN/A// We wrap these in a function to make sure they're built in time.
54360SN/Alist<Info *> &
55360SN/AstatsList()
563114Sgblack@eecs.umich.edu{
57360SN/A    static list<Info *> the_list;
586702Sgblack@eecs.umich.edu    return the_list;
596701Sgblack@eecs.umich.edu}
606702Sgblack@eecs.umich.edu
616111Ssteve.reinhardt@amd.comMapType &
626111Ssteve.reinhardt@amd.comstatsMap()
637823Ssteve.reinhardt@amd.com{
646701Sgblack@eecs.umich.edu    static MapType the_map;
656701Sgblack@eecs.umich.edu    return the_map;
666701Sgblack@eecs.umich.edu}
676701Sgblack@eecs.umich.edu
68360SN/Avoid
692680Sktlim@umich.eduInfoAccess::setInfo(Info *info)
70360SN/A{
712495SN/A    if (statsMap().find(this) != statsMap().end())
7210223Ssteve.reinhardt@amd.com        panic("shouldn't register stat twice!");
73360SN/A
741450SN/A    statsList().push_back(info);
755958Sgblack@eecs.umich.edu
76360SN/A#ifndef NDEBUG
77360SN/A    pair<MapType::iterator, bool> result =
78360SN/A#endif
791450SN/A        statsMap().insert(make_pair(this, info));
803114Sgblack@eecs.umich.edu    assert(result.second && "this should never fail");
812680Sktlim@umich.edu    assert(statsMap().find(this) != statsMap().end());
82360SN/A}
831969SN/A
842484SN/Avoid
852484SN/AInfoAccess::setParams(const StorageParams *params)
86360SN/A{
87360SN/A    info()->storageParams = params;
88360SN/A}
891450SN/A
903114Sgblack@eecs.umich.eduvoid
912680Sktlim@umich.eduInfoAccess::setInit()
92360SN/A{
936701Sgblack@eecs.umich.edu    info()->flags.set(init);
941969SN/A}
956701Sgblack@eecs.umich.edu
96360SN/AInfo *
971458SN/AInfoAccess::info()
98360SN/A{
99360SN/A    MapType::const_iterator i = statsMap().find(this);
100360SN/A    assert(i != statsMap().end());
1011450SN/A    return (*i).second;
1028149SChris.Emmons@ARM.com}
1038149SChris.Emmons@ARM.com
1048149SChris.Emmons@ARM.comconst Info *
1058149SChris.Emmons@ARM.comInfoAccess::info() const
1068149SChris.Emmons@ARM.com{
1078149SChris.Emmons@ARM.com    MapType::const_iterator i = statsMap().find(this);
1088149SChris.Emmons@ARM.com    assert(i != statsMap().end());
1098149SChris.Emmons@ARM.com    return (*i).second;
1108149SChris.Emmons@ARM.com}
1118149SChris.Emmons@ARM.com
1128149SChris.Emmons@ARM.comStorageParams::~StorageParams()
1138149SChris.Emmons@ARM.com{
1143114Sgblack@eecs.umich.edu}
1152680Sktlim@umich.edu
116360SN/Atypedef map<std::string, Info *> NameMapType;
1176029Ssteve.reinhardt@amd.comNameMapType &
1186029Ssteve.reinhardt@amd.comnameMap()
1196701Sgblack@eecs.umich.edu{
1205958Sgblack@eecs.umich.edu    static NameMapType the_map;
1216701Sgblack@eecs.umich.edu    return the_map;
1226029Ssteve.reinhardt@amd.com}
1236029Ssteve.reinhardt@amd.com
1246029Ssteve.reinhardt@amd.comint Info::id_count = 0;
1252834Sksewell@umich.edu
126360SN/Aint debug_break_id = -1;
1271458SN/A
128360SN/AInfo::Info()
129360SN/A    : flags(none), precision(-1), prereq(0), storageParams(NULL)
130360SN/A{
1311450SN/A    id = id_count++;
1326109Ssanchezd@stanford.edu    if (debug_break_id >= 0 and debug_break_id == id)
1336109Ssanchezd@stanford.edu        debug_break();
1346109Ssanchezd@stanford.edu}
1356109Ssanchezd@stanford.edu
1366109Ssanchezd@stanford.eduInfo::~Info()
1376701Sgblack@eecs.umich.edu{
1386109Ssanchezd@stanford.edu}
1396701Sgblack@eecs.umich.edu
1406109Ssanchezd@stanford.eduvoid
1416109Ssanchezd@stanford.eduInfo::setName(const string &name)
1426109Ssanchezd@stanford.edu{
1436109Ssanchezd@stanford.edu    pair<NameMapType::iterator, bool> p =
1446109Ssanchezd@stanford.edu        nameMap().insert(make_pair(name, this));
1456109Ssanchezd@stanford.edu
1463114Sgblack@eecs.umich.edu    Info *other = p.first->second;
147360SN/A    bool result = p.second;
1482107SN/A
149360SN/A    if (!result) {
150360SN/A        // using other->name instead of just name to avoid a compiler
151360SN/A        // warning.  They should be the same.
1521450SN/A        panic("same statistic name used twice! name=%s\n", other->name);
1535748SSteve.Reinhardt@amd.com    }
154360SN/A
155360SN/A    this->name = name;
1566701Sgblack@eecs.umich.edu}
1576701Sgblack@eecs.umich.edu
1585748SSteve.Reinhardt@amd.combool
1595748SSteve.Reinhardt@amd.comInfo::less(Info *stat1, Info *stat2)
1605748SSteve.Reinhardt@amd.com{
1615748SSteve.Reinhardt@amd.com    const string &name1 = stat1->name;
1625748SSteve.Reinhardt@amd.com    const string &name2 = stat2->name;
1635748SSteve.Reinhardt@amd.com
1645748SSteve.Reinhardt@amd.com    vector<string> v1;
1655748SSteve.Reinhardt@amd.com    vector<string> v2;
1662474SN/A
1672474SN/A    tokenize(v1, name1, '.');
1685748SSteve.Reinhardt@amd.com    tokenize(v2, name2, '.');
1698601Ssteve.reinhardt@amd.com
1706687Stjones1@inf.ed.ac.uk    size_type last = min(v1.size(), v2.size()) - 1;
1716687Stjones1@inf.ed.ac.uk    for (off_type i = 0; i < last; ++i)
1726687Stjones1@inf.ed.ac.uk        if (v1[i] != v2[i])
1736687Stjones1@inf.ed.ac.uk            return v1[i] < v2[i];
1748852Sandreas.hansson@arm.com
1756687Stjones1@inf.ed.ac.uk    // Special compare for last element.
1766687Stjones1@inf.ed.ac.uk    if (v1[last] == v2[last])
1776687Stjones1@inf.ed.ac.uk        return v1.size() < v2.size();
1786687Stjones1@inf.ed.ac.uk    else
1798852Sandreas.hansson@arm.com        return v1[last] < v2[last];
1806687Stjones1@inf.ed.ac.uk
1816687Stjones1@inf.ed.ac.uk    return false;
1826687Stjones1@inf.ed.ac.uk}
1836687Stjones1@inf.ed.ac.uk
1846687Stjones1@inf.ed.ac.ukbool
1858852Sandreas.hansson@arm.comInfo::baseCheck() const
1866687Stjones1@inf.ed.ac.uk{
1876687Stjones1@inf.ed.ac.uk    if (!(flags & Stats::init)) {
1882474SN/A#ifdef DEBUG
1891450SN/A        cprintf("this is stat number %d\n", id);
1905748SSteve.Reinhardt@amd.com#endif
1915748SSteve.Reinhardt@amd.com        panic("Not all stats have been initialized");
1921458SN/A        return false;
1931458SN/A    }
194360SN/A
195360SN/A    if ((flags & display) && name.empty()) {
196360SN/A        panic("all printable stats must be named");
1971450SN/A        return false;
1983114Sgblack@eecs.umich.edu    }
199360SN/A
2006701Sgblack@eecs.umich.edu    return true;
2016701Sgblack@eecs.umich.edu}
2027508Stjones1@inf.ed.ac.uk
2037508Stjones1@inf.ed.ac.ukvoid
2047508Stjones1@inf.ed.ac.ukInfo::enable()
2057508Stjones1@inf.ed.ac.uk{
2061970SN/A}
2071970SN/A
2081970SN/Avoid
209360SN/AVectorInfo::enable()
210360SN/A{
211360SN/A    size_type s = size();
2121450SN/A    if (subnames.size() < s)
2133114Sgblack@eecs.umich.edu        subnames.resize(s);
214360SN/A    if (subdescs.size() < s)
2156701Sgblack@eecs.umich.edu        subdescs.resize(s);
2166701Sgblack@eecs.umich.edu}
2176701Sgblack@eecs.umich.edu
2186701Sgblack@eecs.umich.eduvoid
2196701Sgblack@eecs.umich.eduVectorDistInfo::enable()
220360SN/A{
221360SN/A    size_type s = size();
222360SN/A    if (subnames.size() < s)
223360SN/A        subnames.resize(s);
2248706Sandreas.hansson@arm.com    if (subdescs.size() < s)
225360SN/A        subdescs.resize(s);
2261458SN/A}
227360SN/A
228360SN/Avoid
2291450SN/AVector2dInfo::enable()
2303114Sgblack@eecs.umich.edu{
231360SN/A    if (subnames.size() < x)
2326701Sgblack@eecs.umich.edu        subnames.resize(x);
2336701Sgblack@eecs.umich.edu    if (subdescs.size() < x)
2346701Sgblack@eecs.umich.edu        subdescs.resize(x);
2356701Sgblack@eecs.umich.edu    if (y_subnames.size() < y)
2366701Sgblack@eecs.umich.edu        y_subnames.resize(y);
237360SN/A}
2388706Sandreas.hansson@arm.com
239360SN/Avoid
240360SN/AHistStor::grow_out()
241360SN/A{
242360SN/A    int size = cvec.size();
243360SN/A    int zero = size / 2; // round down!
2441458SN/A    int top_half = zero + (size - zero + 1) / 2; // round up!
245360SN/A    int bottom_half = (size - zero) / 2; // round down!
246360SN/A
247360SN/A    // grow down
2481450SN/A    int low_pair = zero - 1;
2493114Sgblack@eecs.umich.edu    for (int i = zero - 1; i >= bottom_half; i--) {
250360SN/A        cvec[i] = cvec[low_pair];
2516701Sgblack@eecs.umich.edu        if (low_pair - 1 >= 0)
2526701Sgblack@eecs.umich.edu            cvec[i] += cvec[low_pair - 1];
2536701Sgblack@eecs.umich.edu        low_pair -= 2;
2546701Sgblack@eecs.umich.edu    }
255360SN/A    assert(low_pair == 0 || low_pair == -1 || low_pair == -2);
256360SN/A
257360SN/A    for (int i = bottom_half - 1; i >= 0; i--)
2581458SN/A        cvec[i] = Counter();
259360SN/A
260360SN/A    // grow up
261360SN/A    int high_pair = zero;
2621450SN/A    for (int i = zero; i < top_half; i++) {
2634118Sgblack@eecs.umich.edu        cvec[i] = cvec[high_pair];
2644118Sgblack@eecs.umich.edu        if (high_pair + 1 < size)
2656701Sgblack@eecs.umich.edu            cvec[i] += cvec[high_pair + 1];
2666701Sgblack@eecs.umich.edu        high_pair += 2;
2676701Sgblack@eecs.umich.edu    }
2686701Sgblack@eecs.umich.edu    assert(high_pair == size || high_pair == size + 1);
2696701Sgblack@eecs.umich.edu
2706701Sgblack@eecs.umich.edu    for (int i = top_half; i < size; i++)
2714118Sgblack@eecs.umich.edu        cvec[i] = Counter();
2724118Sgblack@eecs.umich.edu
2734118Sgblack@eecs.umich.edu    max_bucket *= 2;
2744118Sgblack@eecs.umich.edu    min_bucket *= 2;
2754118Sgblack@eecs.umich.edu    bucket_size *= 2;
2764118Sgblack@eecs.umich.edu}
2774118Sgblack@eecs.umich.edu
2784118Sgblack@eecs.umich.eduvoid
2794118Sgblack@eecs.umich.eduHistStor::grow_convert()
2804118Sgblack@eecs.umich.edu{
2816111Ssteve.reinhardt@amd.com    int size = cvec.size();
2826111Ssteve.reinhardt@amd.com    int half = (size + 1) / 2; // round up!
2836111Ssteve.reinhardt@amd.com    //bool even = (size & 1) == 0;
2846111Ssteve.reinhardt@amd.com
2854118Sgblack@eecs.umich.edu    int pair = size - 1;
2864118Sgblack@eecs.umich.edu    for (int i = size - 1; i >= half; --i) {
2878706Sandreas.hansson@arm.com        cvec[i] = cvec[pair];
2884118Sgblack@eecs.umich.edu        if (pair - 1 >= 0)
2894118Sgblack@eecs.umich.edu            cvec[i] += cvec[pair - 1];
2904118Sgblack@eecs.umich.edu        pair -= 2;
2914118Sgblack@eecs.umich.edu    }
2924118Sgblack@eecs.umich.edu
2934118Sgblack@eecs.umich.edu    for (int i = half - 1; i >= 0; i--)
2944118Sgblack@eecs.umich.edu        cvec[i] = Counter();
2954118Sgblack@eecs.umich.edu
2964118Sgblack@eecs.umich.edu    min_bucket = -max_bucket;// - (even ? bucket_size : 0);
2973114Sgblack@eecs.umich.edu    bucket_size *= 2;
298360SN/A}
299360SN/A
3001458SN/Avoid
301360SN/AHistStor::grow_up()
302360SN/A{
303360SN/A    int size = cvec.size();
304360SN/A    int half = (size + 1) / 2; // round up!
305360SN/A
3061450SN/A    int pair = 0;
3073114Sgblack@eecs.umich.edu    for (int i = 0; i < half; i++) {
308360SN/A        cvec[i] = cvec[pair];
3096701Sgblack@eecs.umich.edu        if (pair + 1 < size)
3106701Sgblack@eecs.umich.edu            cvec[i] += cvec[pair + 1];
3116701Sgblack@eecs.umich.edu        pair += 2;
3126701Sgblack@eecs.umich.edu    }
313360SN/A    assert(pair == size || pair == size + 1);
314360SN/A
315360SN/A    for (int i = half; i < size; i++)
3168706Sandreas.hansson@arm.com        cvec[i] = Counter();
317360SN/A
3181458SN/A    max_bucket *= 2;
319360SN/A    bucket_size *= 2;
320360SN/A}
3211450SN/A
3225513SMichael.Adler@intel.comFormula::Formula()
3235513SMichael.Adler@intel.com{
3245513SMichael.Adler@intel.com}
3256731Svince@csl.cornell.edu
3266701Sgblack@eecs.umich.eduFormula::Formula(Temp r)
3276701Sgblack@eecs.umich.edu{
3286701Sgblack@eecs.umich.edu    root = r;
3295513SMichael.Adler@intel.com    setInit();
3305513SMichael.Adler@intel.com    assert(size());
3315513SMichael.Adler@intel.com}
3325513SMichael.Adler@intel.com
3335513SMichael.Adler@intel.comconst Formula &
3345513SMichael.Adler@intel.comFormula::operator=(Temp r)
3355513SMichael.Adler@intel.com{
3365513SMichael.Adler@intel.com    assert(!root && "Can't change formulas");
3375513SMichael.Adler@intel.com    root = r;
3385513SMichael.Adler@intel.com    setInit();
3395513SMichael.Adler@intel.com    assert(size());
3405513SMichael.Adler@intel.com    return *this;
3415513SMichael.Adler@intel.com}
3425513SMichael.Adler@intel.com
3435513SMichael.Adler@intel.comconst Formula &
3445513SMichael.Adler@intel.comFormula::operator+=(Temp r)
3455513SMichael.Adler@intel.com{
3465513SMichael.Adler@intel.com    if (root)
3475513SMichael.Adler@intel.com        root = NodePtr(new BinaryNode<std::plus<Result> >(root, r));
3485513SMichael.Adler@intel.com    else {
3498706Sandreas.hansson@arm.com        root = r;
3505513SMichael.Adler@intel.com        setInit();
3515513SMichael.Adler@intel.com    }
3525513SMichael.Adler@intel.com
3535513SMichael.Adler@intel.com    assert(size());
35410203SAli.Saidi@ARM.com    return *this;
35510203SAli.Saidi@ARM.com}
35610203SAli.Saidi@ARM.com
35710203SAli.Saidi@ARM.comvoid
35810203SAli.Saidi@ARM.comFormula::result(VResult &vec) const
35910203SAli.Saidi@ARM.com{
36010203SAli.Saidi@ARM.com    if (root)
3615513SMichael.Adler@intel.com        vec = root->result();
3625513SMichael.Adler@intel.com}
36310203SAli.Saidi@ARM.com
36410203SAli.Saidi@ARM.comResult
3655513SMichael.Adler@intel.comFormula::total() const
3665513SMichael.Adler@intel.com{
3675513SMichael.Adler@intel.com    return root ? root->total() : 0.0;
3688852Sandreas.hansson@arm.com}
36910223Ssteve.reinhardt@amd.com
3705513SMichael.Adler@intel.comsize_type
3715513SMichael.Adler@intel.comFormula::size() const
3725513SMichael.Adler@intel.com{
3735513SMichael.Adler@intel.com    if (!root)
3746701Sgblack@eecs.umich.edu        return 0;
3756701Sgblack@eecs.umich.edu    else
3766701Sgblack@eecs.umich.edu        return root->size();
3776701Sgblack@eecs.umich.edu}
3785513SMichael.Adler@intel.com
3795513SMichael.Adler@intel.comvoid
3805513SMichael.Adler@intel.comFormula::reset()
3818706Sandreas.hansson@arm.com{
3825513SMichael.Adler@intel.com}
3835513SMichael.Adler@intel.com
3845513SMichael.Adler@intel.combool
3855513SMichael.Adler@intel.comFormula::zero() const
3865513SMichael.Adler@intel.com{
3873114Sgblack@eecs.umich.edu    VResult vec;
388511SN/A    result(vec);
3891706SN/A    for (VResult::size_type i = 0; i < vec.size(); ++i)
390360SN/A        if (vec[i] != 0.0)
3916701Sgblack@eecs.umich.edu            return false;
3928852Sandreas.hansson@arm.com    return true;
39310223Ssteve.reinhardt@amd.com}
394511SN/A
3953669Sbinkertn@umich.edustring
3963669Sbinkertn@umich.eduFormula::str() const
3973669Sbinkertn@umich.edu{
398511SN/A    return root ? root->str() : "";
3991458SN/A}
400511SN/A
401511SN/Avoid
4025513SMichael.Adler@intel.comenable()
4035513SMichael.Adler@intel.com{
4045513SMichael.Adler@intel.com    typedef list<Info *>::iterator iter_t;
4055513SMichael.Adler@intel.com
4065513SMichael.Adler@intel.com    iter_t i, end = statsList().end();
4075513SMichael.Adler@intel.com    for (i = statsList().begin(); i != end; ++i) {
4086701Sgblack@eecs.umich.edu        Info *info = *i;
4098852Sandreas.hansson@arm.com        assert(info);
41010223Ssteve.reinhardt@amd.com        if (!info->check() || !info->baseCheck())
4115513SMichael.Adler@intel.com            panic("stat check failed for '%s' %d\n", info->name, info->id);
4125513SMichael.Adler@intel.com    }
4135513SMichael.Adler@intel.com
4145513SMichael.Adler@intel.com    off_t j = 0;
4156701Sgblack@eecs.umich.edu    for (i = statsList().begin(); i != end; ++i) {
4165513SMichael.Adler@intel.com        Info *info = *i;
4175513SMichael.Adler@intel.com        if (!(info->flags & display))
4185513SMichael.Adler@intel.com            info->name = "__Stat" + to_string(j++);
4195513SMichael.Adler@intel.com    }
4205513SMichael.Adler@intel.com
4211450SN/A    statsList().sort(Info::less);
4223114Sgblack@eecs.umich.edu
423511SN/A    for (i = statsList().begin(); i != end; ++i) {
4241706SN/A        Info *info = *i;
425511SN/A        info->enable();
4266701Sgblack@eecs.umich.edu    }
4278852Sandreas.hansson@arm.com}
4281458SN/A
429511SN/Avoid
4301706SN/Aprepare()
431511SN/A{
4328852Sandreas.hansson@arm.com    list<Info *>::iterator i = statsList().begin();
4331458SN/A    list<Info *>::iterator end = statsList().end();
434511SN/A    while (i != end) {
4353669Sbinkertn@umich.edu        Info *info = *i;
4363669Sbinkertn@umich.edu        info->prepare();
4373669Sbinkertn@umich.edu        ++i;
4383669Sbinkertn@umich.edu    }
4391706SN/A}
4401458SN/A
441511SN/ACallbackQueue resetQueue;
442511SN/A
4431706SN/Avoid
4443114Sgblack@eecs.umich.edureset()
4451706SN/A{
4461706SN/A    list<Info *>::iterator i = statsList().begin();
4471706SN/A    list<Info *>::iterator end = statsList().end();
4486701Sgblack@eecs.umich.edu    while (i != end) {
4498852Sandreas.hansson@arm.com        Info *info = *i;
4501706SN/A        info->reset();
4511706SN/A        ++i;
4526701Sgblack@eecs.umich.edu    }
4531706SN/A
4543669Sbinkertn@umich.edu    resetQueue.process();
4553669Sbinkertn@umich.edu}
4563669Sbinkertn@umich.edu
4571706SN/Avoid
4581706SN/AregisterResetCallback(Callback *cb)
4591706SN/A{
4601706SN/A    resetQueue.add(cb);
4611706SN/A}
4626111Ssteve.reinhardt@amd.com
4636111Ssteve.reinhardt@amd.com} // namespace Stats
4641706SN/A