Deleted Added
sdiff udiff text old ( 6000:4f887be9e1b6 ) new ( 6001:00251eb95de7 )
full compact
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 */
30
31#include <iomanip>
32#include <fstream>
33#include <list>
34#include <map>
35#include <string>
36
37#include "base/callback.hh"
38#include "base/cprintf.hh"
39#include "base/debug.hh"
40#include "base/hostinfo.hh"
41#include "base/misc.hh"
42#include "base/statistics.hh"
43#include "base/str.hh"
44#include "base/time.hh"
45#include "base/trace.hh"
46
47using namespace std;
48
49namespace Stats {
50
51typedef map<const void *, Info *> MapType;
52
53// We wrap these in a function to make sure they're built in time.
54list<Info *> &
55statsList()
56{
57 static list<Info *> the_list;
58 return the_list;
59}
60
61MapType &
62statsMap()
63{
64 static MapType the_map;
65 return the_map;
66}
67
68void
69InfoAccess::setInfo(Info *info)
70{
71 if (statsMap().find(this) != statsMap().end())
72 panic("shouldn't register stat twice!");
73
74 statsList().push_back(info);
75
76#ifndef NDEBUG
77 pair<MapType::iterator, bool> result =
78#endif
79 statsMap().insert(make_pair(this, info));
80 assert(result.second && "this should never fail");
81 assert(statsMap().find(this) != statsMap().end());
82}
83
84void
85InfoAccess::setParams(const StorageParams *params)
86{
87 info()->storageParams = params;
88}
89
90void
91InfoAccess::setInit()
92{
93 info()->flags |= init;
94}
95
96Info *
97InfoAccess::info()
98{
99 MapType::const_iterator i = statsMap().find(this);
100 assert(i != statsMap().end());
101 return (*i).second;
102}
103
104const Info *
105InfoAccess::info() const
106{
107 MapType::const_iterator i = statsMap().find(this);
108 assert(i != statsMap().end());
109 return (*i).second;
110}
111
112StorageParams::~StorageParams()
113{
114}
115
116int Info::id_count = 0;
117
118int debug_break_id = -1;
119
120Info::Info()
121 : flags(none), precision(-1), prereq(0), storageParams(NULL)
122{
123 id = id_count++;
124 if (debug_break_id >= 0 and debug_break_id == id)
125 debug_break();
126}
127
128Info::~Info()
129{
130}
131
132bool
133Info::less(Info *stat1, Info *stat2)
134{
135 const string &name1 = stat1->name;
136 const string &name2 = stat2->name;
137
138 vector<string> v1;
139 vector<string> v2;
140
141 tokenize(v1, name1, '.');
142 tokenize(v2, name2, '.');
143
144 size_type last = min(v1.size(), v2.size()) - 1;
145 for (off_type i = 0; i < last; ++i)
146 if (v1[i] != v2[i])
147 return v1[i] < v2[i];
148
149 // Special compare for last element.
150 if (v1[last] == v2[last])
151 return v1.size() < v2.size();
152 else
153 return v1[last] < v2[last];
154
155 return false;
156}
157
158bool
159Info::baseCheck() const
160{
161 if (!(flags & Stats::init)) {
162#ifdef DEBUG
163 cprintf("this is stat number %d\n", id);
164#endif
165 panic("Not all stats have been initialized");
166 return false;
167 }
168
169 if ((flags & print) && name.empty()) {
170 panic("all printable stats must be named");
171 return false;
172 }
173
174 return true;
175}
176
177
178Formula::Formula()
179{
180 setInit();
181}
182
183Formula::Formula(Temp r)
184{
185 root = r;
186 assert(size());
187}
188
189const Formula &
190Formula::operator=(Temp r)
191{
192 assert(!root && "Can't change formulas");
193 root = r;
194 assert(size());
195 return *this;
196}
197
198const Formula &
199Formula::operator+=(Temp r)
200{
201 if (root)
202 root = NodePtr(new BinaryNode<std::plus<Result> >(root, r));
203 else
204 root = r;
205 assert(size());
206 return *this;
207}
208
209void
210Formula::result(VResult &vec) const
211{
212 if (root)
213 vec = root->result();
214}
215
216Result
217Formula::total() const
218{
219 return root ? root->total() : 0.0;
220}
221
222size_type
223Formula::size() const
224{
225 if (!root)
226 return 0;
227 else
228 return root->size();
229}
230
231void
232Formula::reset()
233{
234}
235
236bool
237Formula::zero() const
238{
239 VResult vec;
240 result(vec);
241 for (off_t i = 0; i < vec.size(); ++i)
242 if (vec[i] != 0.0)
243 return false;
244 return true;
245}
246
247void
248Formula::update()
249{
250}
251
252string
253Formula::str() const
254{
255 return root ? root->str() : "";
256}
257
258void
259check()
260{
261 typedef list<Info *>::iterator iter_t;
262
263 iter_t i, end = statsList().end();
264 for (i = statsList().begin(); i != end; ++i) {
265 Info *info = *i;
266 assert(info);
267 if (!info->check() || !info->baseCheck())
268 panic("stat check failed for '%s' %d\n", info->name, info->id);
269 }
270
271 off_t j = 0;
272 for (i = statsList().begin(); i != end; ++i) {
273 Info *info = *i;
274 if (!(info->flags & print))
275 info->name = "__Stat" + to_string(j++);
276 }
277
278 statsList().sort(Info::less);
279
280 if (i == end)
281 return;
282
283 iter_t last = i;
284 ++i;
285
286 for (i = statsList().begin(); i != end; ++i) {
287 if ((*i)->name == (*last)->name)
288 panic("same name used twice! name=%s\n", (*i)->name);
289
290 last = i;
291 }
292}
293
294CallbackQueue resetQueue;
295
296void
297reset()
298{
299 list<Info *>::iterator i = statsList().begin();
300 list<Info *>::iterator end = statsList().end();
301 while (i != end) {
302 Info *info = *i;
303 info->reset();
304 ++i;
305 }
306
307 resetQueue.process();
308}
309
310void
311registerResetCallback(Callback *cb)
312{
313 resetQueue.add(cb);
314}
315
316/* namespace Stats */ }