2 * Copyright (c) 2019-2020 Arm Limited
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #include "base/statistics.hh"
49 #include "base/callback.hh"
50 #include "base/logging.hh"
51 #include "sim/root.hh"
55 // We wrap these in a function to make sure they're built in time.
59 static std::list
<Info
*> the_list
;
66 static MapType the_map
;
71 InfoAccess::setInfo(Group
*parent
, Info
*info
)
73 panic_if(statsMap().find(this) != statsMap().end() ||
75 "shouldn't register stat twice!");
77 // New-style stats are reachable through the hierarchy and
78 // shouldn't be added to the global lists.
84 statsList().push_back(info
);
87 std::pair
<MapType::iterator
, bool> result
=
89 statsMap().insert(std::make_pair(this, info
));
90 assert(result
.second
&& "this should never fail");
91 assert(statsMap().find(this) != statsMap().end());
95 InfoAccess::setParams(const StorageParams
*params
)
97 info()->storageParams
= params
;
101 InfoAccess::setInit()
103 info()->flags
.set(init
);
114 MapType::const_iterator i
= statsMap().find(this);
115 assert(i
!= statsMap().end());
121 InfoAccess::info() const
128 MapType::const_iterator i
= statsMap().find(this);
129 assert(i
!= statsMap().end());
134 StorageParams::~StorageParams()
141 int size
= cvec
.size();
142 int zero
= size
/ 2; // round down!
143 int top_half
= zero
+ (size
- zero
+ 1) / 2; // round up!
144 int bottom_half
= (size
- zero
) / 2; // round down!
147 int low_pair
= zero
- 1;
148 for (int i
= zero
- 1; i
>= bottom_half
; i
--) {
149 cvec
[i
] = cvec
[low_pair
];
150 if (low_pair
- 1 >= 0)
151 cvec
[i
] += cvec
[low_pair
- 1];
154 assert(low_pair
== 0 || low_pair
== -1 || low_pair
== -2);
156 for (int i
= bottom_half
- 1; i
>= 0; i
--)
160 int high_pair
= zero
;
161 for (int i
= zero
; i
< top_half
; i
++) {
162 cvec
[i
] = cvec
[high_pair
];
163 if (high_pair
+ 1 < size
)
164 cvec
[i
] += cvec
[high_pair
+ 1];
167 assert(high_pair
== size
|| high_pair
== size
+ 1);
169 for (int i
= top_half
; i
< size
; i
++)
178 HistStor::grow_convert()
180 int size
= cvec
.size();
181 int half
= (size
+ 1) / 2; // round up!
182 //bool even = (size & 1) == 0;
185 for (int i
= size
- 1; i
>= half
; --i
) {
186 cvec
[i
] = cvec
[pair
];
188 cvec
[i
] += cvec
[pair
- 1];
192 for (int i
= half
- 1; i
>= 0; i
--)
195 min_bucket
= -max_bucket
;// - (even ? bucket_size : 0);
202 int size
= cvec
.size();
203 int half
= (size
+ 1) / 2; // round up!
206 for (int i
= 0; i
< half
; i
++) {
207 cvec
[i
] = cvec
[pair
];
209 cvec
[i
] += cvec
[pair
+ 1];
212 assert(pair
== size
|| pair
== size
+ 1);
214 for (int i
= half
; i
< size
; i
++)
222 HistStor::add(HistStor
*hs
)
224 int b_size
= hs
->size();
225 assert(size() == b_size
);
226 assert(min_bucket
== hs
->min_bucket
);
230 squares
+= hs
->squares
;
231 samples
+= hs
->samples
;
233 while (bucket_size
> hs
->bucket_size
)
235 while (bucket_size
< hs
->bucket_size
)
238 for (uint32_t i
= 0; i
< b_size
; i
++)
239 cvec
[i
] += hs
->cvec
[i
];
242 Formula::Formula(Group
*parent
, const char *name
, const char *desc
)
243 : DataWrapVec
<Formula
, FormulaInfoProxy
>(parent
, name
, desc
)
250 Formula::Formula(Group
*parent
, const char *name
, const char *desc
,
252 : DataWrapVec
<Formula
, FormulaInfoProxy
>(parent
, name
, desc
)
258 Formula::operator=(const Temp
&r
)
260 assert(!root
&& "Can't change formulas");
261 root
= r
.getNodePtr();
268 Formula::operator+=(Temp r
)
271 root
= NodePtr(new BinaryNode
<std::plus
<Result
> >(root
, r
));
273 root
= r
.getNodePtr();
282 Formula::operator/=(Temp r
)
285 root
= NodePtr(new BinaryNode
<std::divides
<Result
> >(root
, r
));
293 Formula::result(VResult
&vec
) const
296 vec
= root
->result();
300 Formula::total() const
302 return root
? root
->total() : 0.0;
306 Formula::size() const
320 Formula::zero() const
324 for (VResult::size_type i
= 0; i
< vec
.size(); ++i
)
333 return root
? root
->str() : "";
336 Handler resetHandler
= NULL
;
337 Handler dumpHandler
= NULL
;
340 registerHandlers(Handler reset_handler
, Handler dump_handler
)
342 resetHandler
= reset_handler
;
343 dumpHandler
= dump_handler
;
346 CallbackQueue dumpQueue
;
347 CallbackQueue resetQueue
;
352 resetQueue
.process();
362 registerResetCallback(const std::function
<void()> &callback
)
364 resetQueue
.push_back(callback
);
367 bool _enabled
= false;
379 fatal("Stats are already enabled");
390 fatal("No registered Stats::dump handler");
399 fatal("No registered Stats::reset handler");
403 resolve(const std::string
&name
)
405 const auto &it
= nameMap().find(name
);
406 if (it
!= nameMap().cend()) {
409 return Root::root()->resolveStat(name
);
414 registerDumpCallback(const std::function
<void()> &callback
)
416 dumpQueue
.push_back(callback
);