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