ruby: get rid of Vector and use STL
[gem5.git] / src / mem / ruby / common / Debug.hh
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 #ifndef __MEM_RUBY_COMMON_DEBUG_HH__
30 #define __MEM_RUBY_COMMON_DEBUG_HH__
31
32 #include <unistd.h>
33
34 #include <fstream>
35 #include <iostream>
36 #include <string>
37 #include <vector>
38
39 #include "config/ruby_debug.hh"
40 #include "mem/ruby/common/Global.hh"
41 #include "sim/sim_object.hh"
42
43 #include "params/RubyDebug.hh"
44
45 extern std::ostream * debug_cout_ptr;
46
47 // component enumeration
48 enum DebugComponents
49 {
50 SYSTEM_COMP,
51 NODE_COMP,
52 QUEUE_COMP,
53 EVENTQUEUE_COMP,
54 NETWORK_COMP,
55 SEQUENCER_COMP,
56 TESTER_COMP,
57 GENERATED_COMP,
58 SLICC_COMP,
59 NETWORKQUEUE_COMP,
60 TIME_COMP,
61 NETWORK_INTERNALS_COMP,
62 STOREBUFFER_COMP,
63 CACHE_COMP,
64 PREDICTOR_COMP,
65 MEMORY_COMP,
66 NUMBER_OF_COMPS
67 };
68
69 enum PriorityLevel {HighPrio, MedPrio, LowPrio};
70 enum VerbosityLevel {No_Verb, Low_Verb, Med_Verb, High_Verb};
71
72 class Debug : public SimObject
73 {
74 public:
75 typedef RubyDebugParams Params;
76 Debug(const Params *p);
77 ~Debug();
78
79 static bool getProtocolTrace() { return m_protocol_trace; }
80 bool validDebug(int module, PriorityLevel priority);
81 void printVerbosity(std::ostream& out) const;
82 void setVerbosity(VerbosityLevel vb);
83 bool setVerbosityString(const char *);
84 VerbosityLevel getVerbosity() const { return m_verbosityLevel; }
85 void setFilter(int);
86 static bool checkFilter( char);
87 static bool checkFilterString(const char *);
88 bool setFilterString(const char *);
89 void setDebugTime(Time);
90 Time getDebugTime() const { return m_starting_cycle; }
91 bool addFilter(char);
92 void clearFilter();
93 void allFilter();
94 void print(std::ostream& out) const;
95 /* old school debugging "vararg": sends messages to screen and log */
96 void debugMsg(const char *fmt, ...);
97
98 void setDebugOutputFile (const char * filename);
99 void closeDebugOutputFile ();
100 static void usageInstructions(void);
101
102 private:
103 // Private copy constructor and assignment operator
104 Debug(const Debug& obj);
105 Debug& operator=(const Debug& obj);
106
107 static bool m_protocol_trace;
108 VerbosityLevel m_verbosityLevel;
109 int m_filter;
110 Time m_starting_cycle;
111
112 std::fstream m_fout;
113 };
114
115 inline std::ostream&
116 operator<<(std::ostream& out, const Debug& obj)
117 {
118 obj.print(out);
119 out << std::flush;
120 return out;
121 }
122
123 const bool ERROR_MESSAGE_FLAG = true;
124 const bool WARNING_MESSAGE_FLAG = true;
125
126 #ifdef RUBY_NO_ASSERT
127 const bool ASSERT_FLAG = false;
128 #else
129 const bool ASSERT_FLAG = true;
130 #endif
131
132 #undef assert
133 #define assert(EXPR) ASSERT(EXPR)
134 #undef ASSERT
135 #define ASSERT(EXPR) do { \
136 using namespace std; \
137 if (ASSERT_FLAG) { \
138 if (!(EXPR)) { \
139 cerr << "failed assertion '" \
140 << #EXPR << "' at fn " \
141 << __PRETTY_FUNCTION__ << " in " \
142 << __FILE__ << ":" \
143 << __LINE__ << endl << flush; \
144 (*debug_cout_ptr) << "failed assertion '" \
145 << #EXPR << "' at fn " \
146 << __PRETTY_FUNCTION__ << " in " \
147 << __FILE__ << ":" \
148 << __LINE__ << endl << flush; \
149 if (isatty(STDIN_FILENO)) { \
150 cerr << "At this point you might want to attach a debug to " \
151 << "the running and get to the" << endl \
152 << "crash site; otherwise press enter to continue" \
153 << endl \
154 << "PID: " << getpid() \
155 << endl << flush; \
156 char c; \
157 cin.get(c); \
158 } \
159 abort(); \
160 } \
161 } \
162 } while (0)
163
164 #define BREAK(X) do { \
165 using namespace std; \
166 cerr << "breakpoint '" \
167 << #X << "' reached at fn " \
168 << __PRETTY_FUNCTION__ << " in " \
169 << __FILE__ << ":" \
170 << __LINE__ << endl << flush; \
171 if(isatty(STDIN_FILENO)) { \
172 cerr << "press enter to continue" << endl; \
173 cerr << "PID: " << getpid(); \
174 cerr << endl << flush; \
175 char c; \
176 cin.get(c); \
177 } \
178 } while (0)
179
180 #define ERROR_MSG(MESSAGE) do { \
181 using namespace std; \
182 if (ERROR_MESSAGE_FLAG) { \
183 cerr << "Fatal Error: in fn " \
184 << __PRETTY_FUNCTION__ << " in " \
185 << __FILE__ << ":" \
186 << __LINE__ << ": " \
187 << (MESSAGE) << endl << flush; \
188 (* debug_cout_ptr) << "Fatal Error: in fn " \
189 << __PRETTY_FUNCTION__ << " in " \
190 << __FILE__ << ":" \
191 << __LINE__ << ": " \
192 << (MESSAGE) << endl << flush; \
193 abort(); \
194 } \
195 } while(0)
196
197 #define WARN_MSG(MESSAGE) do { \
198 using namespace std; \
199 if (WARNING_MESSAGE_FLAG) { \
200 cerr << "Warning: in fn " \
201 << __PRETTY_FUNCTION__ << " in " \
202 << __FILE__ << ":" \
203 << __LINE__ << ": " \
204 << (MESSAGE) << endl << flush; \
205 (* debug_cout_ptr) << "Warning: in fn " \
206 << __PRETTY_FUNCTION__ << " in " \
207 << __FILE__ << ":" \
208 << __LINE__ << ": " \
209 << (MESSAGE) << endl << flush; \
210 } \
211 } while (0)
212
213 #define WARN_EXPR(EXPR) do { \
214 using namespace std; \
215 if (WARNING_MESSAGE_FLAG) { \
216 cerr << "Warning: in fn " \
217 << __PRETTY_FUNCTION__ << " in " \
218 << __FILE__ << ":" \
219 << __LINE__ << ": " \
220 << #EXPR << " is " \
221 << (EXPR) << endl << flush; \
222 (* debug_cout_ptr) << "Warning: in fn " \
223 << __PRETTY_FUNCTION__ << " in " \
224 << __FILE__ << ":" \
225 << __LINE__ << ": " \
226 << #EXPR << " is " \
227 << (EXPR) << endl << flush; \
228 } \
229 } while (0)
230
231 #define DEBUG_MSG(module, priority, MESSAGE) do { \
232 using namespace std; \
233 if (RUBY_DEBUG) { \
234 if (g_debug_ptr->validDebug(module, priority)) { \
235 (* debug_cout_ptr) << "Debug: in fn " \
236 << __PRETTY_FUNCTION__ \
237 << " in " << __FILE__ << ":" \
238 << __LINE__ << ": " \
239 << (MESSAGE) << endl << flush; \
240 } \
241 } \
242 } while (0)
243
244 #define DEBUG_EXPR(module, priority, EXPR) do { \
245 using namespace std; \
246 if (RUBY_DEBUG) { \
247 if (g_debug_ptr->validDebug(module, priority)) { \
248 (* debug_cout_ptr) << "Debug: in fn " \
249 << __PRETTY_FUNCTION__ \
250 << " in " << __FILE__ << ":" \
251 << __LINE__ << ": " \
252 << #EXPR << " is " \
253 << (EXPR) << endl << flush; \
254 } \
255 } \
256 } while (0)
257
258 #define DEBUG_NEWLINE(module, priority) do { \
259 using namespace std; \
260 if (RUBY_DEBUG) { \
261 if (g_debug_ptr->validDebug(module, priority)) { \
262 (* debug_cout_ptr) << endl << flush; \
263 } \
264 } \
265 } while (0)
266
267 #define DEBUG_SLICC(priority, LINE, MESSAGE) do { \
268 using namespace std; \
269 if (RUBY_DEBUG) { \
270 if (g_debug_ptr->validDebug(SLICC_COMP, priority)) { \
271 (* debug_cout_ptr) << (LINE) << (MESSAGE) << endl << flush; \
272 } \
273 } \
274 } while (0)
275
276 #define DEBUG_OUT(rest... ) do { \
277 using namespace std; \
278 if (RUBY_DEBUG) { \
279 cout << "Debug: in fn " \
280 << __PRETTY_FUNCTION__ \
281 << " in " << __FILE__ << ":" \
282 << __LINE__ << ": "; \
283 g_debug_ptr->debugMsg(rest); \
284 } \
285 } while (0)
286
287 #define ERROR_OUT( rest... ) do { \
288 using namespace std; \
289 if (ERROR_MESSAGE_FLAG) { \
290 cout << "error: in fn " \
291 << __PRETTY_FUNCTION__ << " in " \
292 << __FILE__ << ":" \
293 << __LINE__ << ": "; \
294 g_debug_ptr->debugMsg(rest); \
295 } \
296 } while (0)
297
298 #endif // __MEM_RUBY_COMMON_DEBUG_HH__
299