cpu: Fix retries on barrier/store in Minor's store buffer
[gem5.git] / src / base / misc.hh
1 /*
2 * Copyright (c) 2014 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Nathan Binkert
41 * Dave Greene
42 * Andreas Sandberg
43 */
44
45 #ifndef __BASE_MISC_HH__
46 #define __BASE_MISC_HH__
47
48 #include <cassert>
49 #include <iostream>
50
51 #include "base/compiler.hh"
52 #include "base/cprintf.hh"
53
54 #if defined(__SUNPRO_CC)
55 #define __FUNCTION__ "how to fix me?"
56 #endif
57
58 void __exit_epilogue(int code,
59 const char *func, const char *file, int line,
60 const char *format) M5_ATTR_NORETURN;
61
62 // General exit message, these functions will never return and will
63 // either abort() if code is < 0 or exit with the code if >= 0
64 template<typename ...Args> void
65 __exit_message(const char *prefix, int code,
66 const char *func, const char *file, int line,
67 const char *format, const Args &...args) M5_ATTR_NORETURN;
68 template<typename ...Args> void
69 __exit_message(const char *prefix, int code,
70 const char *func, const char *file, int line,
71 const std::string &format, const Args &...args) M5_ATTR_NORETURN;
72
73 template<typename ...Args> void
74 __exit_message(const char *prefix, int code,
75 const char *func, const char *file, int line,
76 const char *format, const Args &...args)
77 {
78 std::cerr << prefix << ": ";
79 ccprintf(std::cerr, format, args...);
80
81 __exit_epilogue(code, func, file, line, format);
82 }
83
84 template<typename ...Args> void
85 __exit_message(const char *prefix, int code,
86 const char *func, const char *file, int line,
87 const std::string &format, const Args &...args)
88 {
89 __exit_message(prefix, code, func, file, line, format.c_str(),
90 args...);
91 }
92
93 #define exit_message(prefix, code, ...) \
94 __exit_message(prefix, code, __FUNCTION__, __FILE__, __LINE__, \
95 __VA_ARGS__)
96
97 //
98 // This implements a cprintf based panic() function. panic() should
99 // be called when something happens that should never ever happen
100 // regardless of what the user does (i.e., an acutal m5 bug). panic()
101 // calls abort which can dump core or enter the debugger.
102 //
103 //
104 #define panic(...) exit_message("panic", -1, __VA_ARGS__)
105
106 //
107 // This implements a cprintf based fatal() function. fatal() should
108 // be called when the simulation cannot continue due to some condition
109 // that is the user's fault (bad configuration, invalid arguments,
110 // etc.) and not a simulator bug. fatal() calls abort() like
111 // panic() does.
112 //
113 #define fatal(...) exit_message("fatal", -1, __VA_ARGS__)
114
115 /**
116 * Conditional panic macro that checks the supplied condition and only panics
117 * if the condition is true and allows the programmer to specify diagnostic
118 * printout. Useful to replace if + panic, or if + print + assert, etc.
119 *
120 * @param cond Condition that is checked; if true -> panic
121 * @param ... Printf-based format string with arguments, extends printout.
122 */
123 #define panic_if(cond, ...) \
124 do { \
125 if ((cond)) \
126 exit_message("panic condition "#cond" occurred", -1, __VA_ARGS__); \
127 } while (0)
128
129
130 /**
131 * Conditional fatal macro that checks the supplied condition and only causes a
132 * fatal error if the condition is true and allows the programmer to specify
133 * diagnostic printout. Useful to replace if + fatal, or if + print + assert,
134 * etc.
135 *
136 * @param cond Condition that is checked; if true -> fatal
137 * @param ... Printf-based format string with arguments, extends printout.
138 */
139 #define fatal_if(cond, ...) \
140 do { \
141 if ((cond)) \
142 exit_message("fatal condition "#cond" occurred", 1, __VA_ARGS__); \
143 } while (0)
144
145
146 void
147 __base_message_epilogue(std::ostream &stream, bool verbose,
148 const char *func, const char *file, int line,
149 const char *format);
150
151 template<typename ...Args> void
152 __base_message(std::ostream &stream, const char *prefix, bool verbose,
153 const char *func, const char *file, int line,
154 const char *format, const Args &...args)
155 {
156 stream << prefix << ": ";
157 ccprintf(stream, format, args...);
158
159 __base_message_epilogue(stream, verbose, func, file, line, format);
160 }
161
162 template<typename ...Args> void
163 __base_message(std::ostream &stream, const char *prefix, bool verbose,
164 const char *func, const char *file, int line,
165 const std::string &format, const Args &...args)
166 {
167 __base_message(stream, prefix, verbose, func, file, line, format.c_str(),
168 args...);
169 }
170
171 #define base_message(stream, prefix, verbose, ...) \
172 __base_message(stream, prefix, verbose, __FUNCTION__, __FILE__, __LINE__, \
173 __VA_ARGS__)
174
175 // Only print the message the first time this expression is
176 // encountered. i.e. This doesn't check the string itself and
177 // prevent duplicate strings, this prevents the statement from
178 // happening more than once. So, even if the arguments change and that
179 // would have resulted in a different message thoes messages would be
180 // supressed.
181 #define base_message_once(...) do { \
182 static bool once = false; \
183 if (!once) { \
184 base_message(__VA_ARGS__); \
185 once = true; \
186 } \
187 } while (0)
188
189 #define cond_message(cond, ...) do { \
190 if (cond) \
191 base_message(__VA_ARGS__); \
192 } while (0)
193
194 #define cond_message_once(cond, ...) do { \
195 static bool once = false; \
196 if (!once && cond) { \
197 base_message(__VA_ARGS__); \
198 once = true; \
199 } \
200 } while (0)
201
202
203 extern bool want_warn, warn_verbose;
204 extern bool want_info, info_verbose;
205 extern bool want_hack, hack_verbose;
206
207 #define warn(...) \
208 cond_message(want_warn, std::cerr, "warn", warn_verbose, __VA_ARGS__)
209 #define inform(...) \
210 cond_message(want_info, std::cout, "info", info_verbose, __VA_ARGS__)
211 #define hack(...) \
212 cond_message(want_hack, std::cerr, "hack", hack_verbose, __VA_ARGS__)
213
214 #define warn_once(...) \
215 cond_message_once(want_warn, std::cerr, "warn", warn_verbose, __VA_ARGS__)
216 #define inform_once(...) \
217 cond_message_once(want_info, std::cout, "info", info_verbose, __VA_ARGS__)
218 #define hack_once(...) \
219 cond_message_once(want_hack, std::cerr, "hack", hack_verbose, __VA_ARGS__)
220
221 /**
222 * The chatty assert macro will function like a normal assert, but will allow the
223 * specification of additional, helpful material to aid debugging why the
224 * assertion actually failed. Like the normal assertion, the chatty_assert
225 * will not be active in fast builds.
226 *
227 * @param cond Condition that is checked; if false -> assert
228 * @param ... Printf-based format string with arguments, extends printout.
229 */
230 #ifdef NDEBUG
231 #define chatty_assert(cond, ...)
232 #else //!NDEBUG
233 #define chatty_assert(cond, ...) \
234 do { \
235 if (!(cond)) { \
236 base_message(std::cerr, "assert("#cond") failing", 1, __VA_ARGS__); \
237 assert(cond); \
238 } \
239 } while (0)
240 #endif // NDEBUG
241 #endif // __BASE_MISC_HH__