X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbase%2Fmisc.hh;h=25dcbaa6268280df65ab8e794fc43216e5afcd83;hb=eae1e97fb002b44a9d8c46df2da1ddc1d0156ce4;hp=1c5720ce198cc781a37dd5c80e804021d66f078c;hpb=0a99750ebfe9a9b400ee5f0610ed429851345c4b;p=gem5.git diff --git a/src/base/misc.hh b/src/base/misc.hh index 1c5720ce1..25dcbaa62 100644 --- a/src/base/misc.hh +++ b/src/base/misc.hh @@ -29,11 +29,40 @@ * Dave Greene */ -#ifndef __MISC_HH__ -#define __MISC_HH__ +#ifndef __BASE_MISC_HH__ +#define __BASE_MISC_HH__ -#include +#include "base/compiler.hh" #include "base/cprintf.hh" +#include "base/varargs.hh" + +#if defined(__SUNPRO_CC) +#define __FUNCTION__ "how to fix me?" +#endif + +// General exit message, these functions will never return and will +// either abort() if code is < 0 or exit with the code if >= 0 +void __exit_message(const char *prefix, int code, + const char *func, const char *file, int line, + const char *format, CPRINTF_DECLARATION) M5_ATTR_NORETURN; + +void __exit_message(const char *prefix, int code, + const char *func, const char *file, int line, + const std::string &format, CPRINTF_DECLARATION) M5_ATTR_NORETURN; + +inline void +__exit_message(const char *prefix, int code, + const char *func, const char *file, int line, + const std::string& format, CPRINTF_DEFINITION) +{ + __exit_message(prefix, code, func, file, line, format.c_str(), + VARARGS_ALLARGS); +} + +M5_PRAGMA_NORETURN(__exit_message) +#define exit_message(prefix, code, ...) \ + __exit_message(prefix, code, __FUNCTION__, __FILE__, __LINE__, \ + __VA_ARGS__) // // This implements a cprintf based panic() function. panic() should @@ -42,13 +71,7 @@ // calls abort which can dump core or enter the debugger. // // -void __panic(const std::string&, cp::ArgList &, const char*, const char*, int) - __attribute__((noreturn)); -#define __panic__(format, args...) \ - __panic(format, (*(new cp::ArgList), args), \ - __FUNCTION__, __FILE__, __LINE__) -#define panic(args...) \ - __panic__(args, cp::ArgListNull()) +#define panic(...) exit_message("panic", -1, __VA_ARGS__) // // This implements a cprintf based fatal() function. fatal() should @@ -58,44 +81,70 @@ void __panic(const std::string&, cp::ArgList &, const char*, const char*, int) // "normal" exit with an error code, as opposed to abort() like // panic() does. // -void __fatal(const std::string&, cp::ArgList &, const char*, const char*, int) - __attribute__((noreturn)); -#define __fatal__(format, args...) \ - __fatal(format, (*(new cp::ArgList), args), \ - __FUNCTION__, __FILE__, __LINE__) -#define fatal(args...) \ - __fatal__(args, cp::ArgListNull()) +#define fatal(...) exit_message("fatal", 1, __VA_ARGS__) -// -// This implements a cprintf based warn -// -void __warn(const std::string&, cp::ArgList &, const char*, const char*, int); -#define __warn__(format, args...) \ - __warn(format, (*(new cp::ArgList), args), \ - __FUNCTION__, __FILE__, __LINE__) -#define warn(args...) \ - __warn__(args, cp::ArgListNull()) - -// Only print the warning message the first time it is seen. This -// doesn't check the warning string itself, it just only lets one -// warning come from the statement. So, even if the arguments change -// and that would have resulted in a different warning message, -// subsequent messages would still be supressed. -#define warn_once(args...) do { \ - static bool once = false; \ - if (!once) { \ - __warn__(args, cp::ArgListNull()); \ - once = true; \ - } \ +void +__base_message(std::ostream &stream, const char *prefix, bool verbose, + const char *func, const char *file, int line, + const char *format, CPRINTF_DECLARATION); + +inline void +__base_message(std::ostream &stream, const char *prefix, bool verbose, + const char *func, const char *file, int line, + const std::string &format, CPRINTF_DECLARATION) +{ + __base_message(stream, prefix, verbose, func, file, line, format.c_str(), + VARARGS_ALLARGS); +} + +#define base_message(stream, prefix, verbose, ...) \ + __base_message(stream, prefix, verbose, __FUNCTION__, __FILE__, __LINE__, \ + __VA_ARGS__) + +// Only print the message the first time this expression is +// encountered. i.e. This doesn't check the string itself and +// prevent duplicate strings, this prevents the statement from +// happening more than once. So, even if the arguments change and that +// would have resulted in a different message thoes messages would be +// supressed. +#define base_message_once(...) do { \ + static bool once = false; \ + if (!once) { \ + base_message(__VA_ARGS__); \ + once = true; \ + } \ } while (0) -// -// assert() that prints out the current cycle -// -#define m5_assert(TEST) \ - if (!(TEST)) { \ - std::cerr << "Assertion failure, curTick = " << curTick << std::endl; \ - } \ - assert(TEST); +#define cond_message(cond, ...) do { \ + if (cond) \ + base_message(__VA_ARGS__); \ + } while (0) + +#define cond_message_once(cond, ...) do { \ + static bool once = false; \ + if (!once && cond) { \ + base_message(__VA_ARGS__); \ + once = true; \ + } \ + } while (0) + + +extern bool want_warn, warn_verbose; +extern bool want_info, info_verbose; +extern bool want_hack, hack_verbose; + +#define warn(...) \ + cond_message(want_warn, std::cerr, "warn", warn_verbose, __VA_ARGS__) +#define inform(...) \ + cond_message(want_info, std::cout, "info", info_verbose, __VA_ARGS__) +#define hack(...) \ + cond_message(want_hack, std::cerr, "hack", hack_verbose, __VA_ARGS__) + +#define warn_once(...) \ + cond_message_once(want_warn, std::cerr, "warn", warn_verbose, __VA_ARGS__) +#define inform_once(...) \ + cond_message_once(want_info, std::cout, "info", info_verbose, __VA_ARGS__) +#define hack_once(...) \ + cond_message_once(want_hack, std::cerr, "hack", hack_verbose, __VA_ARGS__) -#endif // __MISC_HH__ +#endif // __BASE_MISC_HH__