trace.hh revision 4042
12SN/A/* 24039Sbinkertn@umich.edu * Copyright (c) 2001-2006 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 292665Ssaidi@eecs.umich.edu * Steve Reinhardt 302SN/A */ 312SN/A 321354SN/A#ifndef __BASE_TRACE_HH__ 331354SN/A#define __BASE_TRACE_HH__ 342SN/A 352SN/A#include <vector> 362SN/A 3756SN/A#include "base/cprintf.hh" 381031SN/A#include "base/match.hh" 3956SN/A#include "sim/host.hh" 401696SN/A#include "sim/root.hh" 412SN/A 42699SN/A#include "base/traceflags.hh" 432SN/A 442SN/Anamespace Trace { 452SN/A 462SN/A typedef std::vector<bool> FlagVec; 472SN/A 482SN/A extern FlagVec flags; 492SN/A 504042Sbinkertn@umich.edu extern std::ostream *dprintf_stream; 512SN/A 522SN/A inline bool 532SN/A IsOn(int t) 542SN/A { 552SN/A return flags[t]; 564042Sbinkertn@umich.edu } 572SN/A 584042Sbinkertn@umich.edu extern bool enabled; 592SN/A 602SN/A void dump(const uint8_t *data, int count); 612SN/A 622SN/A class Record 632SN/A { 642SN/A protected: 651030SN/A Tick cycle; 662SN/A 672SN/A Record(Tick _cycle) 682SN/A : cycle(_cycle) 692SN/A { 702SN/A } 712SN/A 722SN/A public: 732SN/A virtual ~Record() {} 742SN/A 752SN/A virtual void dump(std::ostream &) = 0; 762SN/A }; 772SN/A 782SN/A class PrintfRecord : public Record 792SN/A { 802SN/A private: 814039Sbinkertn@umich.edu const std::string &name; 822SN/A const char *format; 834039Sbinkertn@umich.edu CPrintfArgsList args; 842SN/A 852SN/A public: 864039Sbinkertn@umich.edu PrintfRecord(Tick cycle, const std::string &_name, const char *_format, 874039Sbinkertn@umich.edu CPRINTF_DECLARATION) 884039Sbinkertn@umich.edu : Record(cycle), name(_name), format(_format), 894039Sbinkertn@umich.edu args(VARARGS_ALLARGS) 902SN/A { 912SN/A } 922SN/A 932SN/A virtual ~PrintfRecord(); 942SN/A 952SN/A virtual void dump(std::ostream &); 962SN/A }; 972SN/A 981030SN/A class DataRecord : public Record 992SN/A { 1002SN/A private: 1011030SN/A const std::string &name; 1022SN/A uint8_t *data; 1032SN/A int len; 1042SN/A 1052SN/A public: 1061030SN/A DataRecord(Tick cycle, const std::string &name, 1071030SN/A const void *_data, int _len); 1081030SN/A virtual ~DataRecord(); 1092SN/A 1102SN/A virtual void dump(std::ostream &); 1112SN/A }; 1122SN/A 1132SN/A class Log 1142SN/A { 1152SN/A private: 1162SN/A int size; // number of records in log 1172SN/A Record **buffer; // array of 'size' Record ptrs (circular buf) 1182SN/A Record **nextRecPtr; // next slot to use in buffer 1192SN/A Record **wrapRecPtr; // &buffer[size], for quick wrap check 1202SN/A 1212SN/A public: 1222SN/A Log(); 1232SN/A ~Log(); 1242SN/A 1252SN/A void init(int _size); 1262SN/A 1272SN/A void append(Record *); // append trace record to log 1282SN/A void dump(std::ostream &); // dump contents to stream 1292SN/A }; 1302SN/A 1312SN/A extern Log theLog; 1322SN/A 1331031SN/A extern ObjectMatch ignore; 1342SN/A 1352SN/A inline void 1364039Sbinkertn@umich.edu dprintf(Tick when, const std::string &name, const char *format, 1374039Sbinkertn@umich.edu CPRINTF_DECLARATION) 1382SN/A { 1394039Sbinkertn@umich.edu if (!name.empty() && ignore.match(name)) 1404039Sbinkertn@umich.edu return; 1414039Sbinkertn@umich.edu 1424039Sbinkertn@umich.edu theLog.append(new Trace::PrintfRecord(when, name, format, 1434039Sbinkertn@umich.edu VARARGS_ALLARGS)); 1442SN/A } 1452SN/A 1462SN/A inline void 1474039Sbinkertn@umich.edu dataDump(Tick when, const std::string &name, const void *data, int len) 1482SN/A { 1494039Sbinkertn@umich.edu theLog.append(new Trace::DataRecord(when, name, data, len)); 1502SN/A } 1512SN/A 1522SN/A extern const std::string DefaultName; 1534039Sbinkertn@umich.edu 1542SN/A}; 1552SN/A 1564042Sbinkertn@umich.eduinline std::ostream & 1574042Sbinkertn@umich.eduDebugOut() 1584042Sbinkertn@umich.edu{ 1594042Sbinkertn@umich.edu return *Trace::dprintf_stream; 1604042Sbinkertn@umich.edu} 1614039Sbinkertn@umich.edu 1621070SN/A// This silly little class allows us to wrap a string in a functor 1631070SN/A// object so that we can give a name() that DPRINTF will like 1641070SN/Astruct StringWrap 1651070SN/A{ 1661070SN/A std::string str; 1671070SN/A StringWrap(const std::string &s) : str(s) {} 1681070SN/A const std::string &operator()() const { return str; } 1691070SN/A}; 1701070SN/A 1712SN/Ainline const std::string &name() { return Trace::DefaultName; } 1722SN/A 1732SN/A// 1742SN/A// DPRINTF is a debugging trace facility that allows one to 1752SN/A// selectively enable tracing statements. To use DPRINTF, there must 1762SN/A// be a function or functor called name() that returns a const 1772SN/A// std::string & in the current scope. 1782SN/A// 1792SN/A// If you desire that the automatic printing not occur, use DPRINTFR 1802SN/A// (R for raw) 1812SN/A// 1822SN/A 1832SN/A#if TRACING_ON 1842SN/A 1854042Sbinkertn@umich.edu#define DTRACE(x) (Trace::IsOn(Trace::x) && Trace::enabled) 1862SN/A 1874041Sbinkertn@umich.edu#define DDUMP(x, data, count) do { \ 1884041Sbinkertn@umich.edu if (DTRACE(x)) \ 1894041Sbinkertn@umich.edu Trace::dataDump(curTick, name(), data, count); \ 1902SN/A} while (0) 1912SN/A 1924041Sbinkertn@umich.edu#define DPRINTF(x, ...) do { \ 1934041Sbinkertn@umich.edu if (DTRACE(x)) \ 1944041Sbinkertn@umich.edu Trace::dprintf(curTick, name(), __VA_ARGS__); \ 1952SN/A} while (0) 1962SN/A 1974041Sbinkertn@umich.edu#define DPRINTFR(x, ...) do { \ 1984041Sbinkertn@umich.edu if (DTRACE(x)) \ 1994041Sbinkertn@umich.edu Trace::dprintf((Tick)-1, std::string(), __VA_ARGS__); \ 2002SN/A} while (0) 2012SN/A 2024041Sbinkertn@umich.edu#define DPRINTFN(...) do { \ 2034041Sbinkertn@umich.edu Trace::dprintf(curTick, name(), __VA_ARGS__); \ 2042SN/A} while (0) 2052SN/A 2064041Sbinkertn@umich.edu#define DPRINTFNR(...) do { \ 2074041Sbinkertn@umich.edu Trace::dprintf((Tick)-1, string(), __VA_ARGS__); \ 208507SN/A} while (0) 209507SN/A 2102SN/A#else // !TRACING_ON 2112SN/A 2122SN/A#define DTRACE(x) (false) 2134041Sbinkertn@umich.edu#define DPRINTF(x, ...) do {} while (0) 2144041Sbinkertn@umich.edu#define DPRINTFR(...) do {} while (0) 2154041Sbinkertn@umich.edu#define DPRINTFN(...) do {} while (0) 2164041Sbinkertn@umich.edu#define DPRINTFNR(...) do {} while (0) 217105SN/A#define DDUMP(x, data, count) do {} while (0) 2182SN/A 2192SN/A#endif // TRACING_ON 2202SN/A 2211354SN/A#endif // __BASE_TRACE_HH__ 222