trace.hh revision 4041
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 502SN/A#if TRACING_ON 512SN/A const bool On = true; 522SN/A#else 532SN/A const bool On = false; 542SN/A#endif 552SN/A 562SN/A inline bool 572SN/A IsOn(int t) 582SN/A { 592SN/A return flags[t]; 602SN/A 612SN/A } 622SN/A 632SN/A void dump(const uint8_t *data, int count); 642SN/A 652SN/A class Record 662SN/A { 672SN/A protected: 681030SN/A Tick cycle; 692SN/A 702SN/A Record(Tick _cycle) 712SN/A : cycle(_cycle) 722SN/A { 732SN/A } 742SN/A 752SN/A public: 762SN/A virtual ~Record() {} 772SN/A 782SN/A virtual void dump(std::ostream &) = 0; 792SN/A }; 802SN/A 812SN/A class PrintfRecord : public Record 822SN/A { 832SN/A private: 844039Sbinkertn@umich.edu const std::string &name; 852SN/A const char *format; 864039Sbinkertn@umich.edu CPrintfArgsList args; 872SN/A 882SN/A public: 894039Sbinkertn@umich.edu PrintfRecord(Tick cycle, const std::string &_name, const char *_format, 904039Sbinkertn@umich.edu CPRINTF_DECLARATION) 914039Sbinkertn@umich.edu : Record(cycle), name(_name), format(_format), 924039Sbinkertn@umich.edu args(VARARGS_ALLARGS) 932SN/A { 942SN/A } 952SN/A 962SN/A virtual ~PrintfRecord(); 972SN/A 982SN/A virtual void dump(std::ostream &); 992SN/A }; 1002SN/A 1011030SN/A class DataRecord : public Record 1022SN/A { 1032SN/A private: 1041030SN/A const std::string &name; 1052SN/A uint8_t *data; 1062SN/A int len; 1072SN/A 1082SN/A public: 1091030SN/A DataRecord(Tick cycle, const std::string &name, 1101030SN/A const void *_data, int _len); 1111030SN/A virtual ~DataRecord(); 1122SN/A 1132SN/A virtual void dump(std::ostream &); 1142SN/A }; 1152SN/A 1162SN/A class Log 1172SN/A { 1182SN/A private: 1192SN/A int size; // number of records in log 1202SN/A Record **buffer; // array of 'size' Record ptrs (circular buf) 1212SN/A Record **nextRecPtr; // next slot to use in buffer 1222SN/A Record **wrapRecPtr; // &buffer[size], for quick wrap check 1232SN/A 1242SN/A public: 1252SN/A Log(); 1262SN/A ~Log(); 1272SN/A 1282SN/A void init(int _size); 1292SN/A 1302SN/A void append(Record *); // append trace record to log 1312SN/A void dump(std::ostream &); // dump contents to stream 1322SN/A }; 1332SN/A 1342SN/A extern Log theLog; 1352SN/A 1361031SN/A extern ObjectMatch ignore; 1372SN/A 1382SN/A inline void 1394039Sbinkertn@umich.edu dprintf(Tick when, const std::string &name, const char *format, 1404039Sbinkertn@umich.edu CPRINTF_DECLARATION) 1412SN/A { 1424039Sbinkertn@umich.edu if (!name.empty() && ignore.match(name)) 1434039Sbinkertn@umich.edu return; 1444039Sbinkertn@umich.edu 1454039Sbinkertn@umich.edu theLog.append(new Trace::PrintfRecord(when, name, format, 1464039Sbinkertn@umich.edu VARARGS_ALLARGS)); 1472SN/A } 1482SN/A 1492SN/A inline void 1504039Sbinkertn@umich.edu dataDump(Tick when, const std::string &name, const void *data, int len) 1512SN/A { 1524039Sbinkertn@umich.edu theLog.append(new Trace::DataRecord(when, name, data, len)); 1532SN/A } 1542SN/A 1552SN/A extern const std::string DefaultName; 1564039Sbinkertn@umich.edu 1572SN/A}; 1582SN/A 1594039Sbinkertn@umich.edustd::ostream &DebugOut(); 1604039Sbinkertn@umich.edu 1611070SN/A// This silly little class allows us to wrap a string in a functor 1621070SN/A// object so that we can give a name() that DPRINTF will like 1631070SN/Astruct StringWrap 1641070SN/A{ 1651070SN/A std::string str; 1661070SN/A StringWrap(const std::string &s) : str(s) {} 1671070SN/A const std::string &operator()() const { return str; } 1681070SN/A}; 1691070SN/A 1702SN/Ainline const std::string &name() { return Trace::DefaultName; } 1712SN/A 1722SN/A// 1732SN/A// DPRINTF is a debugging trace facility that allows one to 1742SN/A// selectively enable tracing statements. To use DPRINTF, there must 1752SN/A// be a function or functor called name() that returns a const 1762SN/A// std::string & in the current scope. 1772SN/A// 1782SN/A// If you desire that the automatic printing not occur, use DPRINTFR 1792SN/A// (R for raw) 1802SN/A// 1812SN/A 1822SN/A#if TRACING_ON 1832SN/A 1842SN/A#define DTRACE(x) (Trace::IsOn(Trace::x)) 1852SN/A 1864041Sbinkertn@umich.edu#define DDUMP(x, data, count) do { \ 1874041Sbinkertn@umich.edu if (DTRACE(x)) \ 1884041Sbinkertn@umich.edu Trace::dataDump(curTick, name(), data, count); \ 1892SN/A} while (0) 1902SN/A 1914041Sbinkertn@umich.edu#define DPRINTF(x, ...) do { \ 1924041Sbinkertn@umich.edu if (DTRACE(x)) \ 1934041Sbinkertn@umich.edu Trace::dprintf(curTick, name(), __VA_ARGS__); \ 1942SN/A} while (0) 1952SN/A 1964041Sbinkertn@umich.edu#define DPRINTFR(x, ...) do { \ 1974041Sbinkertn@umich.edu if (DTRACE(x)) \ 1984041Sbinkertn@umich.edu Trace::dprintf((Tick)-1, std::string(), __VA_ARGS__); \ 1992SN/A} while (0) 2002SN/A 2014041Sbinkertn@umich.edu#define DPRINTFN(...) do { \ 2024041Sbinkertn@umich.edu Trace::dprintf(curTick, name(), __VA_ARGS__); \ 2032SN/A} while (0) 2042SN/A 2054041Sbinkertn@umich.edu#define DPRINTFNR(...) do { \ 2064041Sbinkertn@umich.edu Trace::dprintf((Tick)-1, string(), __VA_ARGS__); \ 207507SN/A} while (0) 208507SN/A 2092SN/A#else // !TRACING_ON 2102SN/A 2112SN/A#define DTRACE(x) (false) 2124041Sbinkertn@umich.edu#define DPRINTF(x, ...) do {} while (0) 2134041Sbinkertn@umich.edu#define DPRINTFR(...) do {} while (0) 2144041Sbinkertn@umich.edu#define DPRINTFN(...) do {} while (0) 2154041Sbinkertn@umich.edu#define DPRINTFNR(...) do {} while (0) 216105SN/A#define DDUMP(x, data, count) do {} while (0) 2172SN/A 2182SN/A#endif // TRACING_ON 2192SN/A 2201354SN/A#endif // __BASE_TRACE_HH__ 221