ruby: Ruby debug print fixes.
[gem5.git] / src / mem / ruby / common / Debug.cc
1
2 /*
3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * $Id$
32 *
33 */
34
35 #include <fstream>
36 #include <stdarg.h>
37
38 #include "mem/ruby/common/Global.hh"
39 #include "mem/ruby/common/Debug.hh"
40 #include "mem/ruby/eventqueue/RubyEventQueue.hh"
41 #include "mem/gems_common/util.hh"
42 #include "base/misc.hh"
43
44 class Debug;
45 extern Debug* g_debug_ptr;
46 std::ostream * debug_cout_ptr;
47
48 bool Debug::m_protocol_trace = false;
49 struct DebugComponentData
50 {
51 const char *desc;
52 const char ch;
53 };
54
55 // component character list
56 DebugComponentData debugComponents[] =
57 {
58 {"System", 's' },
59 {"Node", 'N' },
60 {"Queue", 'q' },
61 {"Event Queue", 'e' },
62 {"Network", 'n' },
63 {"Sequencer", 'S' },
64 {"Tester", 't' },
65 {"Generated", 'g' },
66 {"SLICC", 'l' },
67 {"Network Queues", 'Q' },
68 {"Time", 'T' },
69 {"Network Internals", 'i' },
70 {"Store Buffer", 'b' },
71 {"Cache", 'c' },
72 {"Predictor", 'p' },
73 {"Allocator", 'a' },
74 {"Memory", 'M' },
75 };
76
77 extern "C" void changeDebugVerbosity(VerbosityLevel vb);
78 extern "C" void changeDebugFilter(int filter);
79
80 void changeDebugVerbosity(VerbosityLevel vb)
81 {
82 g_debug_ptr->setVerbosity(vb);
83 }
84
85 void changeDebugFilter(int filter)
86 {
87 g_debug_ptr->setFilter(filter);
88 }
89
90 Debug::Debug()
91 {
92 m_verbosityLevel = No_Verb;
93 m_starting_cycle = ~0;
94 clearFilter();
95 debug_cout_ptr = &cout;
96 }
97
98 Debug::Debug( const string & name, const vector<string> & argv )
99 {
100 //
101 // must clear the filter before adding filter strings
102 //
103 clearFilter();
104
105 for (size_t i=0;i<argv.size();i+=2) {
106 if (argv[i] == "filter_string") {
107 if (setFilterString(argv[i+1].c_str())) {
108 fatal("could not set filter string to %s\n", argv[i+1].c_str());
109 }
110 } else if (argv[i] == "verbosity_string") {
111 setVerbosityString( argv[i+1].c_str() );
112 } else if (argv[i] == "start_time") {
113 m_starting_cycle = atoi( argv[i+1].c_str() );
114 } else if (argv[i] == "output_filename") {
115 setDebugOutputFile( argv[i+1].c_str() );
116 } else if (argv[i] == "protocol_trace") {
117 m_protocol_trace = string_to_bool(argv[i+1]);
118 } else {
119 fatal("invalid argument %s\n");
120 }
121 }
122 }
123
124 Debug::Debug( const char *filterString, const char *verboseString,
125 Time filterStartTime, const char *filename )
126 {
127 m_verbosityLevel = No_Verb;
128 clearFilter();
129 debug_cout_ptr = &cout;
130
131 m_starting_cycle = filterStartTime;
132 if (setFilterString(filterString))
133 fatal("could not set filter string to %s\n", filterString);
134 setVerbosityString( verboseString );
135 setDebugOutputFile( filename );
136 }
137
138 Debug::~Debug()
139 {
140 }
141
142 void Debug::printVerbosity(ostream& out) const
143 {
144 switch (getVerbosity()) {
145 case No_Verb:
146 out << "verbosity = No_Verb" << endl;
147 break;
148 case Low_Verb:
149 out << "verbosity = Low_Verb" << endl;
150 break;
151 case Med_Verb:
152 out << "verbosity = Med_Verb" << endl;
153 break;
154 case High_Verb:
155 out << "verbosity = High_Verb" << endl;
156 break;
157 default:
158 out << "verbosity = unknown" << endl;
159 }
160 }
161
162 bool Debug::validDebug(int module, PriorityLevel priority)
163 {
164 int local_module = (1 << module);
165 if(m_filter & local_module) {
166 if (g_eventQueue_ptr == NULL ||
167 g_eventQueue_ptr->getTime() >= m_starting_cycle) {
168 switch(m_verbosityLevel) {
169 case No_Verb:
170 return false;
171 break;
172 case Low_Verb:
173 if(priority == HighPrio) {
174 return true;
175 }else{
176 return false;
177 }
178 break;
179 case Med_Verb:
180 if(priority == HighPrio || priority == MedPrio ) {
181 return true;
182 }else{
183 return false;
184 }
185 break;
186 case High_Verb:
187 return true;
188 break;
189 }
190 }
191 }
192 return false;
193 }
194
195 void Debug::setDebugTime(Time t)
196 {
197 m_starting_cycle = t;
198 }
199
200 void Debug::setVerbosity(VerbosityLevel vb)
201 {
202 m_verbosityLevel = vb;
203 }
204
205 void Debug::setFilter(int filter)
206 {
207 m_filter = filter;
208 }
209
210 bool Debug::checkVerbosityString(const char *verb_str)
211 {
212 if (verb_str == NULL) {
213 cerr << "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl;
214 return true; // error
215 } else if ( (string(verb_str) == "none") ||
216 (string(verb_str) == "low") ||
217 (string(verb_str) == "med") ||
218 (string(verb_str) == "high") ) {
219 return false;
220 }
221 cerr << "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl;
222 return true; // error
223 }
224
225 bool Debug::setVerbosityString(const char *verb_str)
226 {
227 bool check_fails = checkVerbosityString(verb_str);
228 if (check_fails) {
229 return true; // error
230 }
231 if (string(verb_str) == "none") {
232 setVerbosity(No_Verb);
233 } else if (string(verb_str) == "low") {
234 setVerbosity(Low_Verb);
235 } else if (string(verb_str) == "med") {
236 setVerbosity(Med_Verb);
237 } else if (string(verb_str) == "high") {
238 setVerbosity(High_Verb);
239 } else {
240 cerr << "Error: unrecognized verbosity (use none, low, med, high): " << verb_str << endl;
241 return true; // error
242 }
243 return false; // no error
244 }
245
246 bool Debug::checkFilter(char ch)
247 {
248 for (int i=0; i<NUMBER_OF_COMPS; i++) {
249 // Look at all components to find a character match
250 if (debugComponents[i].ch == ch) {
251 // We found a match - return no error
252 return false; // no error
253 }
254 }
255 return true; // error
256 }
257
258 bool Debug::checkFilterString(const char *filter_str)
259 {
260 if (filter_str == NULL) {
261 cerr << "Error: unrecognized component filter: NULL" << endl;
262 return true; // error
263 }
264
265 // check for default filter ("none") before reporting RUBY_DEBUG error
266 if ( (string(filter_str) == "none") ) {
267 return false; // no error
268 }
269
270 if (RUBY_DEBUG == false) {
271 cerr << "Error: User specified set of debug components, but the RUBY_DEBUG compile-time flag is false." << endl;
272 cerr << "Solution: Re-compile with RUBY_DEBUG set to true." << endl;
273 return true; // error
274 }
275
276 if ( (string(filter_str) == "all") ) {
277 return false; // no error
278 }
279
280 // scan string checking each character
281 for (unsigned int i = 0; i < strlen(filter_str); i++) {
282 bool unrecognized = checkFilter( filter_str[i] );
283 if (unrecognized == true) {
284 return true; // error
285 }
286 }
287 return false; // no error
288 }
289
290 bool Debug::setFilterString(const char *filter_str)
291 {
292 if (checkFilterString(filter_str)) {
293 return true; // error
294 }
295
296 if (string(filter_str) == "all" ) {
297 allFilter();
298 } else if (string(filter_str) == "none") {
299 clearFilter();
300 } else {
301 // scan string adding to bit mask for each component which is present
302 for (unsigned int i = 0; i < strlen(filter_str); i++) {
303 bool error = addFilter( filter_str[i] );
304 if (error) {
305 return true; // error
306 }
307 }
308 }
309 return false; // no error
310 }
311
312 bool Debug::addFilter(char ch)
313 {
314 for (int i=0; i<NUMBER_OF_COMPS; i++) {
315 // Look at all components to find a character match
316 if (debugComponents[i].ch == ch) {
317 // We found a match - update the filter bit mask
318 cout << " Debug: Adding to filter: '" << ch << "' (" << debugComponents[i].desc << ")" << endl;
319 m_filter |= (1 << i);
320 return false; // no error
321 }
322 }
323
324 // We didn't find the character
325 cerr << "Error: unrecognized component filter: " << ch << endl;
326 usageInstructions();
327 return true; // error
328 }
329
330 void Debug::clearFilter()
331 {
332 m_filter = 0;
333 }
334
335 void Debug::allFilter()
336 {
337 m_filter = ~0;
338 }
339
340 void Debug::usageInstructions(void)
341 {
342 cerr << "Debug components: " << endl;
343 for (int i=0; i<NUMBER_OF_COMPS; i++) {
344 cerr << " " << debugComponents[i].ch << ": " << debugComponents[i].desc << endl;
345 }
346 }
347
348 void Debug::print(ostream& out) const
349 {
350 out << "[Debug]" << endl;
351 }
352
353 void Debug::setDebugOutputFile (const char * filename)
354 {
355 if ( (filename == NULL) ||
356 (!strcmp(filename, "none")) ) {
357 debug_cout_ptr = &cout;
358 return;
359 }
360
361 if (m_fout.is_open() ) {
362 m_fout.close ();
363 }
364 m_fout.open (filename, std::ios::out);
365 if (! m_fout.is_open() ) {
366 cerr << "setDebugOutputFile: can't open file " << filename << endl;
367 }
368 else {
369 debug_cout_ptr = &m_fout;
370 }
371 }
372
373 void Debug::closeDebugOutputFile ()
374 {
375 if (m_fout.is_open() ) {
376 m_fout.close ();
377 debug_cout_ptr = &cout;
378 }
379 }
380
381 void Debug::debugMsg( const char *fmt, ... )
382 {
383 va_list args;
384
385 // you could check validDebug() here before printing the message
386 va_start(args, fmt);
387 vfprintf(stdout, fmt, args);
388 va_end(args);
389 }
390
391 /*
392 void DEBUG_OUT( const char* fmt, ...) {
393 if (RUBY_DEBUG) {
394 cout << "Debug: in fn "
395 << __PRETTY_FUNCTION__
396 << " in " << __FILE__ << ":"
397 << __LINE__ << ": ";
398 va_list args;
399 va_start(args, fmt);
400 vfprintf(stdout, fmt, args);
401 va_end(args);
402 }
403 }
404
405 void ERROR_OUT( const char* fmt, ... ) {
406 if (ERROR_MESSAGE_FLAG) {
407 cout << "error: in fn "
408 << __PRETTY_FUNCTION__ << " in "
409 << __FILE__ << ":"
410 << __LINE__ << ": ";
411 va_list args;
412 va_start(args, fmt);
413 vfprintf(stdout, fmt, args);
414 va_end(args);
415 }
416 assert(0);
417 }
418 */
419