statistics.cc revision 6001
12SN/A/*
21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
292SN/A */
302SN/A
312SN/A#include <iomanip>
32456SN/A#include <fstream>
332SN/A#include <list>
342SN/A#include <map>
356001Snate@binkert.org#include <set>
362SN/A#include <string>
372SN/A
38148SN/A#include "base/callback.hh"
3956SN/A#include "base/cprintf.hh"
405889Snate@binkert.org#include "base/debug.hh"
41441SN/A#include "base/hostinfo.hh"
4256SN/A#include "base/misc.hh"
4356SN/A#include "base/statistics.hh"
4456SN/A#include "base/str.hh"
45441SN/A#include "base/time.hh"
46433SN/A#include "base/trace.hh"
472SN/A
482SN/Ausing namespace std;
492SN/A
50729SN/Anamespace Stats {
51388SN/A
525887Snate@binkert.orgtypedef map<const void *, Info *> MapType;
535887Snate@binkert.org
545887Snate@binkert.org// We wrap these in a function to make sure they're built in time.
555887Snate@binkert.orglist<Info *> &
565887Snate@binkert.orgstatsList()
57388SN/A{
585887Snate@binkert.org    static list<Info *> the_list;
595887Snate@binkert.org    return the_list;
60388SN/A}
61388SN/A
625887Snate@binkert.orgMapType &
635887Snate@binkert.orgstatsMap()
64441SN/A{
655887Snate@binkert.org    static MapType the_map;
665887Snate@binkert.org    return the_map;
67441SN/A}
68441SN/A
69388SN/Avoid
705886Snate@binkert.orgInfoAccess::setInfo(Info *info)
71388SN/A{
725887Snate@binkert.org    if (statsMap().find(this) != statsMap().end())
735887Snate@binkert.org        panic("shouldn't register stat twice!");
745887Snate@binkert.org
755887Snate@binkert.org    statsList().push_back(info);
765887Snate@binkert.org
775887Snate@binkert.org#ifndef NDEBUG
785887Snate@binkert.org    pair<MapType::iterator, bool> result =
795887Snate@binkert.org#endif
805887Snate@binkert.org        statsMap().insert(make_pair(this, info));
815887Snate@binkert.org    assert(result.second && "this should never fail");
825887Snate@binkert.org    assert(statsMap().find(this) != statsMap().end());
83388SN/A}
84388SN/A
85388SN/Avoid
865889Snate@binkert.orgInfoAccess::setParams(const StorageParams *params)
875889Snate@binkert.org{
885889Snate@binkert.org    info()->storageParams = params;
895889Snate@binkert.org}
905889Snate@binkert.org
915889Snate@binkert.orgvoid
925886Snate@binkert.orgInfoAccess::setInit()
93388SN/A{
945886Snate@binkert.org    info()->flags |= init;
95388SN/A}
96388SN/A
975886Snate@binkert.orgInfo *
985886Snate@binkert.orgInfoAccess::info()
99388SN/A{
1005887Snate@binkert.org    MapType::const_iterator i = statsMap().find(this);
1015887Snate@binkert.org    assert(i != statsMap().end());
1025887Snate@binkert.org    return (*i).second;
103388SN/A}
104388SN/A
1055886Snate@binkert.orgconst Info *
1065886Snate@binkert.orgInfoAccess::info() const
1075886Snate@binkert.org{
1085887Snate@binkert.org    MapType::const_iterator i = statsMap().find(this);
1095887Snate@binkert.org    assert(i != statsMap().end());
1105887Snate@binkert.org    return (*i).second;
1115886Snate@binkert.org}
1125886Snate@binkert.org
1135889Snate@binkert.orgStorageParams::~StorageParams()
1145889Snate@binkert.org{
1155889Snate@binkert.org}
1165889Snate@binkert.org
1175889Snate@binkert.orgint Info::id_count = 0;
1185889Snate@binkert.org
1195889Snate@binkert.orgint debug_break_id = -1;
1205889Snate@binkert.org
1215886Snate@binkert.orgInfo::Info()
1225889Snate@binkert.org    : flags(none), precision(-1), prereq(0), storageParams(NULL)
123582SN/A{
1245889Snate@binkert.org    id = id_count++;
1255889Snate@binkert.org    if (debug_break_id >= 0 and debug_break_id == id)
1265889Snate@binkert.org        debug_break();
127582SN/A}
128582SN/A
1295886Snate@binkert.orgInfo::~Info()
130388SN/A{
131388SN/A}
132388SN/A
1332SN/Abool
1345886Snate@binkert.orgInfo::less(Info *stat1, Info *stat2)
1352SN/A{
136388SN/A    const string &name1 = stat1->name;
137388SN/A    const string &name2 = stat2->name;
1382SN/A
1392SN/A    vector<string> v1;
1402SN/A    vector<string> v2;
1412SN/A
1422SN/A    tokenize(v1, name1, '.');
1432SN/A    tokenize(v2, name2, '.');
1442SN/A
1455599Snate@binkert.org    size_type last = min(v1.size(), v2.size()) - 1;
1465599Snate@binkert.org    for (off_type i = 0; i < last; ++i)
1472SN/A        if (v1[i] != v2[i])
1482SN/A            return v1[i] < v2[i];
1492SN/A
1502SN/A    // Special compare for last element.
1512SN/A    if (v1[last] == v2[last])
1522SN/A        return v1.size() < v2.size();
1532SN/A    else
1542SN/A        return v1[last] < v2[last];
1552SN/A
1562SN/A    return false;
1572SN/A}
1582SN/A
159388SN/Abool
1605886Snate@binkert.orgInfo::baseCheck() const
1612SN/A{
1626000Snate@binkert.org    if (!(flags & Stats::init)) {
163582SN/A#ifdef DEBUG
164695SN/A        cprintf("this is stat number %d\n", id);
165388SN/A#endif
166388SN/A        panic("Not all stats have been initialized");
167388SN/A        return false;
168388SN/A    }
1692SN/A
170434SN/A    if ((flags & print) && name.empty()) {
171388SN/A        panic("all printable stats must be named");
172388SN/A        return false;
173388SN/A    }
1742SN/A
175388SN/A    return true;
1762SN/A}
1772SN/A
1786001Snate@binkert.orgvoid
1796001Snate@binkert.orgInfo::enable()
1806001Snate@binkert.org{
1816001Snate@binkert.org}
1826001Snate@binkert.org
1836001Snate@binkert.orgvoid
1846001Snate@binkert.orgVectorInfoBase::enable()
1856001Snate@binkert.org{
1866001Snate@binkert.org    size_type s = size();
1876001Snate@binkert.org    if (subnames.size() < s)
1886001Snate@binkert.org        subnames.resize(s);
1896001Snate@binkert.org    if (subdescs.size() < s)
1906001Snate@binkert.org        subdescs.resize(s);
1916001Snate@binkert.org}
1926001Snate@binkert.org
1936001Snate@binkert.orgvoid
1946001Snate@binkert.orgVectorDistInfoBase::enable()
1956001Snate@binkert.org{
1966001Snate@binkert.org    size_type s = size();
1976001Snate@binkert.org    if (subnames.size() < s)
1986001Snate@binkert.org        subnames.resize(s);
1996001Snate@binkert.org    if (subdescs.size() < s)
2006001Snate@binkert.org        subdescs.resize(s);
2016001Snate@binkert.org}
2026001Snate@binkert.org
2036001Snate@binkert.orgvoid
2046001Snate@binkert.orgVector2dInfoBase::enable()
2056001Snate@binkert.org{
2066001Snate@binkert.org    if (subnames.size() < x)
2076001Snate@binkert.org        subnames.resize(x);
2086001Snate@binkert.org    if (subdescs.size() < x)
2096001Snate@binkert.org        subdescs.resize(x);
2106001Snate@binkert.org    if (y_subnames.size() < y)
2116001Snate@binkert.org        y_subnames.resize(y);
2126001Snate@binkert.org}
213695SN/A
214388SN/AFormula::Formula()
215388SN/A{
216388SN/A    setInit();
217388SN/A}
218388SN/A
219388SN/AFormula::Formula(Temp r)
220388SN/A{
221388SN/A    root = r;
222388SN/A    assert(size());
223388SN/A}
224388SN/A
225388SN/Aconst Formula &
226388SN/AFormula::operator=(Temp r)
227388SN/A{
228388SN/A    assert(!root && "Can't change formulas");
229388SN/A    root = r;
230388SN/A    assert(size());
231388SN/A    return *this;
232388SN/A}
233388SN/A
234388SN/Aconst Formula &
235388SN/AFormula::operator+=(Temp r)
236388SN/A{
237388SN/A    if (root)
238695SN/A        root = NodePtr(new BinaryNode<std::plus<Result> >(root, r));
239388SN/A    else
240388SN/A        root = r;
241388SN/A    assert(size());
242388SN/A    return *this;
243388SN/A}
244388SN/A
245142SN/Avoid
2466000Snate@binkert.orgFormula::result(VResult &vec) const
2476000Snate@binkert.org{
2486000Snate@binkert.org    if (root)
2496000Snate@binkert.org        vec = root->result();
2506000Snate@binkert.org}
2516000Snate@binkert.org
2526000Snate@binkert.orgResult
2536000Snate@binkert.orgFormula::total() const
2546000Snate@binkert.org{
2556000Snate@binkert.org    return root ? root->total() : 0.0;
2566000Snate@binkert.org}
2576000Snate@binkert.org
2586000Snate@binkert.orgsize_type
2596000Snate@binkert.orgFormula::size() const
2606000Snate@binkert.org{
2616000Snate@binkert.org    if (!root)
2626000Snate@binkert.org        return 0;
2636000Snate@binkert.org    else
2646000Snate@binkert.org        return root->size();
2656000Snate@binkert.org}
2666000Snate@binkert.org
2676000Snate@binkert.orgvoid
2686000Snate@binkert.orgFormula::reset()
2696000Snate@binkert.org{
2706000Snate@binkert.org}
2716000Snate@binkert.org
2726000Snate@binkert.orgbool
2736000Snate@binkert.orgFormula::zero() const
2746000Snate@binkert.org{
2756000Snate@binkert.org    VResult vec;
2766000Snate@binkert.org    result(vec);
2776000Snate@binkert.org    for (off_t i = 0; i < vec.size(); ++i)
2786000Snate@binkert.org        if (vec[i] != 0.0)
2796000Snate@binkert.org            return false;
2806000Snate@binkert.org    return true;
2816000Snate@binkert.org}
2826000Snate@binkert.org
2836000Snate@binkert.orgstring
2846000Snate@binkert.orgFormula::str() const
2856000Snate@binkert.org{
2866000Snate@binkert.org    return root ? root->str() : "";
2876000Snate@binkert.org}
2886000Snate@binkert.org
2896000Snate@binkert.orgvoid
2906001Snate@binkert.orgenable()
2912SN/A{
2925887Snate@binkert.org    typedef list<Info *>::iterator iter_t;
293695SN/A
2945887Snate@binkert.org    iter_t i, end = statsList().end();
2955887Snate@binkert.org    for (i = statsList().begin(); i != end; ++i) {
2965886Snate@binkert.org        Info *info = *i;
2975886Snate@binkert.org        assert(info);
2985886Snate@binkert.org        if (!info->check() || !info->baseCheck())
2995889Snate@binkert.org            panic("stat check failed for '%s' %d\n", info->name, info->id);
300695SN/A    }
301695SN/A
3025599Snate@binkert.org    off_t j = 0;
3035887Snate@binkert.org    for (i = statsList().begin(); i != end; ++i) {
3045886Snate@binkert.org        Info *info = *i;
3055886Snate@binkert.org        if (!(info->flags & print))
3065886Snate@binkert.org            info->name = "__Stat" + to_string(j++);
307695SN/A    }
308695SN/A
3095887Snate@binkert.org    statsList().sort(Info::less);
310695SN/A
3116001Snate@binkert.org    for (i = statsList().begin(); i != end; ++i) {
3126001Snate@binkert.org        Info *info = *i;
3136001Snate@binkert.org        info->enable();
3146001Snate@binkert.org    }
3156001Snate@binkert.org}
316695SN/A
3176001Snate@binkert.orgvoid
3186001Snate@binkert.orgprepare()
3196001Snate@binkert.org{
3206001Snate@binkert.org    list<Info *>::iterator i = statsList().begin();
3216001Snate@binkert.org    list<Info *>::iterator end = statsList().end();
3226001Snate@binkert.org    while (i != end) {
3236001Snate@binkert.org        Info *info = *i;
3246001Snate@binkert.org        info->prepare();
3256001Snate@binkert.org        ++i;
326695SN/A    }
3272SN/A}
3282SN/A
329695SN/ACallbackQueue resetQueue;
3302SN/A
331456SN/Avoid
332695SN/Areset()
333456SN/A{
3345887Snate@binkert.org    list<Info *>::iterator i = statsList().begin();
3355887Snate@binkert.org    list<Info *>::iterator end = statsList().end();
336695SN/A    while (i != end) {
3375886Snate@binkert.org        Info *info = *i;
3385886Snate@binkert.org        info->reset();
339695SN/A        ++i;
340695SN/A    }
341695SN/A
342695SN/A    resetQueue.process();
343456SN/A}
344456SN/A
345456SN/Avoid
346394SN/AregisterResetCallback(Callback *cb)
347148SN/A{
348148SN/A    resetQueue.add(cb);
349148SN/A}
350148SN/A
351729SN/A/* namespace Stats */ }
352