trace.hh revision 4042
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
504042Sbinkertn@umich.edu    extern std::ostream *dprintf_stream;
512SN/A
522SN/A    inline bool
532SN/A    IsOn(int t)
542SN/A    {
552SN/A        return flags[t];
564042Sbinkertn@umich.edu    }
572SN/A
584042Sbinkertn@umich.edu    extern bool enabled;
592SN/A
602SN/A    void dump(const uint8_t *data, int count);
612SN/A
622SN/A    class Record
632SN/A    {
642SN/A      protected:
651030SN/A        Tick cycle;
662SN/A
672SN/A        Record(Tick _cycle)
682SN/A            : cycle(_cycle)
692SN/A        {
702SN/A        }
712SN/A
722SN/A      public:
732SN/A        virtual ~Record() {}
742SN/A
752SN/A        virtual void dump(std::ostream &) = 0;
762SN/A    };
772SN/A
782SN/A    class PrintfRecord : public Record
792SN/A    {
802SN/A      private:
814039Sbinkertn@umich.edu        const std::string &name;
822SN/A        const char *format;
834039Sbinkertn@umich.edu        CPrintfArgsList args;
842SN/A
852SN/A      public:
864039Sbinkertn@umich.edu        PrintfRecord(Tick cycle, const std::string &_name, const char *_format,
874039Sbinkertn@umich.edu                     CPRINTF_DECLARATION)
884039Sbinkertn@umich.edu            : Record(cycle), name(_name), format(_format),
894039Sbinkertn@umich.edu              args(VARARGS_ALLARGS)
902SN/A        {
912SN/A        }
922SN/A
932SN/A        virtual ~PrintfRecord();
942SN/A
952SN/A        virtual void dump(std::ostream &);
962SN/A    };
972SN/A
981030SN/A    class DataRecord : public Record
992SN/A    {
1002SN/A      private:
1011030SN/A        const std::string &name;
1022SN/A        uint8_t *data;
1032SN/A        int len;
1042SN/A
1052SN/A      public:
1061030SN/A        DataRecord(Tick cycle, const std::string &name,
1071030SN/A                   const void *_data, int _len);
1081030SN/A        virtual ~DataRecord();
1092SN/A
1102SN/A        virtual void dump(std::ostream &);
1112SN/A    };
1122SN/A
1132SN/A    class Log
1142SN/A    {
1152SN/A      private:
1162SN/A        int	 size;		// number of records in log
1172SN/A        Record **buffer;	// array of 'size' Record ptrs (circular buf)
1182SN/A        Record **nextRecPtr;	// next slot to use in buffer
1192SN/A        Record **wrapRecPtr;	// &buffer[size], for quick wrap check
1202SN/A
1212SN/A      public:
1222SN/A        Log();
1232SN/A        ~Log();
1242SN/A
1252SN/A        void init(int _size);
1262SN/A
1272SN/A        void append(Record *);	// append trace record to log
1282SN/A        void dump(std::ostream &);	// dump contents to stream
1292SN/A    };
1302SN/A
1312SN/A    extern Log theLog;
1322SN/A
1331031SN/A    extern ObjectMatch ignore;
1342SN/A
1352SN/A    inline void
1364039Sbinkertn@umich.edu    dprintf(Tick when, const std::string &name, const char *format,
1374039Sbinkertn@umich.edu            CPRINTF_DECLARATION)
1382SN/A    {
1394039Sbinkertn@umich.edu        if (!name.empty() && ignore.match(name))
1404039Sbinkertn@umich.edu            return;
1414039Sbinkertn@umich.edu
1424039Sbinkertn@umich.edu        theLog.append(new Trace::PrintfRecord(when, name, format,
1434039Sbinkertn@umich.edu                                              VARARGS_ALLARGS));
1442SN/A    }
1452SN/A
1462SN/A    inline void
1474039Sbinkertn@umich.edu    dataDump(Tick when, const std::string &name, const void *data, int len)
1482SN/A    {
1494039Sbinkertn@umich.edu        theLog.append(new Trace::DataRecord(when, name, data, len));
1502SN/A    }
1512SN/A
1522SN/A    extern const std::string DefaultName;
1534039Sbinkertn@umich.edu
1542SN/A};
1552SN/A
1564042Sbinkertn@umich.eduinline std::ostream &
1574042Sbinkertn@umich.eduDebugOut()
1584042Sbinkertn@umich.edu{
1594042Sbinkertn@umich.edu    return *Trace::dprintf_stream;
1604042Sbinkertn@umich.edu}
1614039Sbinkertn@umich.edu
1621070SN/A// This silly little class allows us to wrap a string in a functor
1631070SN/A// object so that we can give a name() that DPRINTF will like
1641070SN/Astruct StringWrap
1651070SN/A{
1661070SN/A    std::string str;
1671070SN/A    StringWrap(const std::string &s) : str(s) {}
1681070SN/A    const std::string &operator()() const { return str; }
1691070SN/A};
1701070SN/A
1712SN/Ainline const std::string &name() { return Trace::DefaultName; }
1722SN/A
1732SN/A//
1742SN/A// DPRINTF is a debugging trace facility that allows one to
1752SN/A// selectively enable tracing statements.  To use DPRINTF, there must
1762SN/A// be a function or functor called name() that returns a const
1772SN/A// std::string & in the current scope.
1782SN/A//
1792SN/A// If you desire that the automatic printing not occur, use DPRINTFR
1802SN/A// (R for raw)
1812SN/A//
1822SN/A
1832SN/A#if TRACING_ON
1842SN/A
1854042Sbinkertn@umich.edu#define DTRACE(x) (Trace::IsOn(Trace::x) && Trace::enabled)
1862SN/A
1874041Sbinkertn@umich.edu#define DDUMP(x, data, count) do {                              \
1884041Sbinkertn@umich.edu    if (DTRACE(x))                                              \
1894041Sbinkertn@umich.edu        Trace::dataDump(curTick, name(), data, count);          \
1902SN/A} while (0)
1912SN/A
1924041Sbinkertn@umich.edu#define DPRINTF(x, ...) do {                                    \
1934041Sbinkertn@umich.edu    if (DTRACE(x))                                              \
1944041Sbinkertn@umich.edu        Trace::dprintf(curTick, name(), __VA_ARGS__);           \
1952SN/A} while (0)
1962SN/A
1974041Sbinkertn@umich.edu#define DPRINTFR(x, ...) do {                                   \
1984041Sbinkertn@umich.edu    if (DTRACE(x))                                              \
1994041Sbinkertn@umich.edu        Trace::dprintf((Tick)-1, std::string(), __VA_ARGS__);   \
2002SN/A} while (0)
2012SN/A
2024041Sbinkertn@umich.edu#define DPRINTFN(...) do {                                      \
2034041Sbinkertn@umich.edu    Trace::dprintf(curTick, name(), __VA_ARGS__);               \
2042SN/A} while (0)
2052SN/A
2064041Sbinkertn@umich.edu#define DPRINTFNR(...) do {                                     \
2074041Sbinkertn@umich.edu    Trace::dprintf((Tick)-1, string(), __VA_ARGS__);            \
208507SN/A} while (0)
209507SN/A
2102SN/A#else // !TRACING_ON
2112SN/A
2122SN/A#define DTRACE(x) (false)
2134041Sbinkertn@umich.edu#define DPRINTF(x, ...) do {} while (0)
2144041Sbinkertn@umich.edu#define DPRINTFR(...) do {} while (0)
2154041Sbinkertn@umich.edu#define DPRINTFN(...) do {} while (0)
2164041Sbinkertn@umich.edu#define DPRINTFNR(...) do {} while (0)
217105SN/A#define DDUMP(x, data, count) do {} while (0)
2182SN/A
2192SN/A#endif	// TRACING_ON
2202SN/A
2211354SN/A#endif // __BASE_TRACE_HH__
222