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