gem5 v24.0.0.0
Loading...
Searching...
No Matches
logging.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014, 2017, 2019 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
41#ifndef __BASE_LOGGING_HH__
42#define __BASE_LOGGING_HH__
43
44#include <cassert>
45#include <sstream>
46#include <utility>
47
48#include "base/compiler.hh"
49#include "base/cprintf.hh"
50
51namespace gem5
52{
53
54class Logger
55{
56 public:
57
61 static Logger &getPanic();
62 static Logger &getFatal();
63 static Logger &getWarn();
64 static Logger &getInfo();
65 static Logger &getHack();
66
72
73 static void
75 {
76 getPanic().enabled = (ll >= PANIC);
77 getFatal().enabled = (ll >= FATAL);
78 getWarn().enabled = (ll >= WARN);
79 getInfo().enabled = (ll >= INFO);
80 getHack().enabled = (ll >= HACK);
81 }
82
83 struct Loc
84 {
85 Loc(const char *file, int line) : file(file), line(line) {}
86 const char *file;
87 int line;
88 };
89
90 Logger(const char *prefix) : enabled(true), prefix(prefix)
91 {
92 assert(prefix);
93 }
94
95 virtual ~Logger() {};
96
97 template<typename ...Args> void
98 print(const Loc &loc, const char *format, const Args &...args)
99 {
100 std::stringstream ss;
101 ccprintf(ss, format, args...);
102 const std::string str = ss.str();
103
104 std::stringstream ss_formatted;
105 ss_formatted << prefix << str;
106 if (str.length() && str.back() != '\n' && str.back() != '\r')
107 ss_formatted << std::endl;
108 if (!enabled)
109 return;
110 log(loc, ss_formatted.str());
111 }
112
113 template<typename ...Args> void
114 print(const Loc &loc, const std::string &format, const Args &...args)
115 {
116 print(loc, format.c_str(), args...);
117 }
118
124 [[noreturn]] void exit_helper() { exit(); ::abort(); }
125
126 protected:
128
130 virtual void
131 log(const Loc &loc, std::string s)
132 {
133 std::cerr << loc.file << ":" << loc.line << ": " << s;
134 }
135
136 virtual void exit() { /* Fall through to the abort in exit_helper. */ }
137
138 const char *prefix;
139};
140
141#define base_message(logger, ...) \
142 [&log = logger](const auto&... args) { \
143 log.print(::gem5::Logger::Loc(__FILE__, __LINE__), args...); \
144 }(__VA_ARGS__)
145
146/*
147 * Only print the message the first time this expression is
148 * encountered. i.e. This doesn't check the string itself and
149 * prevent duplicate strings, this prevents the statement from
150 * happening more than once. So, even if the arguments change and that
151 * would have resulted in a different message thoes messages would be
152 * supressed.
153 */
154#define base_message_once(logger, ...) \
155 [&log = logger](const auto&... args) { \
156 static bool once{false}; \
157 if (GEM5_UNLIKELY(!once)) { \
158 once = true; \
159 base_message(log, args...); \
160 } \
161 }(__VA_ARGS__)
162
163/*
164 * logger.exit_helper() can't be called inside the lambda for now as the
165 * lambda's operator() can't be [[noreturn]]. As a result, exit_message and it'
166 * s derivative cannot be used in functions without also specifying a return
167 * value, which is inconvenient if not impossible.
168 */
169
170#define exit_message(logger, ...) \
171 ( \
172 [&log = logger](const auto&... args) { \
173 base_message(log, args...); \
174 }(__VA_ARGS__), \
175 logger.exit_helper() \
176 )
177
188#define panic(...) exit_message(::gem5::Logger::getPanic(), __VA_ARGS__)
189
200#define fatal(...) exit_message(::gem5::Logger::getFatal(), __VA_ARGS__)
201
214#define panic_if(cond, ...) \
215 ( \
216 GEM5_UNLIKELY(static_cast<bool>(cond)) ? \
217 panic("panic condition " # cond " occurred: %s", \
218 ::gem5::csprintf(__VA_ARGS__)) : \
219 void(0) \
220 )
221
222
236#define fatal_if(cond, ...) \
237 ( \
238 GEM5_UNLIKELY(static_cast<bool>(cond)) ? \
239 fatal("fatal condition " # cond " occurred: %s", \
240 ::gem5::csprintf(__VA_ARGS__)) : \
241 void(0) \
242 )
243
244
256#define warn(...) base_message(::gem5::Logger::getWarn(), __VA_ARGS__)
257#define inform(...) base_message(::gem5::Logger::getInfo(), __VA_ARGS__)
258#define hack(...) base_message(::gem5::Logger::getHack(), __VA_ARGS__)
259
260#define warn_once(...) \
261 base_message_once(::gem5::Logger::getWarn(), __VA_ARGS__)
262#define inform_once(...) \
263 base_message_once(::gem5::Logger::getInfo(), __VA_ARGS__)
264#define hack_once(...) \
265 base_message_once(::gem5::Logger::getHack(), __VA_ARGS__)
266 // end of api_logger
267
283#define warn_if(cond, ...) \
284 ( \
285 static_cast<bool>(cond) ? \
286 warn(__VA_ARGS__) : \
287 void(0) \
288 )
289
290#define warn_if_once(cond, ...) \
291 ( \
292 static_cast<bool>(cond) ? \
293 warn_once(__VA_ARGS__) : \
294 void(0) \
295 )
296
297 // end of api_logger
298
299#ifdef NDEBUG
300#define NDEBUG_DEFINED 1
301#else
302#define NDEBUG_DEFINED 0
303#endif
304
317#define gem5_assert(cond, ...) \
318 ( \
319 GEM5_UNLIKELY(NDEBUG_DEFINED || static_cast<bool>(cond)) ? \
320 void(0) : \
321 [](const auto&... args) { \
322 auto msg = [&]{ \
323 if constexpr (sizeof...(args) == 0) return ""; \
324 else return std::string(": ") + csprintf(args...); \
325 }; \
326 panic("assert(" #cond ") failed%s", msg()); \
327 }(__VA_ARGS__) \
328 )
329
330 // end of api_logger
331
332#define chatty_assert(...) \
333 ( \
334 gem5_assert(args...), \
335 GEM5_DEPRECATED_MACRO(chatty_assert, {}, "Please use gem5_assert()") \
336 )
337
338} // namespace gem5
339#endif // __BASE_LOGGING_HH__
virtual void exit()
Definition logging.hh:136
virtual ~Logger()
Definition logging.hh:95
virtual void log(const Loc &loc, std::string s)
Generates the log message.
Definition logging.hh:131
const char * prefix
Definition logging.hh:138
static Logger & getWarn()
Logger(const char *prefix)
Definition logging.hh:90
void print(const Loc &loc, const std::string &format, const Args &...args)
Definition logging.hh:114
static Logger & getInfo()
static Logger & getHack()
void print(const Loc &loc, const char *format, const Args &...args)
Definition logging.hh:98
static Logger & getPanic()
Get a Logger for the specified type of message.
void exit_helper()
This helper is necessary since noreturn isn't inherited by virtual functions, and gcc will get mad if...
Definition logging.hh:124
static Logger & getFatal()
static void setLevel(LogLevel ll)
Definition logging.hh:74
Bitfield< 4 > s
Bitfield< 31, 29 > format
Bitfield< 21 > ss
Definition misc_types.hh:60
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
void ccprintf(cp::Print &print)
Definition cprintf.hh:130
const char * file
Definition logging.hh:86
Loc(const char *file, int line)
Definition logging.hh:85

Generated on Tue Jun 18 2024 16:24:00 for gem5 by doxygen 1.11.0