3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
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.
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.
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"
45 extern Debug
* g_debug_ptr
;
46 std::ostream
* debug_cout_ptr
;
48 bool Debug::m_protocol_trace
= false;
49 struct DebugComponentData
55 // component character list
56 DebugComponentData debugComponents
[] =
61 {"Event Queue", 'e' },
67 {"Network Queues", 'Q' },
69 {"Network Internals", 'i' },
70 {"Store Buffer", 'b' },
77 extern "C" void changeDebugVerbosity(VerbosityLevel vb
);
78 extern "C" void changeDebugFilter(int filter
);
80 void changeDebugVerbosity(VerbosityLevel vb
)
82 g_debug_ptr
->setVerbosity(vb
);
85 void changeDebugFilter(int filter
)
87 g_debug_ptr
->setFilter(filter
);
92 m_verbosityLevel
= No_Verb
;
93 m_starting_cycle
= ~0;
95 debug_cout_ptr
= &cout
;
98 Debug::Debug( const string
& name
, const vector
<string
> & argv
)
101 // must clear the filter before adding filter strings
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());
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]);
119 fatal("invalid argument %s\n");
124 Debug::Debug( const char *filterString
, const char *verboseString
,
125 Time filterStartTime
, const char *filename
)
127 m_verbosityLevel
= No_Verb
;
129 debug_cout_ptr
= &cout
;
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
);
142 void Debug::printVerbosity(ostream
& out
) const
144 switch (getVerbosity()) {
146 out
<< "verbosity = No_Verb" << endl
;
149 out
<< "verbosity = Low_Verb" << endl
;
152 out
<< "verbosity = Med_Verb" << endl
;
155 out
<< "verbosity = High_Verb" << endl
;
158 out
<< "verbosity = unknown" << endl
;
162 bool Debug::validDebug(int module
, PriorityLevel priority
)
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
) {
173 if(priority
== HighPrio
) {
180 if(priority
== HighPrio
|| priority
== MedPrio
) {
195 void Debug::setDebugTime(Time t
)
197 m_starting_cycle
= t
;
200 void Debug::setVerbosity(VerbosityLevel vb
)
202 m_verbosityLevel
= vb
;
205 void Debug::setFilter(int filter
)
210 bool Debug::checkVerbosityString(const char *verb_str
)
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") ) {
221 cerr
<< "Error: unrecognized verbosity (use none, low, med, high): NULL" << endl
;
222 return true; // error
225 bool Debug::setVerbosityString(const char *verb_str
)
227 bool check_fails
= checkVerbosityString(verb_str
);
229 return true; // error
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
);
240 cerr
<< "Error: unrecognized verbosity (use none, low, med, high): " << verb_str
<< endl
;
241 return true; // error
243 return false; // no error
246 bool Debug::checkFilter(char ch
)
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
255 return true; // error
258 bool Debug::checkFilterString(const char *filter_str
)
260 if (filter_str
== NULL
) {
261 cerr
<< "Error: unrecognized component filter: NULL" << endl
;
262 return true; // error
265 // check for default filter ("none") before reporting RUBY_DEBUG error
266 if ( (string(filter_str
) == "none") ) {
267 return false; // no error
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
276 if ( (string(filter_str
) == "all") ) {
277 return false; // no error
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
287 return false; // no error
290 bool Debug::setFilterString(const char *filter_str
)
292 if (checkFilterString(filter_str
)) {
293 return true; // error
296 if (string(filter_str
) == "all" ) {
298 } else if (string(filter_str
) == "none") {
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
] );
305 return true; // error
309 return false; // no error
312 bool Debug::addFilter(char ch
)
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
324 // We didn't find the character
325 cerr
<< "Error: unrecognized component filter: " << ch
<< endl
;
327 return true; // error
330 void Debug::clearFilter()
335 void Debug::allFilter()
340 void Debug::usageInstructions(void)
342 cerr
<< "Debug components: " << endl
;
343 for (int i
=0; i
<NUMBER_OF_COMPS
; i
++) {
344 cerr
<< " " << debugComponents
[i
].ch
<< ": " << debugComponents
[i
].desc
<< endl
;
348 void Debug::print(ostream
& out
) const
350 out
<< "[Debug]" << endl
;
353 void Debug::setDebugOutputFile (const char * filename
)
355 if ( (filename
== NULL
) ||
356 (!strcmp(filename
, "none")) ) {
357 debug_cout_ptr
= &cout
;
361 if (m_fout
.is_open() ) {
364 m_fout
.open (filename
, std::ios::out
);
365 if (! m_fout
.is_open() ) {
366 cerr
<< "setDebugOutputFile: can't open file " << filename
<< endl
;
369 debug_cout_ptr
= &m_fout
;
373 void Debug::closeDebugOutputFile ()
375 if (m_fout
.is_open() ) {
377 debug_cout_ptr
= &cout
;
381 void Debug::debugMsg( const char *fmt
, ... )
385 // you could check validDebug() here before printing the message
387 vfprintf(stdout
, fmt
, args
);
392 void DEBUG_OUT( const char* fmt, ...) {
394 cout << "Debug: in fn "
395 << __PRETTY_FUNCTION__
396 << " in " << __FILE__ << ":"
400 vfprintf(stdout, fmt, args);
405 void ERROR_OUT( const char* fmt, ... ) {
406 if (ERROR_MESSAGE_FLAG) {
407 cout << "error: in fn "
408 << __PRETTY_FUNCTION__ << " in "
413 vfprintf(stdout, fmt, args);