X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbase%2Ftrace.hh;h=ddf936ecd72e89e8e81c599f22d1f365fe2865f3;hb=97887eb6dc9e548c9b5719727fd4783ef157917c;hp=8df5dd893e988a2b0c25dbffd0f7529fc9242750;hpb=d2d581cf01d07f6a22f02f471d23e3d31919c695;p=gem5.git diff --git a/src/base/trace.hh b/src/base/trace.hh index 8df5dd893..ddf936ecd 100644 --- a/src/base/trace.hh +++ b/src/base/trace.hh @@ -1,5 +1,8 @@ /* - * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2014 ARM Limited + * All rights reserved + * + * Copyright (c) 2001-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,138 +30,97 @@ * * Authors: Nathan Binkert * Steve Reinhardt + * Andrew Bardsley */ #ifndef __BASE_TRACE_HH__ #define __BASE_TRACE_HH__ -#include +#include #include "base/cprintf.hh" +#include "base/debug.hh" #include "base/match.hh" -#include "sim/host.hh" -#include "sim/root.hh" - -#ifndef TRACING_ON -#ifndef NDEBUG -#define TRACING_ON 1 -#else -#define TRACING_ON 0 -#endif -#endif - -#include "base/traceflags.hh" +#include "base/types.hh" +#include "sim/core.hh" namespace Trace { - typedef std::vector FlagVec; - - extern FlagVec flags; - -#if TRACING_ON - const bool On = true; -#else - const bool On = false; -#endif - - inline bool - IsOn(int t) +/** Debug logging base class. Handles formatting and outputting + * time/name/message messages */ +class Logger +{ + protected: + /** Name match for objects to ignore */ + ObjectMatch ignore; + + public: + /** Log a single message */ + template + void dprintf(Tick when, const std::string &name, const char *fmt, + const Args &...args) { - return flags[t]; + if (!name.empty() && ignore.match(name)) + return; + std::ostringstream line; + ccprintf(line, fmt, args...); + logMessage(when, name, line.str()); } - void dump(const uint8_t *data, int count); - - class Record - { - protected: - Tick cycle; - - Record(Tick _cycle) - : cycle(_cycle) - { - } - - public: - virtual ~Record() {} - - virtual void dump(std::ostream &) = 0; - }; - - class PrintfRecord : public Record - { - private: - const char *format; - const std::string &name; - cp::ArgList &args; - - public: - PrintfRecord(const char *_format, cp::ArgList &_args, - Tick cycle, const std::string &_name) - : Record(cycle), format(_format), name(_name), args(_args) - { - } - - virtual ~PrintfRecord(); - - virtual void dump(std::ostream &); - }; + /** Dump a block of data of length len */ + virtual void dump(Tick when, const std::string &name, + const void *d, int len); - class DataRecord : public Record - { - private: - const std::string &name; - uint8_t *data; - int len; + /** Log formatted message */ + virtual void logMessage(Tick when, const std::string &name, + const std::string &message) = 0; - public: - DataRecord(Tick cycle, const std::string &name, - const void *_data, int _len); - virtual ~DataRecord(); + /** Return an ostream that can be used to send messages to + * the 'same place' as formatted logMessage messages. This + * can be implemented to use a logger's underlying ostream, + * to provide an ostream which formats the output in some + * way, or just set to one of std::cout, std::cerr */ + virtual std::ostream &getOstream() = 0; - virtual void dump(std::ostream &); - }; + /** Set objects to ignore */ + void setIgnore(ObjectMatch &ignore_) { ignore = ignore_; } - class Log - { - private: - int size; // number of records in log - Record **buffer; // array of 'size' Record ptrs (circular buf) - Record **nextRecPtr; // next slot to use in buffer - Record **wrapRecPtr; // &buffer[size], for quick wrap check + virtual ~Logger() { } +}; - public: +/** Logging wrapper for ostreams with the format: + * : : */ +class OstreamLogger : public Logger +{ + protected: + std::ostream &stream; - Log(); - ~Log(); + public: + OstreamLogger(std::ostream &stream_) : stream(stream_) + { } - void init(int _size); + void logMessage(Tick when, const std::string &name, + const std::string &message) override; - void append(Record *); // append trace record to log - void dump(std::ostream &); // dump contents to stream - }; + std::ostream &getOstream() override { return stream; } +}; - extern Log theLog; +/** Get the current global debug logger. This takes ownership of the given + * logger which should be allocated using 'new' */ +Logger *getDebugLogger(); - extern ObjectMatch ignore; +/** Get the ostream from the current global logger */ +std::ostream &output(); - inline void - dprintf(const char *format, cp::ArgList &args, Tick cycle, - const std::string &name) - { - if (name.empty() || !ignore.match(name)) - theLog.append(new Trace::PrintfRecord(format, args, cycle, name)); - } +/** Delete the current global logger and assign a new one */ +void setDebugLogger(Logger *logger); - inline void - dataDump(Tick cycle, const std::string &name, const void *data, int len) - { - theLog.append(new Trace::DataRecord(cycle, name, data, len)); - } +/** Enable/disable debug logging */ +void enable(); +void disable(); - extern const std::string DefaultName; -}; +} // namespace Trace // This silly little class allows us to wrap a string in a functor // object so that we can give a name() that DPRINTF will like @@ -169,8 +131,23 @@ struct StringWrap const std::string &operator()() const { return str; } }; -inline const std::string &name() { return Trace::DefaultName; } -std::ostream &DebugOut(); +// Return the global context name "global". This function gets called when +// the DPRINTF macros are used in a context without a visible name() function +const std::string &name(); + +// Interface for things with names. (cf. SimObject but without other +// functionality). This is useful when using DPRINTF +class Named +{ + protected: + const std::string _name; + + public: + Named(const std::string &name_) : _name(name_) { } + + public: + const std::string &name() const { return _name; } +}; // // DPRINTF is a debugging trace facility that allows one to @@ -184,51 +161,61 @@ std::ostream &DebugOut(); #if TRACING_ON -#define DTRACE(x) (Trace::IsOn(Trace::x)) +#define DTRACE(x) (Debug::x) -#define DCOUT(x) if (Trace::IsOn(Trace::x)) DebugOut() +#define DDUMP(x, data, count) do { \ + using namespace Debug; \ + if (DTRACE(x)) \ + Trace::getDebugLogger()->dump(curTick(), name(), data, count); \ +} while (0) -#define DDUMP(x, data, count) \ -do { \ - if (Trace::IsOn(Trace::x)) \ - Trace::dataDump(curTick, name(), data, count); \ +#define DPRINTF(x, ...) do { \ + using namespace Debug; \ + if (DTRACE(x)) { \ + Trace::getDebugLogger()->dprintf(curTick(), name(), \ + __VA_ARGS__); \ + } \ } while (0) -#define __dprintf(cycle, name, format, args...) \ - Trace::dprintf(format, (*(new cp::ArgList), args), cycle, name) +#define DPRINTFS(x, s, ...) do { \ + using namespace Debug; \ + if (DTRACE(x)) { \ + Trace::getDebugLogger()->dprintf(curTick(), s->name(), \ + __VA_ARGS__); \ + } \ +} while (0) -#define DPRINTF(x, args...) \ -do { \ - if (Trace::IsOn(Trace::x)) \ - __dprintf(curTick, name(), args, cp::ArgListNull()); \ +#define DPRINTFR(x, ...) do { \ + using namespace Debug; \ + if (DTRACE(x)) { \ + Trace::getDebugLogger()->dprintf((Tick)-1, std::string(), \ + __VA_ARGS__); \ + } \ } while (0) -#define DPRINTFR(x, args...) \ -do { \ - if (Trace::IsOn(Trace::x)) \ - __dprintf((Tick)-1, std::string(), args, cp::ArgListNull()); \ +#define DDUMPN(data, count) do { \ + Trace::getDebugLogger()->dump(curTick(), name(), data, count); \ } while (0) -#define DPRINTFN(args...) \ -do { \ - __dprintf(curTick, name(), args, cp::ArgListNull()); \ +#define DPRINTFN(...) do { \ + Trace::getDebugLogger()->dprintf(curTick(), name(), __VA_ARGS__); \ } while (0) -#define DPRINTFNR(args...) \ -do { \ - __dprintf((Tick)-1, string(), args, cp::ArgListNull()); \ +#define DPRINTFNR(...) do { \ + Trace::getDebugLogger()->dprintf((Tick)-1, string(), __VA_ARGS__); \ } while (0) #else // !TRACING_ON #define DTRACE(x) (false) -#define DCOUT(x) if (0) DebugOut() -#define DPRINTF(x, args...) do {} while (0) -#define DPRINTFR(args...) do {} while (0) -#define DPRINTFN(args...) do {} while (0) -#define DPRINTFNR(args...) do {} while (0) #define DDUMP(x, data, count) do {} while (0) - -#endif // TRACING_ON +#define DPRINTF(x, ...) do {} while (0) +#define DPRINTFS(x, ...) do {} while (0) +#define DPRINTFR(...) do {} while (0) +#define DDUMPN(data, count) do {} while (0) +#define DPRINTFN(...) do {} while (0) +#define DPRINTFNR(...) do {} while (0) + +#endif // TRACING_ON #endif // __BASE_TRACE_HH__