base: Move Stats::Info functions to its own source file
[gem5.git] / src / base / stats / info.cc
1 /*
2 * Copyright (c) 2021 Daniel R. Carvalho
3 * Copyright (c) 2019 Arm Limited
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2003-2005 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
42 #include "base/stats/info.hh"
43
44 #include <cctype>
45 #include <map>
46 #include <string>
47
48 #include "base/cprintf.hh"
49 #include "base/debug.hh"
50 #include "base/logging.hh"
51 #include "base/str.hh"
52
53 namespace Stats {
54
55 std::string Info::separatorString = "::";
56
57 int Info::id_count = 0;
58
59 int debug_break_id = -1;
60
61 NameMapType &
62 nameMap()
63 {
64 static NameMapType the_map;
65 return the_map;
66 }
67
68 Info::Info()
69 : flags(none), precision(-1), prereq(0), storageParams(NULL)
70 {
71 id = id_count++;
72 if (debug_break_id >= 0 and debug_break_id == id)
73 Debug::breakpoint();
74 }
75
76 Info::~Info()
77 {
78 }
79
80 bool
81 validateStatName(const std::string &name)
82 {
83 if (name.empty())
84 return false;
85
86 std::vector<std::string> vec;
87 tokenize(vec, name, '.');
88 std::vector<std::string>::const_iterator item = vec.begin();
89 while (item != vec.end()) {
90 if (item->empty())
91 return false;
92
93 std::string::const_iterator c = item->begin();
94
95 // The first character is different
96 if (!isalpha(*c) && *c != '_')
97 return false;
98
99 // The rest of the characters have different rules.
100 while (++c != item->end()) {
101 if (!isalnum(*c) && *c != '_')
102 return false;
103 }
104
105 ++item;
106 }
107
108 return true;
109 }
110
111 void
112 Info::setName(const std::string &name)
113 {
114 setName(nullptr, name);
115 }
116
117 void
118 Info::setName(const Group *parent, const std::string &name)
119 {
120 if (!validateStatName(name))
121 panic("invalid stat name '%s'", name);
122
123 // We only register the stat with the nameMap() if we are using
124 // old-style stats without a parent group. New-style stats should
125 // be unique since their names should correspond to a member
126 // variable.
127 if (!parent) {
128 auto p = nameMap().insert(make_pair(name, this));
129
130 if (!p.second)
131 panic("same statistic name used twice! name=%s\n",
132 name);
133 }
134
135 this->name = name;
136 }
137
138 bool
139 Info::less(Info *stat1, Info *stat2)
140 {
141 const std::string &name1 = stat1->name;
142 const std::string &name2 = stat2->name;
143
144 std::vector<std::string> v1;
145 std::vector<std::string> v2;
146
147 tokenize(v1, name1, '.');
148 tokenize(v2, name2, '.');
149
150 size_type last = std::min(v1.size(), v2.size()) - 1;
151 for (off_type i = 0; i < last; ++i)
152 if (v1[i] != v2[i])
153 return v1[i] < v2[i];
154
155 // Special compare for last element.
156 if (v1[last] == v2[last])
157 return v1.size() < v2.size();
158 else
159 return v1[last] < v2[last];
160
161 return false;
162 }
163
164 bool
165 Info::baseCheck() const
166 {
167 if (!(flags & Stats::init)) {
168 #ifdef DEBUG
169 cprintf("this is stat number %d\n", id);
170 #endif
171 panic("Not all stats have been initialized.\n"
172 "You may need to add <ParentClass>::regStats() to a"
173 " new SimObject's regStats() function. Name: %s",
174 name);
175 return false;
176 }
177
178 if ((flags & display) && name.empty()) {
179 panic("all printable stats must be named");
180 return false;
181 }
182
183 return true;
184 }
185
186 void
187 Info::enable()
188 {
189 }
190
191 void
192 VectorInfo::enable()
193 {
194 size_type s = size();
195 if (subnames.size() < s)
196 subnames.resize(s);
197 if (subdescs.size() < s)
198 subdescs.resize(s);
199 }
200
201 void
202 VectorDistInfo::enable()
203 {
204 size_type s = size();
205 if (subnames.size() < s)
206 subnames.resize(s);
207 if (subdescs.size() < s)
208 subdescs.resize(s);
209 }
210
211 void
212 Vector2dInfo::enable()
213 {
214 if (subnames.size() < x)
215 subnames.resize(x);
216 if (subdescs.size() < x)
217 subdescs.resize(x);
218 if (y_subnames.size() < y)
219 y_subnames.resize(y);
220 }
221
222 } // namespace Stats