1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30 */ 31 32#ifndef __BASE_TRACE_HH__ 33#define __BASE_TRACE_HH__ 34 35#include <vector> 36 37#include "base/cprintf.hh" 38#include "base/match.hh" 39#include "sim/host.hh" 40#include "sim/root.hh" 41 42#ifndef TRACING_ON 43#ifndef NDEBUG 44#define TRACING_ON 1 45#else 46#define TRACING_ON 0 47#endif 48#endif 49 50#include "base/traceflags.hh" 51 52namespace Trace { 53 54 typedef std::vector<bool> FlagVec; 55 56 extern FlagVec flags; 57 58#if TRACING_ON 59 const bool On = true; 60#else 61 const bool On = false; 62#endif 63 64 inline bool 65 IsOn(int t) 66 { 67 return flags[t]; 68 69 } 70 71 void dump(const uint8_t *data, int count); 72 73 class Record 74 { 75 protected: 76 Tick cycle; 77 78 Record(Tick _cycle) 79 : cycle(_cycle) 80 { 81 } 82 83 public: 84 virtual ~Record() {} 85 86 virtual void dump(std::ostream &) = 0; 87 }; 88 89 class PrintfRecord : public Record 90 { 91 private: 92 const char *format; 93 const std::string &name; 94 cp::ArgList &args; 95 96 public: 97 PrintfRecord(const char *_format, cp::ArgList &_args, 98 Tick cycle, const std::string &_name) 99 : Record(cycle), format(_format), name(_name), args(_args) 100 { 101 } 102 103 virtual ~PrintfRecord(); 104 105 virtual void dump(std::ostream &); 106 }; 107 108 class DataRecord : public Record 109 { 110 private: 111 const std::string &name; 112 uint8_t *data; 113 int len; 114 115 public: 116 DataRecord(Tick cycle, const std::string &name, 117 const void *_data, int _len); 118 virtual ~DataRecord(); 119 120 virtual void dump(std::ostream &); 121 }; 122 123 class Log 124 { 125 private: 126 int size; // number of records in log 127 Record **buffer; // array of 'size' Record ptrs (circular buf) 128 Record **nextRecPtr; // next slot to use in buffer 129 Record **wrapRecPtr; // &buffer[size], for quick wrap check 130 131 public: 132 133 Log(); 134 ~Log(); 135 136 void init(int _size); 137 138 void append(Record *); // append trace record to log 139 void dump(std::ostream &); // dump contents to stream 140 }; 141 142 extern Log theLog; 143 144 extern ObjectMatch ignore; 145 146 inline void 147 dprintf(const char *format, cp::ArgList &args, Tick cycle, 148 const std::string &name) 149 { 150 if (name.empty() || !ignore.match(name)) 151 theLog.append(new Trace::PrintfRecord(format, args, cycle, name)); 152 } 153 154 inline void 155 dataDump(Tick cycle, const std::string &name, const void *data, int len) 156 { 157 theLog.append(new Trace::DataRecord(cycle, name, data, len)); 158 } 159 160 extern const std::string DefaultName; 161}; 162 163// This silly little class allows us to wrap a string in a functor 164// object so that we can give a name() that DPRINTF will like 165struct StringWrap 166{ 167 std::string str; 168 StringWrap(const std::string &s) : str(s) {} 169 const std::string &operator()() const { return str; } 170}; 171 172inline const std::string &name() { return Trace::DefaultName; } 173std::ostream &DebugOut(); 174 175// 176// DPRINTF is a debugging trace facility that allows one to 177// selectively enable tracing statements. To use DPRINTF, there must 178// be a function or functor called name() that returns a const 179// std::string & in the current scope. 180// 181// If you desire that the automatic printing not occur, use DPRINTFR 182// (R for raw) 183// 184 185#if TRACING_ON 186 187#define DTRACE(x) (Trace::IsOn(Trace::x)) 188 189#define DCOUT(x) if (Trace::IsOn(Trace::x)) DebugOut() 190 191#define DDUMP(x, data, count) \ 192do { \ 193 if (Trace::IsOn(Trace::x)) \ 194 Trace::dataDump(curTick, name(), data, count); \ 195} while (0) 196 197#define __dprintf(cycle, name, format, args...) \ 198 Trace::dprintf(format, (*(new cp::ArgList), args), cycle, name) 199 200#define DPRINTF(x, args...) \ 201do { \ 202 if (Trace::IsOn(Trace::x)) \ 203 __dprintf(curTick, name(), args, cp::ArgListNull()); \ 204} while (0) 205 206#define DPRINTFR(x, args...) \ 207do { \ 208 if (Trace::IsOn(Trace::x)) \ 209 __dprintf((Tick)-1, std::string(), args, cp::ArgListNull()); \ 210} while (0) 211 212#define DPRINTFN(args...) \ 213do { \ 214 __dprintf(curTick, name(), args, cp::ArgListNull()); \ 215} while (0) 216 217#define DPRINTFNR(args...) \ 218do { \ 219 __dprintf((Tick)-1, string(), args, cp::ArgListNull()); \ 220} while (0) 221 222#else // !TRACING_ON 223 224#define DTRACE(x) (false) 225#define DCOUT(x) if (0) DebugOut() 226#define DPRINTF(x, args...) do {} while (0) 227#define DPRINTFR(args...) do {} while (0) 228#define DPRINTFN(args...) do {} while (0) 229#define DPRINTFNR(args...) do {} while (0) 230#define DDUMP(x, data, count) do {} while (0) 231 232#endif // TRACING_ON 233 234#endif // __BASE_TRACE_HH__
|