113372Sgabeblack@google.com/* 213372Sgabeblack@google.com * Copyright (c) 2014 ARM Limited 313372Sgabeblack@google.com * All rights reserved 413372Sgabeblack@google.com * 513372Sgabeblack@google.com * The license below extends only to copyright in the software and shall 613372Sgabeblack@google.com * not be construed as granting a license to any other intellectual 713372Sgabeblack@google.com * property including but not limited to intellectual property relating 813372Sgabeblack@google.com * to a hardware implementation of the functionality of the software 913372Sgabeblack@google.com * licensed hereunder. You may use the software subject to the license 1013372Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated 1113372Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software, 1213372Sgabeblack@google.com * modified or unmodified, in source code or in binary form. 1313372Sgabeblack@google.com * 1413372Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 1513372Sgabeblack@google.com * modification, are permitted provided that the following conditions are 1613372Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 1713372Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 1813372Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1913372Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 2013372Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 2113372Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 2213372Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 2313372Sgabeblack@google.com * this software without specific prior written permission. 2413372Sgabeblack@google.com * 2513372Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2613372Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2713372Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2813372Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2913372Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3013372Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3113372Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3213372Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3313372Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3413372Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3513372Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3613372Sgabeblack@google.com * 3713372Sgabeblack@google.com * Authors: Andrew Bardsley 3813372Sgabeblack@google.com */ 3913372Sgabeblack@google.com 4013372Sgabeblack@google.com/** 4113372Sgabeblack@google.com * @file 4213372Sgabeblack@google.com * 4313372Sgabeblack@google.com * A logger to allow SystemC to capture DPRINTF messages (and similar things) 4413372Sgabeblack@google.com * using sc_report 4513372Sgabeblack@google.com */ 4613372Sgabeblack@google.com 4713372Sgabeblack@google.com#include <cstdlib> 4813372Sgabeblack@google.com#include <cstring> 4913372Sgabeblack@google.com#include <sstream> 5013372Sgabeblack@google.com 5113372Sgabeblack@google.com#include "sc_logger.hh" 5213372Sgabeblack@google.com 5313372Sgabeblack@google.comnamespace Gem5SystemC 5413372Sgabeblack@google.com{ 5513372Sgabeblack@google.com 5613372Sgabeblack@google.com/** Class to act as a streambuf for std::ostream which cuts output strings 5713372Sgabeblack@google.com * into lines and offers them to a logger */ 5813372Sgabeblack@google.comclass CuttingStreambuf : public std::streambuf 5913372Sgabeblack@google.com{ 6013372Sgabeblack@google.com public: 6113372Sgabeblack@google.com /** Accumulate line so far */ 6213372Sgabeblack@google.com std::ostringstream line; 6313372Sgabeblack@google.com 6413372Sgabeblack@google.com /** Logger to send complete lines to */ 6513372Sgabeblack@google.com Trace::Logger *logger; 6613372Sgabeblack@google.com 6713372Sgabeblack@google.com CuttingStreambuf(Trace::Logger *logger_) : logger(logger_) 6813372Sgabeblack@google.com { } 6913372Sgabeblack@google.com 7013372Sgabeblack@google.com /** Accumulate to line up to \n and then emit */ 7113372Sgabeblack@google.com int overflow(int i); 7213372Sgabeblack@google.com int sync(); 7313372Sgabeblack@google.com 7413372Sgabeblack@google.com /** Push a line out to the logger */ 7513372Sgabeblack@google.com void outputLine(); 7613372Sgabeblack@google.com 7713372Sgabeblack@google.com ~CuttingStreambuf(); 7813372Sgabeblack@google.com}; 7913372Sgabeblack@google.com 8013372Sgabeblack@google.comvoid CuttingStreambuf::outputLine() 8113372Sgabeblack@google.com{ 8213372Sgabeblack@google.com logger->logMessage((Tick)-1, "gem5", line.str()); 8313372Sgabeblack@google.com line.clear(); 8413372Sgabeblack@google.com line.str(""); 8513372Sgabeblack@google.com} 8613372Sgabeblack@google.com 8713372Sgabeblack@google.com/** This is pretty much the least efficient way of doing this, but it has the 8813372Sgabeblack@google.com * advantage of having very few corners to get wrong. 8913372Sgabeblack@google.com * 9013372Sgabeblack@google.com * A newly allocated streambuf will have no buffer to serve to its 9113372Sgabeblack@google.com * [oi]stream. It will, therefore, call overflow for every character it 9213372Sgabeblack@google.com * wants to insert into the output stream. Those characters are captured one 9313372Sgabeblack@google.com * by one here and added to this->line. */ 9413372Sgabeblack@google.comint 9513372Sgabeblack@google.comCuttingStreambuf::overflow(int chr) 9613372Sgabeblack@google.com{ 9713372Sgabeblack@google.com if (chr == '\n') 9813372Sgabeblack@google.com outputLine(); 9913372Sgabeblack@google.com else if (chr != EOF) 10013372Sgabeblack@google.com line << (char) chr; 10113372Sgabeblack@google.com 10213372Sgabeblack@google.com /* Always succeeds */ 10313372Sgabeblack@google.com return 0; 10413372Sgabeblack@google.com} 10513372Sgabeblack@google.com 10613372Sgabeblack@google.comint 10713372Sgabeblack@google.comCuttingStreambuf::sync() 10813372Sgabeblack@google.com{ 10913372Sgabeblack@google.com if (!line.str().empty()) 11013372Sgabeblack@google.com outputLine(); 11113372Sgabeblack@google.com 11213372Sgabeblack@google.com /* Always succeeds */ 11313372Sgabeblack@google.com return 0; 11413372Sgabeblack@google.com} 11513372Sgabeblack@google.com 11613372Sgabeblack@google.comCuttingStreambuf::~CuttingStreambuf() 11713372Sgabeblack@google.com{ 11813372Sgabeblack@google.com sync(); 11913372Sgabeblack@google.com} 12013372Sgabeblack@google.com 12113372Sgabeblack@google.comLogger::Logger() : 12213372Sgabeblack@google.com cuttingStreambuf(new CuttingStreambuf(this)), 12313372Sgabeblack@google.com stream(cuttingStreambuf) 12413372Sgabeblack@google.com{ 12513372Sgabeblack@google.com} 12613372Sgabeblack@google.com 12713372Sgabeblack@google.comLogger::~Logger() 12813372Sgabeblack@google.com{ 12913372Sgabeblack@google.com stream.flush(); 13013372Sgabeblack@google.com delete cuttingStreambuf; 13113372Sgabeblack@google.com} 13213372Sgabeblack@google.com 13313372Sgabeblack@google.com/** Log a single message as a single sc_report call */ 13413372Sgabeblack@google.comvoid 13513372Sgabeblack@google.comLogger::logMessage(Tick when, const std::string &name, 13613372Sgabeblack@google.com const std::string &message) 13713372Sgabeblack@google.com{ 13813372Sgabeblack@google.com /* Need to chop the newline off the message */ 13913372Sgabeblack@google.com std::string message_without_nl = message; 14013372Sgabeblack@google.com message_without_nl.erase( 14113372Sgabeblack@google.com message_without_nl.find_last_not_of(" \n\r") + 1); 14213372Sgabeblack@google.com 14313372Sgabeblack@google.com SC_REPORT_INFO(name.c_str(), message_without_nl.c_str()); 14413372Sgabeblack@google.com} 14513372Sgabeblack@google.com 14613372Sgabeblack@google.comstd::ostream & 14713372Sgabeblack@google.comLogger::getOstream() 14813372Sgabeblack@google.com{ 14913372Sgabeblack@google.com return stream; 15013372Sgabeblack@google.com} 15113372Sgabeblack@google.com 15213372Sgabeblack@google.com} 153