ruby: get rid of Vector and use STL
[gem5.git] / src / mem / ruby / common / Debug.cc
1 /*
2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
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
29 #include <fstream>
30 #include <stdarg.h>
31
32 #include "base/misc.hh"
33 #include "mem/ruby/common/Debug.hh"
34 #include "mem/ruby/common/Global.hh"
35 #include "mem/ruby/eventqueue/RubyEventQueue.hh"
36
37 using namespace std;
38
39 class Debug;
40 extern Debug* g_debug_ptr;
41 ostream *debug_cout_ptr;
42
43 bool Debug::m_protocol_trace = false;
44 struct DebugComponentData
45 {
46 const char *desc;
47 const char ch;
48 };
49
50 // component character list
51 DebugComponentData debugComponents[] =
52 {
53 {"System", 's' },
54 {"Node", 'N' },
55 {"Queue", 'q' },
56 {"Event Queue", 'e' },
57 {"Network", 'n' },
58 {"Sequencer", 'S' },
59 {"Tester", 't' },
60 {"Generated", 'g' },
61 {"SLICC", 'l' },
62 {"Network Queues", 'Q' },
63 {"Time", 'T' },
64 {"Network Internals", 'i' },
65 {"Store Buffer", 'b' },
66 {"Cache", 'c' },
67 {"Predictor", 'p' },
68 {"Memory", 'M' },
69 };
70
71 extern "C" void changeDebugVerbosity(VerbosityLevel vb);
72 extern "C" void changeDebugFilter(int filter);
73
74 void
75 changeDebugVerbosity(VerbosityLevel vb)
76 {
77 g_debug_ptr->setVerbosity(vb);
78 }
79
80 void
81 changeDebugFilter(int filter)
82 {
83 g_debug_ptr->setFilter(filter);
84 }
85
86 Debug::Debug(const Params *p)
87 : SimObject(p)
88 {
89 clearFilter();
90 debug_cout_ptr = &cout;
91
92 setFilterString(p->filter_string.c_str());
93 setVerbosityString(p->verbosity_string.c_str());
94 setDebugOutputFile(p->output_filename.c_str());
95 m_starting_cycle = p->start_time;
96 m_protocol_trace = p->protocol_trace;
97 g_debug_ptr = this;
98 }
99
100 Debug::~Debug()
101 {
102 }
103
104 void
105 Debug::printVerbosity(ostream& out) const
106 {
107 switch (getVerbosity()) {
108 case No_Verb:
109 out << "verbosity = No_Verb" << endl;
110 break;
111 case Low_Verb:
112 out << "verbosity = Low_Verb" << endl;
113 break;
114 case Med_Verb:
115 out << "verbosity = Med_Verb" << endl;
116 break;
117 case High_Verb:
118 out << "verbosity = High_Verb" << endl;
119 break;
120 default:
121 out << "verbosity = unknown" << endl;
122 }
123 }
124
125 bool
126 Debug::validDebug(int module, PriorityLevel priority)
127 {
128 int local_module = (1 << module);
129 if (m_filter & local_module) {
130 if (g_eventQueue_ptr == NULL ||
131 g_eventQueue_ptr->getTime() >= m_starting_cycle) {
132 switch (m_verbosityLevel) {
133 case No_Verb:
134 return false;
135 case Low_Verb:
136 return (priority == HighPrio);
137 case Med_Verb:
138 return (priority == HighPrio || priority == MedPrio);
139 case High_Verb:
140 return true;
141 }
142 }
143 }
144 return false;
145 }
146
147 void
148 Debug::setDebugTime(Time t)
149 {
150 m_starting_cycle = t;
151 }
152
153 void
154 Debug::setVerbosity(VerbosityLevel vb)
155 {
156 m_verbosityLevel = vb;
157 }
158
159 void
160 Debug::setFilter(int filter)
161 {
162 m_filter = filter;
163 }
164
165 bool
166 Debug::setVerbosityString(const char *verb_str)
167 {
168 string verb = verb_str ? verb_str : "";
169 if (verb == "none") {
170 setVerbosity(No_Verb);
171 } else if (verb == "low") {
172 setVerbosity(Low_Verb);
173 } else if (verb == "med") {
174 setVerbosity(Med_Verb);
175 } else if (verb == "high") {
176 setVerbosity(High_Verb);
177 } else {
178 cerr << "Error: unrecognized verbosity (use none, low, med, high): "
179 << verb << endl;
180 return true; // error
181 }
182 return false; // no error
183 }
184
185 bool
186 Debug::checkFilter(char ch)
187 {
188 for (int i = 0; i < NUMBER_OF_COMPS; i++) {
189 // Look at all components to find a character match
190 if (debugComponents[i].ch == ch) {
191 // We found a match - return no error
192 return false; // no error
193 }
194 }
195 return true; // error
196 }
197
198 bool
199 Debug::checkFilterString(const char *filter_str)
200 {
201 if (filter_str == NULL) {
202 cerr << "Error: unrecognized component filter: NULL" << endl;
203 return true; // error
204 }
205
206 // check for default filter ("none") before reporting RUBY_DEBUG error
207 if (string(filter_str) == "none") {
208 return false; // no error
209 }
210
211 if (RUBY_DEBUG == false) {
212 cerr << "Error: User specified set of debug components, but the "
213 << "RUBY_DEBUG compile-time flag is false." << endl
214 << "Solution: Re-compile with RUBY_DEBUG set to true." << endl;
215 return true; // error
216 }
217
218 if (string(filter_str) == "all") {
219 return false; // no error
220 }
221
222 // scan string checking each character
223 for (unsigned int i = 0; i < strlen(filter_str); i++) {
224 bool unrecognized = checkFilter(filter_str[i]);
225 if (unrecognized == true) {
226 return true; // error
227 }
228 }
229 return false; // no error
230 }
231
232 bool
233 Debug::setFilterString(const char *filter_str)
234 {
235 if (checkFilterString(filter_str)) {
236 return true; // error
237 }
238
239 if (string(filter_str) == "all" ) {
240 allFilter();
241 } else if (string(filter_str) == "none") {
242 clearFilter();
243 } else {
244 // scan string adding to bit mask for each component which is present
245 for (unsigned int i = 0; i < strlen(filter_str); i++) {
246 bool error = addFilter( filter_str[i] );
247 if (error) {
248 return true; // error
249 }
250 }
251 }
252 return false; // no error
253 }
254
255 bool
256 Debug::addFilter(char ch)
257 {
258 for (int i = 0; i < NUMBER_OF_COMPS; i++) {
259 // Look at all components to find a character match
260 if (debugComponents[i].ch == ch) {
261 // We found a match - update the filter bit mask
262 cout << " Debug: Adding to filter: '" << ch << "' ("
263 << debugComponents[i].desc << ")" << endl;
264 m_filter |= (1 << i);
265 return false; // no error
266 }
267 }
268
269 // We didn't find the character
270 cerr << "Error: unrecognized component filter: " << ch << endl;
271 usageInstructions();
272 return true; // error
273 }
274
275 void
276 Debug::clearFilter()
277 {
278 m_filter = 0;
279 }
280
281 void Debug::allFilter()
282 {
283 m_filter = ~0;
284 }
285
286 void
287 Debug::usageInstructions(void)
288 {
289 cerr << "Debug components: " << endl;
290 for (int i = 0; i < NUMBER_OF_COMPS; i++) {
291 cerr << " " << debugComponents[i].ch << ": "
292 << debugComponents[i].desc << endl;
293 }
294 }
295
296 void
297 Debug::print(ostream& out) const
298 {
299 out << "[Debug]" << endl;
300 }
301
302 void
303 Debug::setDebugOutputFile (const char *filename)
304 {
305 if (filename == NULL || !strcmp(filename, "none")) {
306 debug_cout_ptr = &cout;
307 return;
308 }
309
310 if (m_fout.is_open()) {
311 m_fout.close();
312 }
313 m_fout.open(filename, ios::out);
314 if (!m_fout.is_open()) {
315 cerr << "setDebugOutputFile: can't open file " << filename << endl;
316 } else {
317 debug_cout_ptr = &m_fout;
318 }
319 }
320
321 void
322 Debug::closeDebugOutputFile ()
323 {
324 if (m_fout.is_open()) {
325 m_fout.close ();
326 debug_cout_ptr = &cout;
327 }
328 }
329
330 void
331 Debug::debugMsg( const char *fmt, ...)
332 {
333 va_list args;
334
335 // you could check validDebug() here before printing the message
336 va_start(args, fmt);
337 vfprintf(stdout, fmt, args);
338 va_end(args);
339 }
340
341 Debug *
342 RubyDebugParams::create()
343 {
344 return new Debug(this);
345 }