statistics.cc revision 5599
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
51388SN/AStatData *
52388SN/ADataAccess::find() const
53388SN/A{
54695SN/A    return Database::find(const_cast<void *>((const void *)this));
55388SN/A}
56388SN/A
57441SN/Aconst StatData *
58441SN/AgetStatData(const void *stat)
59441SN/A{
60695SN/A    return Database::find(const_cast<void *>(stat));
61441SN/A}
62441SN/A
63388SN/Avoid
64388SN/ADataAccess::map(StatData *data)
65388SN/A{
66695SN/A    Database::regStat(this, data);
67388SN/A}
68388SN/A
69388SN/AStatData *
70388SN/ADataAccess::statData()
71388SN/A{
72388SN/A    StatData *ptr = find();
73388SN/A    assert(ptr);
74388SN/A    return ptr;
75388SN/A}
76388SN/A
77388SN/Aconst StatData *
78388SN/ADataAccess::statData() const
79388SN/A{
80388SN/A    const StatData *ptr = find();
81388SN/A    assert(ptr);
82388SN/A    return ptr;
83388SN/A}
84388SN/A
85388SN/Avoid
86388SN/ADataAccess::setInit()
87388SN/A{
88434SN/A    statData()->flags |= init;
89388SN/A}
90388SN/A
91388SN/Avoid
92388SN/ADataAccess::setPrint()
93388SN/A{
94695SN/A    Database::regPrint(this);
95388SN/A}
96388SN/A
97582SN/AStatData::StatData()
98582SN/A    : flags(none), precision(-1), prereq(0)
99582SN/A{
100695SN/A    static int count = 0;
101695SN/A    id = count++;
102582SN/A}
103582SN/A
104388SN/AStatData::~StatData()
105388SN/A{
106388SN/A}
107388SN/A
1082SN/Abool
109388SN/AStatData::less(StatData *stat1, StatData *stat2)
1102SN/A{
111388SN/A    const string &name1 = stat1->name;
112388SN/A    const string &name2 = stat2->name;
1132SN/A
1142SN/A    vector<string> v1;
1152SN/A    vector<string> v2;
1162SN/A
1172SN/A    tokenize(v1, name1, '.');
1182SN/A    tokenize(v2, name2, '.');
1192SN/A
1205599Snate@binkert.org    size_type last = min(v1.size(), v2.size()) - 1;
1215599Snate@binkert.org    for (off_type i = 0; i < last; ++i)
1222SN/A        if (v1[i] != v2[i])
1232SN/A            return v1[i] < v2[i];
1242SN/A
1252SN/A    // Special compare for last element.
1262SN/A    if (v1[last] == v2[last])
1272SN/A        return v1.size() < v2.size();
1282SN/A    else
1292SN/A        return v1[last] < v2[last];
1302SN/A
1312SN/A    return false;
1322SN/A}
1332SN/A
134388SN/Abool
135414SN/AStatData::baseCheck() const
1362SN/A{
137434SN/A    if (!(flags & init)) {
138582SN/A#ifdef DEBUG
139695SN/A        cprintf("this is stat number %d\n", id);
140388SN/A#endif
141388SN/A        panic("Not all stats have been initialized");
142388SN/A        return false;
143388SN/A    }
1442SN/A
145434SN/A    if ((flags & print) && name.empty()) {
146388SN/A        panic("all printable stats must be named");
147388SN/A        return false;
148388SN/A    }
1492SN/A
150388SN/A    return true;
1512SN/A}
1522SN/A
153695SN/A
154695SN/Avoid
155695SN/AFormulaBase::result(VResult &vec) const
1562SN/A{
157695SN/A    if (root)
158695SN/A        vec = root->result();
1592SN/A}
1602SN/A
161695SN/AResult
162388SN/AFormulaBase::total() const
163388SN/A{
164456SN/A    return root ? root->total() : 0.0;
165388SN/A}
166388SN/A
1675599Snate@binkert.orgsize_type
168388SN/AFormulaBase::size() const
169388SN/A{
170388SN/A    if (!root)
171388SN/A        return 0;
172388SN/A    else
173388SN/A        return root->size();
174388SN/A}
175388SN/A
176388SN/Avoid
177388SN/AFormulaBase::reset()
178388SN/A{
179388SN/A}
180388SN/A
181388SN/Abool
182388SN/AFormulaBase::zero() const
183388SN/A{
184695SN/A    VResult vec;
185695SN/A    result(vec);
1865599Snate@binkert.org    for (off_t i = 0; i < vec.size(); ++i)
187388SN/A        if (vec[i] != 0.0)
188388SN/A            return false;
189388SN/A    return true;
190388SN/A}
191388SN/A
192388SN/Avoid
193388SN/AFormulaBase::update(StatData *)
194388SN/A{
195388SN/A}
196388SN/A
197441SN/Astring
198441SN/AFormulaBase::str() const
199441SN/A{
200441SN/A    return root ? root->str() : "";
201441SN/A}
202441SN/A
203388SN/AFormula::Formula()
204388SN/A{
205388SN/A    setInit();
206388SN/A}
207388SN/A
208388SN/AFormula::Formula(Temp r)
209388SN/A{
210388SN/A    root = r;
211388SN/A    assert(size());
212388SN/A}
213388SN/A
214388SN/Aconst Formula &
215388SN/AFormula::operator=(Temp r)
216388SN/A{
217388SN/A    assert(!root && "Can't change formulas");
218388SN/A    root = r;
219388SN/A    assert(size());
220388SN/A    return *this;
221388SN/A}
222388SN/A
223388SN/Aconst Formula &
224388SN/AFormula::operator+=(Temp r)
225388SN/A{
226388SN/A    if (root)
227695SN/A        root = NodePtr(new BinaryNode<std::plus<Result> >(root, r));
228388SN/A    else
229388SN/A        root = r;
230388SN/A    assert(size());
231388SN/A    return *this;
232388SN/A}
233388SN/A
234142SN/Avoid
2352SN/Acheck()
2362SN/A{
237695SN/A    typedef Database::stat_list_t::iterator iter_t;
238695SN/A
239695SN/A    iter_t i, end = Database::stats().end();
240695SN/A    for (i = Database::stats().begin(); i != end; ++i) {
241695SN/A        StatData *data = *i;
242695SN/A        assert(data);
2431014SN/A        if (!data->check() || !data->baseCheck())
2441014SN/A            panic("stat check failed for %s\n", data->name);
245695SN/A    }
246695SN/A
2475599Snate@binkert.org    off_t j = 0;
248695SN/A    for (i = Database::stats().begin(); i != end; ++i) {
249695SN/A        StatData *data = *i;
250695SN/A        if (!(data->flags & print))
251695SN/A            data->name = "__Stat" + to_string(j++);
252695SN/A    }
253695SN/A
254695SN/A    Database::stats().sort(StatData::less);
255695SN/A
256695SN/A    if (i == end)
257695SN/A        return;
258695SN/A
259695SN/A    iter_t last = i;
260695SN/A    ++i;
261695SN/A
262695SN/A    for (i = Database::stats().begin(); i != end; ++i) {
263695SN/A        if ((*i)->name == (*last)->name)
264695SN/A            panic("same name used twice! name=%s\n", (*i)->name);
265695SN/A
266695SN/A        last = i;
267695SN/A    }
2682SN/A}
2692SN/A
270695SN/ACallbackQueue resetQueue;
2712SN/A
272456SN/Avoid
273695SN/Areset()
274456SN/A{
275695SN/A    Database::stat_list_t::iterator i = Database::stats().begin();
276695SN/A    Database::stat_list_t::iterator end = Database::stats().end();
277695SN/A    while (i != end) {
278695SN/A        StatData *data = *i;
2792343SN/A        data->reset();
280695SN/A        ++i;
281695SN/A    }
282695SN/A
283695SN/A    resetQueue.process();
284456SN/A}
285456SN/A
286456SN/Avoid
287394SN/AregisterResetCallback(Callback *cb)
288148SN/A{
289148SN/A    resetQueue.add(cb);
290148SN/A}
291148SN/A
292729SN/A/* namespace Stats */ }
293