diff options
author | Gabe Black <gabeblack@google.com> | 2018-07-25 19:30:30 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-09-11 21:48:32 +0000 |
commit | ea6b370fe79e043ed949033f9f3a4306b668aa94 (patch) | |
tree | 199b1796e5ea9a12d2464d8b62fb7c7848fd229b /src/systemc/utils | |
parent | 802efef3c40a028b0048bc4b8985dcc9bf64322f (diff) | |
download | gem5-ea6b370fe79e043ed949033f9f3a4306b668aa94.tar.xz |
systemc: Implement most of the sc_report_handler mechanism.
This doesn't include support for the deprecated integer message ids.
Change-Id: I309d58df1cdc464428189eb0b7180edf41ca4f67
Reviewed-on: https://gem5-review.googlesource.com/12048
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/utils')
-rw-r--r-- | src/systemc/utils/sc_report.cc | 97 | ||||
-rw-r--r-- | src/systemc/utils/sc_report_handler.cc | 348 |
2 files changed, 297 insertions, 148 deletions
diff --git a/src/systemc/utils/sc_report.cc b/src/systemc/utils/sc_report.cc index 6edbf2a05..838488021 100644 --- a/src/systemc/utils/sc_report.cc +++ b/src/systemc/utils/sc_report.cc @@ -29,85 +29,47 @@ #include "base/logging.hh" #include "systemc/ext/utils/sc_report.hh" +#include "systemc/ext/utils/sc_report_handler.hh" namespace sc_core { -sc_report::sc_report(const sc_report &) +sc_report::sc_report(sc_severity _severity, const char *_msgType, + const char *_msg, int _verbosity, const char *_fileName, + int _lineNumber, sc_time _time, const char *_processName, int _id) : + _severity(_severity), _msgType(_msgType), _msg(_msg), + _verbosity(_verbosity), _fileName(_fileName), _lineNumber(_lineNumber), + _time(_time), _processName(_processName), _id(_id) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _what = sc_report_compose_message(*this); } +sc_report::sc_report(const sc_report &r) : + sc_report(r._severity, r._msgType, r._msg, r._verbosity, r._fileName, + r._lineNumber, r._time, r._processName, r._id) +{} + sc_report & -sc_report::operator = (const sc_report &) -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); +sc_report::operator = (const sc_report &r) +{ + _severity = r._severity; + _msgType = r._msgType; + _msg = r._msg; + _verbosity = r._verbosity; + _fileName = r._fileName; + _lineNumber = r._lineNumber; + _time = r._time; + _processName = r._processName; + _id = r._id; return *this; } sc_report::~sc_report() throw() {} -sc_severity -sc_report::get_severity() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_FATAL; -} - -const char * -sc_report::get_msg_type() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return ""; -} - -const char * -sc_report::get_msg() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return ""; -} - -int -sc_report::get_verbosity() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_NONE; -} - -const char * -sc_report::get_file_name() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return ""; -} - -int -sc_report::get_line_number() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; -} - -const sc_time & -sc_report::get_time() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return *(const sc_time *)nullptr; -} - -const char * -sc_report::get_process_name() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return ""; -} - const char * sc_report::what() const throw() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return ""; + return _what.c_str(); } const char * @@ -154,17 +116,10 @@ sc_report::suppress_warnings(bool) warn("%s not implemented.\n", __PRETTY_FUNCTION__); } -int -sc_report::get_id() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; -} - void sc_abort() { - panic("%s not implemented.\n", __PRETTY_FUNCTION__); + panic("simulation aborted"); } } // namespace sc_core diff --git a/src/systemc/utils/sc_report_handler.cc b/src/systemc/utils/sc_report_handler.cc index 1a0e0d491..6b259342a 100644 --- a/src/systemc/utils/sc_report_handler.cc +++ b/src/systemc/utils/sc_report_handler.cc @@ -27,225 +27,419 @@ * Authors: Gabe Black */ +#include <fstream> +#include <map> +#include <sstream> +#include <string> + #include "base/logging.hh" +#include "systemc/core/process.hh" +#include "systemc/core/scheduler.hh" +#include "systemc/ext/core/sc_main.hh" #include "systemc/ext/utils/sc_report_handler.hh" namespace sc_core { +namespace +{ + +std::unique_ptr<std::string> logFileName; +std::unique_ptr<std::ofstream> logFile; + +struct ReportCatInfo +{ + explicit ReportCatInfo(sc_actions actions) : + actions(actions), count(0), limit(-1) + {} + ReportCatInfo() : ReportCatInfo(SC_UNSPECIFIED) {} + + bool + checkLimit(sc_actions &actions) + { + if (limit == 0 || count < limit) + return false; + if (limit != -1) + actions |= SC_STOP; + return true; + } + + sc_actions actions; + int count; + int limit; +}; + +const char *severityNames[] = { + [SC_INFO] = "Info", + [SC_WARNING] = "Warning", + [SC_ERROR] = "Error", + [SC_FATAL] = "Fatal" +}; + +ReportCatInfo catForSeverity[SC_MAX_SEVERITY] = +{ + [SC_INFO] = ReportCatInfo(SC_DEFAULT_INFO_ACTIONS), + [SC_WARNING] = ReportCatInfo(SC_DEFAULT_WARNING_ACTIONS), + [SC_ERROR] = ReportCatInfo(SC_DEFAULT_ERROR_ACTIONS), + [SC_FATAL] = ReportCatInfo(SC_DEFAULT_FATAL_ACTIONS) +}; + +std::map<std::string, ReportCatInfo> catForMsgType; +std::map<std::pair<std::string, sc_severity>, ReportCatInfo> + catForSeverityAndMsgType; + +int verbosityLevel = SC_MEDIUM; + +sc_actions suppressedActions = SC_UNSPECIFIED; +sc_actions forcedActions = SC_UNSPECIFIED; +sc_actions catchActions = SC_UNSPECIFIED; + +sc_report_handler_proc reportHandlerProc = &sc_report_handler::default_handler; + +sc_actions maxAction = SC_ABORT; + +std::unique_ptr<sc_report> globalReportCache; + +} // anonymous namespace + void -sc_report_handler::report(sc_severity, const char *msg_type, const char *msg, - const char *file, int line) +sc_report_handler::report(sc_severity severity, const char *msg_type, + const char *msg, const char *file, int line) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + report(severity, msg_type, msg, SC_MEDIUM, file, line); } void -sc_report_handler::report(sc_severity, const char *msg_type, const char *msg, - int verbosity, const char *file, int line) -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); +sc_report_handler::report(sc_severity severity, const char *msg_type, + const char *msg, int verbosity, const char *file, + int line) +{ + if (severity == SC_INFO && verbosity > verbosityLevel) + return; + + ReportCatInfo &sevInfo = catForSeverity[severity]; + ReportCatInfo &msgInfo = catForMsgType[msg_type]; + ReportCatInfo &sevMsgInfo = catForSeverityAndMsgType[ + std::make_pair(std::string(msg_type), severity)]; + + sevInfo.count++; + msgInfo.count++; + sevMsgInfo.count++; + + sc_actions actions = SC_UNSPECIFIED; + if (sevMsgInfo.actions != SC_UNSPECIFIED) + actions = sevMsgInfo.actions; + else if (msgInfo.actions != SC_UNSPECIFIED) + actions = msgInfo.actions; + else if (sevInfo.actions != SC_UNSPECIFIED) + actions = sevInfo.actions; + + actions &= ~suppressedActions; + actions |= forcedActions; + + if (sevMsgInfo.checkLimit(actions) && msgInfo.checkLimit(actions)) + sevInfo.checkLimit(actions); + + ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); + sc_report report(severity, msg_type, msg, verbosity, file, line, + sc_time::from_value(::sc_gem5::scheduler.getCurTick()), + current ? current->name() : nullptr, -1); + + if (actions & SC_CACHE_REPORT) { + if (current) { + current->lastReport(&report); + } else { + globalReportCache = + std::unique_ptr<sc_report>(new sc_report(report)); + } + } + + reportHandlerProc(report, actions); } void sc_report_handler::report(sc_severity, int id, const char *msg, const char *file, int line) { + warn("%s:%d %s\n", file, line, msg); warn("%s not implemented.\n", __PRETTY_FUNCTION__); } sc_actions -sc_report_handler::set_actions(sc_severity, sc_actions) +sc_report_handler::set_actions(sc_severity severity, sc_actions actions) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_UNSPECIFIED; + ReportCatInfo &info = catForSeverity[severity]; + sc_actions previous = info.actions; + info.actions = actions; + return previous; } sc_actions -sc_report_handler::set_actions(const char *msg_type, sc_actions) +sc_report_handler::set_actions(const char *msg_type, sc_actions actions) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_UNSPECIFIED; + ReportCatInfo &info = catForMsgType[msg_type]; + sc_actions previous = info.actions; + info.actions = actions; + return previous; } sc_actions -sc_report_handler::set_actions(const char *msg_type, sc_severity, sc_actions) -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_UNSPECIFIED; +sc_report_handler::set_actions( + const char *msg_type, sc_severity severity, sc_actions actions) +{ + ReportCatInfo &info = catForSeverityAndMsgType[ + std::make_pair(std::string(msg_type), severity)]; + sc_actions previous = info.actions; + info.actions = actions; + return previous; } int -sc_report_handler::stop_after(sc_severity, int limit) +sc_report_handler::stop_after(sc_severity severity, int limit) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; + ReportCatInfo &info = catForSeverity[severity]; + int previous = info.limit; + info.limit = limit; + return previous; } int sc_report_handler::stop_after(const char *msg_type, int limit) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; + ReportCatInfo &info = catForMsgType[msg_type]; + int previous = info.limit; + info.limit = limit; + return previous; } int -sc_report_handler::stop_after(const char *msg_type, sc_severity, sc_actions) -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; +sc_report_handler::stop_after( + const char *msg_type, sc_severity severity, int limit) +{ + ReportCatInfo &info = catForSeverityAndMsgType[ + std::make_pair(std::string(msg_type), severity)]; + int previous = info.limit; + info.limit = limit; + return previous; } int -sc_report_handler::get_count(sc_severity) +sc_report_handler::get_count(sc_severity severity) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; + return catForSeverity[severity].count; } int sc_report_handler::get_count(const char *msg_type) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; + return catForMsgType[msg_type].count; } int -sc_report_handler::get_count(const char *msg_type, sc_severity) +sc_report_handler::get_count(const char *msg_type, sc_severity severity) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; + return catForSeverityAndMsgType[ + std::make_pair(std::string(msg_type), severity)].count; } int -sc_report_handler::set_verbosity_level(int) +sc_report_handler::set_verbosity_level(int vl) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; + int previous = verbosityLevel; + verbosityLevel = vl; + return previous; } int sc_report_handler::get_verbosity_level() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; + return verbosityLevel; } sc_actions -sc_report_handler::suppress(sc_actions) +sc_report_handler::suppress(sc_actions actions) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_UNSPECIFIED; + sc_actions previous = suppressedActions; + suppressedActions = actions; + return previous; } sc_actions sc_report_handler::suppress() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_UNSPECIFIED; + return suppress(SC_UNSPECIFIED); } sc_actions -sc_report_handler::force(sc_actions) +sc_report_handler::force(sc_actions actions) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_UNSPECIFIED; + sc_actions previous = forcedActions; + forcedActions = actions; + return previous; } sc_actions sc_report_handler::force() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_UNSPECIFIED; + return force(SC_UNSPECIFIED); } sc_actions -sc_report_handler::set_catch_actions(sc_actions) +sc_report_handler::set_catch_actions(sc_actions actions) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_UNSPECIFIED; + sc_actions previous = catchActions; + catchActions = actions; + return previous; } sc_actions sc_report_handler::get_catch_actions() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_UNSPECIFIED; + return catchActions; } void -sc_report_handler::set_handler(sc_report_handler_proc) +sc_report_handler::set_handler(sc_report_handler_proc proc) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + reportHandlerProc = proc; } void -sc_report_handler::default_handler(const sc_report &, const sc_actions &) -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); +sc_report_handler::default_handler( + const sc_report &report, const sc_actions &actions) +{ + if (actions & SC_DISPLAY) + cprintf("\n%s\n", sc_report_compose_message(report)); + + if ((actions & SC_LOG) && logFile) { + ccprintf(*logFile, "%s: %s\n", report.get_time().to_string(), + sc_report_compose_message(report)); + } + if (actions & SC_STOP) { + sc_stop_here(report.get_msg_type(), report.get_severity()); + sc_stop(); + } + if (actions & SC_INTERRUPT) + sc_interrupt_here(report.get_msg_type(), report.get_severity()); + if (actions & SC_ABORT) + sc_abort(); + if (actions & SC_THROW) { + ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); + if (current) + current->isUnwinding(false); + throw report; + } } sc_actions sc_report_handler::get_new_action_id() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return SC_UNSPECIFIED; + maxAction = maxAction << 1; + return maxAction; } sc_report * sc_report_handler::get_cached_report() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return nullptr; + ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); + if (current) + return current->lastReport(); + return globalReportCache.get(); } void sc_report_handler::clear_cached_report() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); + if (current) { + current->lastReport(nullptr); + } else { + globalReportCache = nullptr; + } } bool -sc_report_handler::set_log_file_name(const char *) -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return false; +sc_report_handler::set_log_file_name(const char *new_name) +{ + if (!new_name) { + logFile = nullptr; + logFileName = nullptr; + return false; + } else { + if (logFileName) + return false; + logFileName = std::unique_ptr<std::string>(new std::string(new_name)); + logFile = std::unique_ptr<std::ofstream>(new std::ofstream(new_name)); + return true; + } } const char * sc_report_handler::get_log_file_name() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return nullptr; + if (!logFileName) + return nullptr; + else + return logFileName->c_str(); } void sc_interrupt_here(const char *msg_type, sc_severity) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + // Purposefully empty, for setting breakpoints supposedly. } void sc_stop_here(const char *msg_type, sc_severity) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + // Purposefully empty, for setting breakpoints supposedly. } const std::string -sc_report_compose_message(const sc_report &) +sc_report_compose_message(const sc_report &report) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return ""; + std::ostringstream str; + + const char *sevName = severityNames[report.get_severity()]; + int id = report.get_id(); + + str << sevName << ": "; + if (id >= 0) { + ccprintf(str, "(%c%d) ", sevName[0], id); + } + str << report.get_msg_type(); + + const char *msg = report.get_msg(); + if (msg[0]) + str << ": " << msg; + + if (report.get_severity() > SC_INFO) { + ccprintf(str, "\nIn file: %s:%d", report.get_file_name(), + report.get_line_number()); + + ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); + const char *name = report.get_process_name(); + if (current && sc_is_running() && name) { + ccprintf(str, "\nIn process: %s @ %s", name, + report.get_time().to_string()); + } + } + + return str.str(); } bool sc_report_close_default_log() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return false; + if (logFile) { + logFile = nullptr; + logFileName = nullptr; + return false; + } + return true; } } // namespace sc_core |