statistics.cc revision 5886
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>
352SN/A#include <string>
362SN/A
37148SN/A#include "base/callback.hh"
3856SN/A#include "base/cprintf.hh"
39441SN/A#include "base/hostinfo.hh"
4056SN/A#include "base/misc.hh"
4156SN/A#include "base/statistics.hh"
4256SN/A#include "base/str.hh"
43441SN/A#include "base/time.hh"
44433SN/A#include "base/trace.hh"
45695SN/A#include "base/stats/statdb.hh"
462SN/A
472SN/Ausing namespace std;
482SN/A
49729SN/Anamespace Stats {
50388SN/A
515886Snate@binkert.orgInfo *
525886Snate@binkert.orgInfoAccess::find() const
53388SN/A{
54695SN/A    return Database::find(const_cast<void *>((const void *)this));
55388SN/A}
56388SN/A
575886Snate@binkert.orgconst Info *
585886Snate@binkert.orggetInfo(const void *stat)
59441SN/A{
60695SN/A    return Database::find(const_cast<void *>(stat));
61441SN/A}
62441SN/A
63388SN/Avoid
645886Snate@binkert.orgInfoAccess::setInfo(Info *info)
65388SN/A{
665886Snate@binkert.org    Database::regStat(this, info);
67388SN/A}
68388SN/A
69388SN/Avoid
705886Snate@binkert.orgInfoAccess::setInit()
71388SN/A{
725886Snate@binkert.org    info()->flags |= init;
73388SN/A}
74388SN/A
755886Snate@binkert.orgInfo *
765886Snate@binkert.orgInfoAccess::info()
77388SN/A{
785886Snate@binkert.org    Info *info = find();
795886Snate@binkert.org    assert(info);
805886Snate@binkert.org    return info;
81388SN/A}
82388SN/A
835886Snate@binkert.orgconst Info *
845886Snate@binkert.orgInfoAccess::info() const
855886Snate@binkert.org{
865886Snate@binkert.org    const Info *info = find();
875886Snate@binkert.org    assert(info);
885886Snate@binkert.org    return info;
895886Snate@binkert.org}
905886Snate@binkert.org
915886Snate@binkert.orgInfo::Info()
92582SN/A    : flags(none), precision(-1), prereq(0)
93582SN/A{
94695SN/A    static int count = 0;
95695SN/A    id = count++;
96582SN/A}
97582SN/A
985886Snate@binkert.orgInfo::~Info()
99388SN/A{
100388SN/A}
101388SN/A
1022SN/Abool
1035886Snate@binkert.orgInfo::less(Info *stat1, Info *stat2)
1042SN/A{
105388SN/A    const string &name1 = stat1->name;
106388SN/A    const string &name2 = stat2->name;
1072SN/A
1082SN/A    vector<string> v1;
1092SN/A    vector<string> v2;
1102SN/A
1112SN/A    tokenize(v1, name1, '.');
1122SN/A    tokenize(v2, name2, '.');
1132SN/A
1145599Snate@binkert.org    size_type last = min(v1.size(), v2.size()) - 1;
1155599Snate@binkert.org    for (off_type i = 0; i < last; ++i)
1162SN/A        if (v1[i] != v2[i])
1172SN/A            return v1[i] < v2[i];
1182SN/A
1192SN/A    // Special compare for last element.
1202SN/A    if (v1[last] == v2[last])
1212SN/A        return v1.size() < v2.size();
1222SN/A    else
1232SN/A        return v1[last] < v2[last];
1242SN/A
1252SN/A    return false;
1262SN/A}
1272SN/A
128388SN/Abool
1295886Snate@binkert.orgInfo::baseCheck() const
1302SN/A{
131434SN/A    if (!(flags & init)) {
132582SN/A#ifdef DEBUG
133695SN/A        cprintf("this is stat number %d\n", id);
134388SN/A#endif
135388SN/A        panic("Not all stats have been initialized");
136388SN/A        return false;
137388SN/A    }
1382SN/A
139434SN/A    if ((flags & print) && name.empty()) {
140388SN/A        panic("all printable stats must be named");
141388SN/A        return false;
142388SN/A    }
1432SN/A
144388SN/A    return true;
1452SN/A}
1462SN/A
147695SN/A
148695SN/Avoid
149695SN/AFormulaBase::result(VResult &vec) const
1502SN/A{
151695SN/A    if (root)
152695SN/A        vec = root->result();
1532SN/A}
1542SN/A
155695SN/AResult
156388SN/AFormulaBase::total() const
157388SN/A{
158456SN/A    return root ? root->total() : 0.0;
159388SN/A}
160388SN/A
1615599Snate@binkert.orgsize_type
162388SN/AFormulaBase::size() const
163388SN/A{
164388SN/A    if (!root)
165388SN/A        return 0;
166388SN/A    else
167388SN/A        return root->size();
168388SN/A}
169388SN/A
170388SN/Avoid
171388SN/AFormulaBase::reset()
172388SN/A{
173388SN/A}
174388SN/A
175388SN/Abool
176388SN/AFormulaBase::zero() const
177388SN/A{
178695SN/A    VResult vec;
179695SN/A    result(vec);
1805599Snate@binkert.org    for (off_t i = 0; i < vec.size(); ++i)
181388SN/A        if (vec[i] != 0.0)
182388SN/A            return false;
183388SN/A    return true;
184388SN/A}
185388SN/A
186388SN/Avoid
1875886Snate@binkert.orgFormulaBase::update(Info *)
188388SN/A{
189388SN/A}
190388SN/A
191441SN/Astring
192441SN/AFormulaBase::str() const
193441SN/A{
194441SN/A    return root ? root->str() : "";
195441SN/A}
196441SN/A
197388SN/AFormula::Formula()
198388SN/A{
199388SN/A    setInit();
200388SN/A}
201388SN/A
202388SN/AFormula::Formula(Temp r)
203388SN/A{
204388SN/A    root = r;
205388SN/A    assert(size());
206388SN/A}
207388SN/A
208388SN/Aconst Formula &
209388SN/AFormula::operator=(Temp r)
210388SN/A{
211388SN/A    assert(!root && "Can't change formulas");
212388SN/A    root = r;
213388SN/A    assert(size());
214388SN/A    return *this;
215388SN/A}
216388SN/A
217388SN/Aconst Formula &
218388SN/AFormula::operator+=(Temp r)
219388SN/A{
220388SN/A    if (root)
221695SN/A        root = NodePtr(new BinaryNode<std::plus<Result> >(root, r));
222388SN/A    else
223388SN/A        root = r;
224388SN/A    assert(size());
225388SN/A    return *this;
226388SN/A}
227388SN/A
228142SN/Avoid
2292SN/Acheck()
2302SN/A{
231695SN/A    typedef Database::stat_list_t::iterator iter_t;
232695SN/A
233695SN/A    iter_t i, end = Database::stats().end();
234695SN/A    for (i = Database::stats().begin(); i != end; ++i) {
2355886Snate@binkert.org        Info *info = *i;
2365886Snate@binkert.org        assert(info);
2375886Snate@binkert.org        if (!info->check() || !info->baseCheck())
2385886Snate@binkert.org            panic("stat check failed for %s\n", info->name);
239695SN/A    }
240695SN/A
2415599Snate@binkert.org    off_t j = 0;
242695SN/A    for (i = Database::stats().begin(); i != end; ++i) {
2435886Snate@binkert.org        Info *info = *i;
2445886Snate@binkert.org        if (!(info->flags & print))
2455886Snate@binkert.org            info->name = "__Stat" + to_string(j++);
246695SN/A    }
247695SN/A
2485886Snate@binkert.org    Database::stats().sort(Info::less);
249695SN/A
250695SN/A    if (i == end)
251695SN/A        return;
252695SN/A
253695SN/A    iter_t last = i;
254695SN/A    ++i;
255695SN/A
256695SN/A    for (i = Database::stats().begin(); i != end; ++i) {
257695SN/A        if ((*i)->name == (*last)->name)
258695SN/A            panic("same name used twice! name=%s\n", (*i)->name);
259695SN/A
260695SN/A        last = i;
261695SN/A    }
2622SN/A}
2632SN/A
264695SN/ACallbackQueue resetQueue;
2652SN/A
266456SN/Avoid
267695SN/Areset()
268456SN/A{
269695SN/A    Database::stat_list_t::iterator i = Database::stats().begin();
270695SN/A    Database::stat_list_t::iterator end = Database::stats().end();
271695SN/A    while (i != end) {
2725886Snate@binkert.org        Info *info = *i;
2735886Snate@binkert.org        info->reset();
274695SN/A        ++i;
275695SN/A    }
276695SN/A
277695SN/A    resetQueue.process();
278456SN/A}
279456SN/A
280456SN/Avoid
281394SN/AregisterResetCallback(Callback *cb)
282148SN/A{
283148SN/A    resetQueue.add(cb);
284148SN/A}
285148SN/A
286729SN/A/* namespace Stats */ }
287