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