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