blob: d5626e6bb1fca7097a2bd8461c16e92ce3c0c047 [file] [log] [blame]
Andreas Sandberg6f384282019-06-26 18:58:24 +01001/*
Nikos Nikoleris8cac5792020-04-03 11:57:31 +01002 * Copyright (c) 2019, 2020 Arm Limited
Andreas Sandberg6f384282019-06-26 18:58:24 +01003 * All rights reserved
4 *
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.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Andreas Sandberg6f384282019-06-26 18:58:24 +010036 */
37
38#include "base/stats/group.hh"
39
Daniel R. Carvalho9b675eb2021-05-13 12:02:34 -030040#include "base/compiler.hh"
Hoa Nguyen6c07c012020-12-04 23:57:14 -080041#include "base/logging.hh"
Daniel R. Carvalhof5204292021-03-13 13:44:42 -030042#include "base/named.hh"
Andreas Sandberg6f384282019-06-26 18:58:24 +010043#include "base/stats/info.hh"
44#include "base/trace.hh"
45#include "debug/Stats.hh"
Andreas Sandberg6f384282019-06-26 18:58:24 +010046
Daniel R. Carvalho974a47d2021-05-09 12:32:07 -030047namespace gem5
48{
49
Daniel R. Carvalho98ac0802021-05-06 20:00:51 -030050GEM5_DEPRECATED_NAMESPACE(Stats, statistics);
51namespace statistics
52{
Andreas Sandberg6f384282019-06-26 18:58:24 +010053
54Group::Group(Group *parent, const char *name)
Andreas Sandberg3e3152f2020-10-05 15:13:06 +010055 : mergedParent(nullptr)
Andreas Sandberg6f384282019-06-26 18:58:24 +010056{
57 if (parent && name) {
58 parent->addStatGroup(name, this);
59 } else if (parent && !name) {
60 parent->mergeStatGroup(this);
61 }
62}
63
64Group::~Group()
65{
66}
67
68void
69Group::regStats()
70{
71 for (auto &g : mergedStatGroups)
72 g->regStats();
73
74 for (auto &g : statGroups) {
Daniel R. Carvalho5ff1fac2021-06-08 14:39:58 -030075 if (debug::Stats) {
Daniel R. Carvalhof5204292021-03-13 13:44:42 -030076 M5_VAR_USED const Named *named = dynamic_cast<const Named *>(this);
Andreas Sandberg6f384282019-06-26 18:58:24 +010077 DPRINTF(Stats, "%s: regStats in group %s\n",
Daniel R. Carvalhof5204292021-03-13 13:44:42 -030078 named ? named->name() : "?",
Andreas Sandberg6f384282019-06-26 18:58:24 +010079 g.first);
80 }
81 g.second->regStats();
82 }
83}
84
85void
86Group::resetStats()
87{
88 for (auto &s : stats)
89 s->reset();
90
91 for (auto &g : mergedStatGroups)
92 g->resetStats();
93
94 for (auto &g : statGroups)
95 g.second->resetStats();
96}
97
98void
Andreas Sandberg7e52bf02019-09-24 10:41:17 +010099Group::preDumpStats()
100{
101 for (auto &g : mergedStatGroups)
102 g->preDumpStats();
103
104 for (auto &g : statGroups)
105 g.second->preDumpStats();
106}
107
108void
Daniel R. Carvalho98ac0802021-05-06 20:00:51 -0300109Group::addStat(statistics::Info *info)
Andreas Sandberg6f384282019-06-26 18:58:24 +0100110{
111 stats.push_back(info);
112 if (mergedParent)
113 mergedParent->addStat(info);
114}
115
116void
117Group::addStatGroup(const char *name, Group *block)
118{
Daniel R. Carvalhof43febb2021-03-15 00:17:24 -0300119 panic_if(!block, "Can't add null stat group %s", name);
Daniel R. Carvalhoaf2d4202021-03-15 00:07:18 -0300120 panic_if(block == this, "Stat group can't be added to itself");
Hoa Nguyen6c07c012020-12-04 23:57:14 -0800121 panic_if(statGroups.find(name) != statGroups.end(),
122 "Stats of the same group share the same name `%s`.\n", name);
Andreas Sandberg6f384282019-06-26 18:58:24 +0100123
124 statGroups[name] = block;
125}
126
Nikos Nikoleris8cac5792020-04-03 11:57:31 +0100127const Info *
128Group::resolveStat(std::string name) const
129{
130 auto pos = name.find(".");
131 if (pos == std::string::npos) {
132 // look for the stat in this group
133 for (auto &info : stats) {
134 if (info->name == name) {
135 return info;
136 }
137 }
138 } else {
139 // look for the stat in subgroups
140 const std::string gname = name.substr(0, pos);
141 for (auto &g : statGroups) {
142 if (g.first == gname) {
143 return g.second->resolveStat(name.substr(pos + 1));
144 }
145 }
146 }
147
148 // finally look for the stat in groups that have been merged
149 for (auto &g : mergedStatGroups) {
150 auto info = g->resolveStat(name);
151 if (info) {
152 return info;
153 }
154 }
155
156 return nullptr;
157}
158
Andreas Sandberg6f384282019-06-26 18:58:24 +0100159void
160Group::mergeStatGroup(Group *block)
161{
Andreas Sandberg3e3152f2020-10-05 15:13:06 +0100162 panic_if(!block, "No stat block provided");
163 panic_if(block->mergedParent,
164 "Stat group already merged into another group");
165 panic_if(block == this, "Stat group can't merge with itself");
166
167 // Track the new stat group
Andreas Sandberg6f384282019-06-26 18:58:24 +0100168 mergedStatGroups.push_back(block);
Andreas Sandberg3e3152f2020-10-05 15:13:06 +0100169
170 // We might not have seen stats that were associated with the
171 // child group before it was merged, so add them here.
172 for (auto &s : block->stats)
173 addStat(s);
174
175 // Setup the parent pointer so the child know that it needs to
176 // register new stats with the parent.
177 block->mergedParent = this;
Andreas Sandberg6f384282019-06-26 18:58:24 +0100178}
179
180const std::map<std::string, Group *> &
181Group::getStatGroups() const
182{
183 return statGroups;
184}
185
186const std::vector<Info *> &
187Group::getStats() const
188{
189 return stats;
190}
191
Daniel R. Carvalho98ac0802021-05-06 20:00:51 -0300192} // namespace statistics
Daniel R. Carvalho974a47d2021-05-09 12:32:07 -0300193} // namespace gem5