X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbase%2Ftrace.hh;h=ddf936ecd72e89e8e81c599f22d1f365fe2865f3;hb=97887eb6dc9e548c9b5719727fd4783ef157917c;hp=eb0ab9daecd3c1ae4e45839778f2fca74d3c03ee;hpb=0e8a90f06bd3db00f700891a33458353478cce76;p=gem5.git diff --git a/src/base/trace.hh b/src/base/trace.hh index eb0ab9dae..ddf936ecd 100644 --- a/src/base/trace.hh +++ b/src/base/trace.hh @@ -1,4 +1,7 @@ /* + * Copyright (c) 2014 ARM Limited + * All rights reserved + * * Copyright (c) 2001-2006 The Regents of The University of Michigan * All rights reserved. * @@ -27,6 +30,7 @@ * * Authors: Nathan Binkert * Steve Reinhardt + * Andrew Bardsley */ #ifndef __BASE_TRACE_HH__ @@ -42,22 +46,79 @@ namespace Trace { -using Debug::SimpleFlag; -using Debug::CompoundFlag; +/** Debug logging base class. Handles formatting and outputting + * time/name/message messages */ +class Logger +{ + protected: + /** Name match for objects to ignore */ + ObjectMatch ignore; -std::ostream &output(); -void setOutput(const std::string &filename); + public: + /** Log a single message */ + template + void dprintf(Tick when, const std::string &name, const char *fmt, + const Args &...args) + { + if (!name.empty() && ignore.match(name)) + return; + + std::ostringstream line; + ccprintf(line, fmt, args...); + logMessage(when, name, line.str()); + } + + /** Dump a block of data of length len */ + virtual void dump(Tick when, const std::string &name, + const void *d, int len); + + /** Log formatted message */ + virtual void logMessage(Tick when, const std::string &name, + const std::string &message) = 0; + + /** 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; + + /** Set objects to ignore */ + void setIgnore(ObjectMatch &ignore_) { ignore = ignore_; } + + virtual ~Logger() { } +}; + +/** Logging wrapper for ostreams with the format: + * : : */ +class OstreamLogger : public Logger +{ + protected: + std::ostream &stream; + + public: + OstreamLogger(std::ostream &stream_) : stream(stream_) + { } + + void logMessage(Tick when, const std::string &name, + const std::string &message) override; -extern bool enabled; -bool changeFlag(const char *str, bool value); -void dumpStatus(); + std::ostream &getOstream() override { return stream; } +}; + +/** Get the current global debug logger. This takes ownership of the given + * logger which should be allocated using 'new' */ +Logger *getDebugLogger(); + +/** Get the ostream from the current global logger */ +std::ostream &output(); -extern ObjectMatch ignore; -extern const std::string DefaultName; +/** Delete the current global logger and assign a new one */ +void setDebugLogger(Logger *logger); -void dprintf(Tick when, const std::string &name, const char *format, - CPRINTF_DECLARATION); -void dump(Tick when, const std::string &name, const void *data, int len); +/** Enable/disable debug logging */ +void enable(); +void disable(); } // namespace Trace @@ -70,7 +131,9 @@ struct StringWrap const std::string &operator()() const { return str; } }; -inline const std::string &name() { return Trace::DefaultName; } +// 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 @@ -98,42 +161,48 @@ class Named #if TRACING_ON -#define DTRACE(x) ((Debug::x) && Trace::enabled) +#define DTRACE(x) (Debug::x) -#define DDUMP(x, data, count) do { \ - using namespace Debug; \ - if (DTRACE(x)) \ - Trace::dump(curTick(), name(), data, count); \ +#define DDUMP(x, data, count) do { \ + using namespace Debug; \ + if (DTRACE(x)) \ + Trace::getDebugLogger()->dump(curTick(), name(), data, count); \ } while (0) -#define DPRINTF(x, ...) do { \ - using namespace Debug; \ - if (DTRACE(x)) \ - Trace::dprintf(curTick(), name(), __VA_ARGS__); \ +#define DPRINTF(x, ...) do { \ + using namespace Debug; \ + if (DTRACE(x)) { \ + Trace::getDebugLogger()->dprintf(curTick(), name(), \ + __VA_ARGS__); \ + } \ } while (0) -#define DPRINTFS(x, s, ...) do { \ - using namespace Debug; \ - if (DTRACE(x)) \ - Trace::dprintf(curTick(), s->name(), __VA_ARGS__); \ +#define DPRINTFS(x, s, ...) do { \ + using namespace Debug; \ + if (DTRACE(x)) { \ + Trace::getDebugLogger()->dprintf(curTick(), s->name(), \ + __VA_ARGS__); \ + } \ } while (0) -#define DPRINTFR(x, ...) do { \ - using namespace Debug; \ - if (DTRACE(x)) \ - Trace::dprintf((Tick)-1, std::string(), __VA_ARGS__); \ +#define DPRINTFR(x, ...) do { \ + using namespace Debug; \ + if (DTRACE(x)) { \ + Trace::getDebugLogger()->dprintf((Tick)-1, std::string(), \ + __VA_ARGS__); \ + } \ } while (0) -#define DDUMPN(data, count) do { \ - Trace::dump(curTick(), name(), data, count); \ +#define DDUMPN(data, count) do { \ + Trace::getDebugLogger()->dump(curTick(), name(), data, count); \ } while (0) -#define DPRINTFN(...) do { \ - Trace::dprintf(curTick(), name(), __VA_ARGS__); \ +#define DPRINTFN(...) do { \ + Trace::getDebugLogger()->dprintf(curTick(), name(), __VA_ARGS__); \ } while (0) -#define DPRINTFNR(...) do { \ - Trace::dprintf((Tick)-1, string(), __VA_ARGS__); \ +#define DPRINTFNR(...) do { \ + Trace::getDebugLogger()->dprintf((Tick)-1, string(), __VA_ARGS__); \ } while (0) #else // !TRACING_ON