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