sc_report_handler.cc revision 13313
112852Sgabeblack@google.com/* 212852Sgabeblack@google.com * Copyright 2018 Google, Inc. 312852Sgabeblack@google.com * 412852Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 512852Sgabeblack@google.com * modification, are permitted provided that the following conditions are 612852Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 712852Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 812852Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 912852Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1012852Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1112852Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1212852Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1312852Sgabeblack@google.com * this software without specific prior written permission. 1412852Sgabeblack@google.com * 1512852Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1612852Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1712852Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1812852Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1912852Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2012852Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2112852Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2212852Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2312852Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2412852Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2512852Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2612852Sgabeblack@google.com * 2712852Sgabeblack@google.com * Authors: Gabe Black 2812852Sgabeblack@google.com */ 2912852Sgabeblack@google.com 3012997Sgabeblack@google.com#include <fstream> 3112997Sgabeblack@google.com#include <map> 3212997Sgabeblack@google.com#include <sstream> 3312997Sgabeblack@google.com#include <string> 3412997Sgabeblack@google.com 3512852Sgabeblack@google.com#include "base/logging.hh" 3612997Sgabeblack@google.com#include "systemc/core/process.hh" 3712997Sgabeblack@google.com#include "systemc/core/scheduler.hh" 3812997Sgabeblack@google.com#include "systemc/ext/core/sc_main.hh" 3912852Sgabeblack@google.com#include "systemc/ext/utils/sc_report_handler.hh" 4013312Sgabeblack@google.com#include "systemc/utils/report.hh" 4112852Sgabeblack@google.com 4212852Sgabeblack@google.comnamespace sc_core 4312852Sgabeblack@google.com{ 4412852Sgabeblack@google.com 4512997Sgabeblack@google.comnamespace 4612997Sgabeblack@google.com{ 4712997Sgabeblack@google.com 4812997Sgabeblack@google.comstd::unique_ptr<std::string> logFileName; 4912997Sgabeblack@google.comstd::unique_ptr<std::ofstream> logFile; 5012997Sgabeblack@google.com 5112997Sgabeblack@google.com} // anonymous namespace 5212997Sgabeblack@google.com 5312852Sgabeblack@google.comvoid 5412997Sgabeblack@google.comsc_report_handler::report(sc_severity severity, const char *msg_type, 5512997Sgabeblack@google.com const char *msg, const char *file, int line) 5612852Sgabeblack@google.com{ 5712997Sgabeblack@google.com report(severity, msg_type, msg, SC_MEDIUM, file, line); 5812852Sgabeblack@google.com} 5912852Sgabeblack@google.com 6012852Sgabeblack@google.comvoid 6112997Sgabeblack@google.comsc_report_handler::report(sc_severity severity, const char *msg_type, 6212997Sgabeblack@google.com const char *msg, int verbosity, const char *file, 6312997Sgabeblack@google.com int line) 6412852Sgabeblack@google.com{ 6513312Sgabeblack@google.com if (severity == SC_INFO && verbosity > sc_gem5::reportVerbosityLevel) 6612997Sgabeblack@google.com return; 6712997Sgabeblack@google.com 6813312Sgabeblack@google.com sc_gem5::ReportSevInfo &sevInfo = sc_gem5::reportSevInfos[severity]; 6913312Sgabeblack@google.com sc_gem5::ReportMsgInfo &msgInfo = sc_gem5::reportMsgInfoMap[msg_type]; 7012997Sgabeblack@google.com 7112997Sgabeblack@google.com sevInfo.count++; 7212997Sgabeblack@google.com msgInfo.count++; 7313312Sgabeblack@google.com msgInfo.sevCounts[severity]++; 7412997Sgabeblack@google.com 7512997Sgabeblack@google.com sc_actions actions = SC_UNSPECIFIED; 7613312Sgabeblack@google.com if (msgInfo.sevActions[severity] != SC_UNSPECIFIED) 7713312Sgabeblack@google.com actions = msgInfo.sevActions[severity]; 7812997Sgabeblack@google.com else if (msgInfo.actions != SC_UNSPECIFIED) 7912997Sgabeblack@google.com actions = msgInfo.actions; 8012997Sgabeblack@google.com else if (sevInfo.actions != SC_UNSPECIFIED) 8112997Sgabeblack@google.com actions = sevInfo.actions; 8212997Sgabeblack@google.com 8313312Sgabeblack@google.com actions &= ~sc_gem5::reportSuppressedActions; 8413312Sgabeblack@google.com actions |= sc_gem5::reportForcedActions; 8512997Sgabeblack@google.com 8613312Sgabeblack@google.com msgInfo.checkLimits(severity, actions); 8713312Sgabeblack@google.com sevInfo.checkLimit(actions); 8812997Sgabeblack@google.com 8912997Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 9012997Sgabeblack@google.com sc_report report(severity, msg_type, msg, verbosity, file, line, 9112997Sgabeblack@google.com sc_time::from_value(::sc_gem5::scheduler.getCurTick()), 9213313Sgabeblack@google.com current ? current->name() : nullptr, msgInfo.id); 9312997Sgabeblack@google.com 9412997Sgabeblack@google.com if (actions & SC_CACHE_REPORT) { 9512997Sgabeblack@google.com if (current) { 9612997Sgabeblack@google.com current->lastReport(&report); 9712997Sgabeblack@google.com } else { 9813312Sgabeblack@google.com sc_gem5::globalReportCache = 9912997Sgabeblack@google.com std::unique_ptr<sc_report>(new sc_report(report)); 10012997Sgabeblack@google.com } 10112997Sgabeblack@google.com } 10212997Sgabeblack@google.com 10313312Sgabeblack@google.com sc_gem5::reportHandlerProc(report, actions); 10412852Sgabeblack@google.com} 10512852Sgabeblack@google.com 10612902Sgabeblack@google.comvoid 10713313Sgabeblack@google.comsc_report_handler::report(sc_severity severity, int id, const char *msg, 10812902Sgabeblack@google.com const char *file, int line) 10912902Sgabeblack@google.com{ 11013313Sgabeblack@google.com std::string &msg_type = sc_gem5::reportIdToMsgMap[id]; 11113313Sgabeblack@google.com if (msg_type == "") 11213313Sgabeblack@google.com msg_type = "unknown id"; 11313313Sgabeblack@google.com 11413313Sgabeblack@google.com if (sc_gem5::reportWarningsAsErrors && severity == SC_WARNING) 11513313Sgabeblack@google.com severity = SC_ERROR; 11613313Sgabeblack@google.com 11713313Sgabeblack@google.com report(severity, msg_type.c_str(), msg, file, line); 11812902Sgabeblack@google.com} 11912902Sgabeblack@google.com 12012852Sgabeblack@google.comsc_actions 12112997Sgabeblack@google.comsc_report_handler::set_actions(sc_severity severity, sc_actions actions) 12212852Sgabeblack@google.com{ 12313312Sgabeblack@google.com sc_gem5::ReportSevInfo &info = sc_gem5::reportSevInfos[severity]; 12412997Sgabeblack@google.com sc_actions previous = info.actions; 12512997Sgabeblack@google.com info.actions = actions; 12612997Sgabeblack@google.com return previous; 12712852Sgabeblack@google.com} 12812852Sgabeblack@google.com 12912852Sgabeblack@google.comsc_actions 13012997Sgabeblack@google.comsc_report_handler::set_actions(const char *msg_type, sc_actions actions) 13112852Sgabeblack@google.com{ 13213312Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type]; 13312997Sgabeblack@google.com sc_actions previous = info.actions; 13412997Sgabeblack@google.com info.actions = actions; 13512997Sgabeblack@google.com return previous; 13612852Sgabeblack@google.com} 13712852Sgabeblack@google.com 13812852Sgabeblack@google.comsc_actions 13912997Sgabeblack@google.comsc_report_handler::set_actions( 14012997Sgabeblack@google.com const char *msg_type, sc_severity severity, sc_actions actions) 14112852Sgabeblack@google.com{ 14213312Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type]; 14313312Sgabeblack@google.com sc_actions previous = info.sevActions[severity]; 14413312Sgabeblack@google.com info.sevActions[severity] = actions; 14512997Sgabeblack@google.com return previous; 14612852Sgabeblack@google.com} 14712852Sgabeblack@google.com 14812852Sgabeblack@google.comint 14912997Sgabeblack@google.comsc_report_handler::stop_after(sc_severity severity, int limit) 15012852Sgabeblack@google.com{ 15113312Sgabeblack@google.com sc_gem5::ReportSevInfo &info = sc_gem5::reportSevInfos[severity]; 15212997Sgabeblack@google.com int previous = info.limit; 15312997Sgabeblack@google.com info.limit = limit; 15412997Sgabeblack@google.com return previous; 15512852Sgabeblack@google.com} 15612852Sgabeblack@google.com 15712852Sgabeblack@google.comint 15812852Sgabeblack@google.comsc_report_handler::stop_after(const char *msg_type, int limit) 15912852Sgabeblack@google.com{ 16013312Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type]; 16112997Sgabeblack@google.com int previous = info.limit; 16212997Sgabeblack@google.com info.limit = limit; 16312997Sgabeblack@google.com return previous; 16412852Sgabeblack@google.com} 16512852Sgabeblack@google.com 16612852Sgabeblack@google.comint 16712997Sgabeblack@google.comsc_report_handler::stop_after( 16812997Sgabeblack@google.com const char *msg_type, sc_severity severity, int limit) 16912852Sgabeblack@google.com{ 17013312Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type]; 17113312Sgabeblack@google.com int previous = info.sevLimits[severity]; 17213312Sgabeblack@google.com info.sevLimits[severity] = limit; 17312997Sgabeblack@google.com return previous; 17412852Sgabeblack@google.com} 17512852Sgabeblack@google.com 17612852Sgabeblack@google.comint 17712997Sgabeblack@google.comsc_report_handler::get_count(sc_severity severity) 17812852Sgabeblack@google.com{ 17913312Sgabeblack@google.com return sc_gem5::reportSevInfos[severity].count; 18012852Sgabeblack@google.com} 18112852Sgabeblack@google.com 18212852Sgabeblack@google.comint 18312852Sgabeblack@google.comsc_report_handler::get_count(const char *msg_type) 18412852Sgabeblack@google.com{ 18513312Sgabeblack@google.com return sc_gem5::reportMsgInfoMap[msg_type].count; 18612852Sgabeblack@google.com} 18712852Sgabeblack@google.com 18812852Sgabeblack@google.comint 18912997Sgabeblack@google.comsc_report_handler::get_count(const char *msg_type, sc_severity severity) 19012852Sgabeblack@google.com{ 19113312Sgabeblack@google.com return sc_gem5::reportMsgInfoMap[msg_type].sevCounts[severity]; 19212852Sgabeblack@google.com} 19312852Sgabeblack@google.com 19412852Sgabeblack@google.comint 19512997Sgabeblack@google.comsc_report_handler::set_verbosity_level(int vl) 19612852Sgabeblack@google.com{ 19713312Sgabeblack@google.com int previous = sc_gem5::reportVerbosityLevel; 19813312Sgabeblack@google.com sc_gem5::reportVerbosityLevel = vl; 19912997Sgabeblack@google.com return previous; 20012852Sgabeblack@google.com} 20112852Sgabeblack@google.com 20212852Sgabeblack@google.comint 20312852Sgabeblack@google.comsc_report_handler::get_verbosity_level() 20412852Sgabeblack@google.com{ 20513312Sgabeblack@google.com return sc_gem5::reportVerbosityLevel; 20612852Sgabeblack@google.com} 20712852Sgabeblack@google.com 20812852Sgabeblack@google.com 20912852Sgabeblack@google.comsc_actions 21012997Sgabeblack@google.comsc_report_handler::suppress(sc_actions actions) 21112852Sgabeblack@google.com{ 21213312Sgabeblack@google.com sc_actions previous = sc_gem5::reportSuppressedActions; 21313312Sgabeblack@google.com sc_gem5::reportSuppressedActions = actions; 21412997Sgabeblack@google.com return previous; 21512852Sgabeblack@google.com} 21612852Sgabeblack@google.com 21712852Sgabeblack@google.comsc_actions 21812852Sgabeblack@google.comsc_report_handler::suppress() 21912852Sgabeblack@google.com{ 22012997Sgabeblack@google.com return suppress(SC_UNSPECIFIED); 22112852Sgabeblack@google.com} 22212852Sgabeblack@google.com 22312852Sgabeblack@google.comsc_actions 22412997Sgabeblack@google.comsc_report_handler::force(sc_actions actions) 22512852Sgabeblack@google.com{ 22613312Sgabeblack@google.com sc_actions previous = sc_gem5::reportForcedActions; 22713312Sgabeblack@google.com sc_gem5::reportForcedActions = actions; 22812997Sgabeblack@google.com return previous; 22912852Sgabeblack@google.com} 23012852Sgabeblack@google.com 23112852Sgabeblack@google.comsc_actions 23212852Sgabeblack@google.comsc_report_handler::force() 23312852Sgabeblack@google.com{ 23412997Sgabeblack@google.com return force(SC_UNSPECIFIED); 23512852Sgabeblack@google.com} 23612852Sgabeblack@google.com 23712852Sgabeblack@google.com 23812911Sgabeblack@google.comsc_actions 23912997Sgabeblack@google.comsc_report_handler::set_catch_actions(sc_actions actions) 24012911Sgabeblack@google.com{ 24113312Sgabeblack@google.com sc_actions previous = sc_gem5::reportCatchActions; 24213312Sgabeblack@google.com sc_gem5::reportCatchActions = actions; 24312997Sgabeblack@google.com return previous; 24412911Sgabeblack@google.com} 24512911Sgabeblack@google.com 24612911Sgabeblack@google.comsc_actions 24712911Sgabeblack@google.comsc_report_handler::get_catch_actions() 24812911Sgabeblack@google.com{ 24913312Sgabeblack@google.com return sc_gem5::reportCatchActions; 25012911Sgabeblack@google.com} 25112911Sgabeblack@google.com 25212911Sgabeblack@google.com 25312852Sgabeblack@google.comvoid 25412997Sgabeblack@google.comsc_report_handler::set_handler(sc_report_handler_proc proc) 25512852Sgabeblack@google.com{ 25613312Sgabeblack@google.com sc_gem5::reportHandlerProc = proc; 25712852Sgabeblack@google.com} 25812852Sgabeblack@google.com 25912852Sgabeblack@google.comvoid 26012997Sgabeblack@google.comsc_report_handler::default_handler( 26112997Sgabeblack@google.com const sc_report &report, const sc_actions &actions) 26212852Sgabeblack@google.com{ 26312997Sgabeblack@google.com if (actions & SC_DISPLAY) 26412997Sgabeblack@google.com cprintf("\n%s\n", sc_report_compose_message(report)); 26512997Sgabeblack@google.com 26612997Sgabeblack@google.com if ((actions & SC_LOG) && logFile) { 26712997Sgabeblack@google.com ccprintf(*logFile, "%s: %s\n", report.get_time().to_string(), 26812997Sgabeblack@google.com sc_report_compose_message(report)); 26912997Sgabeblack@google.com } 27012997Sgabeblack@google.com if (actions & SC_STOP) { 27112997Sgabeblack@google.com sc_stop_here(report.get_msg_type(), report.get_severity()); 27212997Sgabeblack@google.com sc_stop(); 27312997Sgabeblack@google.com } 27412997Sgabeblack@google.com if (actions & SC_INTERRUPT) 27512997Sgabeblack@google.com sc_interrupt_here(report.get_msg_type(), report.get_severity()); 27612997Sgabeblack@google.com if (actions & SC_ABORT) 27712997Sgabeblack@google.com sc_abort(); 27812997Sgabeblack@google.com if (actions & SC_THROW) { 27912997Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 28012997Sgabeblack@google.com if (current) 28112997Sgabeblack@google.com current->isUnwinding(false); 28212997Sgabeblack@google.com throw report; 28312997Sgabeblack@google.com } 28412852Sgabeblack@google.com} 28512852Sgabeblack@google.com 28612852Sgabeblack@google.comsc_actions 28712852Sgabeblack@google.comsc_report_handler::get_new_action_id() 28812852Sgabeblack@google.com{ 28913312Sgabeblack@google.com static sc_actions maxAction = SC_ABORT; 29012997Sgabeblack@google.com maxAction = maxAction << 1; 29112997Sgabeblack@google.com return maxAction; 29212852Sgabeblack@google.com} 29312852Sgabeblack@google.com 29412852Sgabeblack@google.comsc_report * 29512852Sgabeblack@google.comsc_report_handler::get_cached_report() 29612852Sgabeblack@google.com{ 29712997Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 29812997Sgabeblack@google.com if (current) 29912997Sgabeblack@google.com return current->lastReport(); 30013312Sgabeblack@google.com return ::sc_gem5::globalReportCache.get(); 30112852Sgabeblack@google.com} 30212852Sgabeblack@google.com 30312852Sgabeblack@google.comvoid 30412852Sgabeblack@google.comsc_report_handler::clear_cached_report() 30512852Sgabeblack@google.com{ 30612997Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 30712997Sgabeblack@google.com if (current) { 30812997Sgabeblack@google.com current->lastReport(nullptr); 30912997Sgabeblack@google.com } else { 31013312Sgabeblack@google.com ::sc_gem5::globalReportCache = nullptr; 31112997Sgabeblack@google.com } 31212852Sgabeblack@google.com} 31312852Sgabeblack@google.com 31412852Sgabeblack@google.combool 31512997Sgabeblack@google.comsc_report_handler::set_log_file_name(const char *new_name) 31612852Sgabeblack@google.com{ 31712997Sgabeblack@google.com if (!new_name) { 31812997Sgabeblack@google.com logFile = nullptr; 31912997Sgabeblack@google.com logFileName = nullptr; 32012997Sgabeblack@google.com return false; 32112997Sgabeblack@google.com } else { 32212997Sgabeblack@google.com if (logFileName) 32312997Sgabeblack@google.com return false; 32412997Sgabeblack@google.com logFileName = std::unique_ptr<std::string>(new std::string(new_name)); 32512997Sgabeblack@google.com logFile = std::unique_ptr<std::ofstream>(new std::ofstream(new_name)); 32612997Sgabeblack@google.com return true; 32712997Sgabeblack@google.com } 32812852Sgabeblack@google.com} 32912852Sgabeblack@google.com 33012852Sgabeblack@google.comconst char * 33112852Sgabeblack@google.comsc_report_handler::get_log_file_name() 33212852Sgabeblack@google.com{ 33312997Sgabeblack@google.com if (!logFileName) 33412997Sgabeblack@google.com return nullptr; 33512997Sgabeblack@google.com else 33612997Sgabeblack@google.com return logFileName->c_str(); 33712852Sgabeblack@google.com} 33812852Sgabeblack@google.com 33912852Sgabeblack@google.comvoid 34012852Sgabeblack@google.comsc_interrupt_here(const char *msg_type, sc_severity) 34112852Sgabeblack@google.com{ 34212997Sgabeblack@google.com // Purposefully empty, for setting breakpoints supposedly. 34312852Sgabeblack@google.com} 34412852Sgabeblack@google.com 34512852Sgabeblack@google.comvoid 34612852Sgabeblack@google.comsc_stop_here(const char *msg_type, sc_severity) 34712852Sgabeblack@google.com{ 34812997Sgabeblack@google.com // Purposefully empty, for setting breakpoints supposedly. 34912852Sgabeblack@google.com} 35012852Sgabeblack@google.com 35112921Sgabeblack@google.comconst std::string 35212997Sgabeblack@google.comsc_report_compose_message(const sc_report &report) 35312921Sgabeblack@google.com{ 35412997Sgabeblack@google.com std::ostringstream str; 35512997Sgabeblack@google.com 35613312Sgabeblack@google.com const char *sevName = sc_gem5::reportSeverityNames[report.get_severity()]; 35712997Sgabeblack@google.com int id = report.get_id(); 35812997Sgabeblack@google.com 35912997Sgabeblack@google.com str << sevName << ": "; 36012997Sgabeblack@google.com if (id >= 0) { 36112997Sgabeblack@google.com ccprintf(str, "(%c%d) ", sevName[0], id); 36212997Sgabeblack@google.com } 36312997Sgabeblack@google.com str << report.get_msg_type(); 36412997Sgabeblack@google.com 36512997Sgabeblack@google.com const char *msg = report.get_msg(); 36613080Sgabeblack@google.com if (msg && msg[0]) 36712997Sgabeblack@google.com str << ": " << msg; 36812997Sgabeblack@google.com 36912997Sgabeblack@google.com if (report.get_severity() > SC_INFO) { 37012997Sgabeblack@google.com ccprintf(str, "\nIn file: %s:%d", report.get_file_name(), 37112997Sgabeblack@google.com report.get_line_number()); 37212997Sgabeblack@google.com 37312997Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 37412997Sgabeblack@google.com const char *name = report.get_process_name(); 37512997Sgabeblack@google.com if (current && sc_is_running() && name) { 37612997Sgabeblack@google.com ccprintf(str, "\nIn process: %s @ %s", name, 37712997Sgabeblack@google.com report.get_time().to_string()); 37812997Sgabeblack@google.com } 37912997Sgabeblack@google.com } 38012997Sgabeblack@google.com 38112997Sgabeblack@google.com return str.str(); 38212921Sgabeblack@google.com} 38312921Sgabeblack@google.com 38412921Sgabeblack@google.combool 38512921Sgabeblack@google.comsc_report_close_default_log() 38612921Sgabeblack@google.com{ 38712997Sgabeblack@google.com if (logFile) { 38812997Sgabeblack@google.com logFile = nullptr; 38912997Sgabeblack@google.com logFileName = nullptr; 39012997Sgabeblack@google.com return false; 39112997Sgabeblack@google.com } 39212997Sgabeblack@google.com return true; 39312921Sgabeblack@google.com} 39412921Sgabeblack@google.com 39512852Sgabeblack@google.com} // namespace sc_core 396