diff options
author | Nathan Binkert <nate@binkert.org> | 2009-05-11 10:38:43 -0700 |
---|---|---|
committer | Nathan Binkert <nate@binkert.org> | 2009-05-11 10:38:43 -0700 |
commit | 2f30950143cc70bc42a3c8a4111d7cf8198ec881 (patch) | |
tree | 708f6c22edb3c6feb31dd82866c26623a5329580 /src/mem/ruby/recorder | |
parent | c70241810d4e4f523f173c1646b008dc40faad8e (diff) | |
download | gem5-2f30950143cc70bc42a3c8a4111d7cf8198ec881.tar.xz |
ruby: Import ruby and slicc from GEMS
We eventually plan to replace the m5 cache hierarchy with the GEMS
hierarchy, but for now we will make both live alongside eachother.
Diffstat (limited to 'src/mem/ruby/recorder')
-rw-r--r-- | src/mem/ruby/recorder/CacheRecorder.cc | 75 | ||||
-rw-r--r-- | src/mem/ruby/recorder/CacheRecorder.hh | 87 | ||||
-rw-r--r-- | src/mem/ruby/recorder/TraceRecord.cc | 132 | ||||
-rw-r--r-- | src/mem/ruby/recorder/TraceRecord.hh | 101 | ||||
-rw-r--r-- | src/mem/ruby/recorder/Tracer.cc | 126 | ||||
-rw-r--r-- | src/mem/ruby/recorder/Tracer.hh | 94 |
6 files changed, 615 insertions, 0 deletions
diff --git a/src/mem/ruby/recorder/CacheRecorder.cc b/src/mem/ruby/recorder/CacheRecorder.cc new file mode 100644 index 000000000..e858f618e --- /dev/null +++ b/src/mem/ruby/recorder/CacheRecorder.cc @@ -0,0 +1,75 @@ + +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * $Id$ + * + */ + +#include "CacheRecorder.hh" +#include "TraceRecord.hh" +#include "EventQueue.hh" +#include "PrioHeap.hh" +#include "gzstream.hh" + +CacheRecorder::CacheRecorder() +{ + m_records_ptr = new PrioHeap<TraceRecord>; +} + +CacheRecorder::~CacheRecorder() +{ + delete m_records_ptr; +} + +void CacheRecorder::addRecord(NodeID id, const Address& data_addr, const Address& pc_addr, CacheRequestType type, Time time) +{ + m_records_ptr->insert(TraceRecord(id, data_addr, pc_addr, type, time)); +} + +int CacheRecorder::dumpRecords(string filename) +{ + ogzstream out(filename.c_str()); + if (out.fail()) { + cout << "Error: error opening file '" << filename << "'" << endl; + return 0; + } + + int counter = 0; + while (m_records_ptr->size() != 0) { + TraceRecord record = m_records_ptr->extractMin(); + record.output(out); + counter++; + } + return counter; +} + +void CacheRecorder::print(ostream& out) const +{ +} diff --git a/src/mem/ruby/recorder/CacheRecorder.hh b/src/mem/ruby/recorder/CacheRecorder.hh new file mode 100644 index 000000000..b8b56ff09 --- /dev/null +++ b/src/mem/ruby/recorder/CacheRecorder.hh @@ -0,0 +1,87 @@ + +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * $Id$ + * + * Description: Recording cache requests made to a ruby cache at certain + * ruby time. Also dump the requests to a gziped file. + * + */ + +#ifndef CACHERECORDER_H +#define CACHERECORDER_H + +#include "Global.hh" +#include "NodeID.hh" +#include "CacheRequestType.hh" + +template <class TYPE> class PrioHeap; +class Address; +class TraceRecord; + +class CacheRecorder { +public: + // Constructors + CacheRecorder(); + + // Destructor + ~CacheRecorder(); + + // Public Methods + void addRecord(NodeID id, const Address& data_addr, const Address& pc_addr, CacheRequestType type, Time time); + int dumpRecords(string filename); + + void print(ostream& out) const; +private: + // Private Methods + + // Private copy constructor and assignment operator + CacheRecorder(const CacheRecorder& obj); + CacheRecorder& operator=(const CacheRecorder& obj); + + // Data Members (m_ prefix) + PrioHeap<TraceRecord>* m_records_ptr; +}; + +// Output operator declaration +ostream& operator<<(ostream& out, const CacheRecorder& obj); + +// ******************* Definitions ******************* + +// Output operator definition +extern inline +ostream& operator<<(ostream& out, const CacheRecorder& obj) +{ + obj.print(out); + out << flush; + return out; +} + +#endif //CACHERECORDER_H diff --git a/src/mem/ruby/recorder/TraceRecord.cc b/src/mem/ruby/recorder/TraceRecord.cc new file mode 100644 index 000000000..3116edf93 --- /dev/null +++ b/src/mem/ruby/recorder/TraceRecord.cc @@ -0,0 +1,132 @@ + +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * $Id$ + * + */ + +#include "TraceRecord.hh" +#include "Sequencer.hh" +#include "System.hh" +#include "AbstractChip.hh" +#include "CacheMsg.hh" + +TraceRecord::TraceRecord(NodeID id, const Address& data_addr, const Address& pc_addr, CacheRequestType type, Time time) +{ + m_node_num = id; + m_data_address = data_addr; + m_pc_address = pc_addr; + m_time = time; + m_type = type; + + // Don't differentiate between store misses and atomic requests in + // the trace + if (m_type == CacheRequestType_ATOMIC) { + m_type = CacheRequestType_ST; + } +} + +// Public copy constructor and assignment operator +TraceRecord::TraceRecord(const TraceRecord& obj) +{ + *this = obj; // Call assignment operator +} + +TraceRecord& TraceRecord::operator=(const TraceRecord& obj) +{ + m_node_num = obj.m_node_num; + m_time = obj.m_time; + m_data_address = obj.m_data_address; + m_pc_address = obj.m_pc_address; + m_type = obj.m_type; + return *this; +} + +void TraceRecord::issueRequest() const +{ + // Lookup sequencer pointer from system + // Note that the chip index also needs to take into account SMT configurations + AbstractChip* chip_ptr = g_system_ptr->getChip(m_node_num/RubyConfig::numberOfProcsPerChip()/RubyConfig::numberofSMTThreads()); + assert(chip_ptr != NULL); + Sequencer* sequencer_ptr = chip_ptr->getSequencer((m_node_num/RubyConfig::numberofSMTThreads())%RubyConfig::numberOfProcsPerChip()); + assert(sequencer_ptr != NULL); + + CacheMsg request(m_data_address, m_data_address, m_type, m_pc_address, AccessModeType_UserMode, 0, PrefetchBit_Yes, 0, Address(0), 0 /* only 1 SMT thread */, 0, false); + + // Clear out the sequencer + while (!sequencer_ptr->empty()) { + g_eventQueue_ptr->triggerEvents(g_eventQueue_ptr->getTime() + 100); + } + + sequencer_ptr->makeRequest(request); + + // Clear out the sequencer + while (!sequencer_ptr->empty()) { + g_eventQueue_ptr->triggerEvents(g_eventQueue_ptr->getTime() + 100); + } +} + +void TraceRecord::print(ostream& out) const +{ + out << "[TraceRecord: Node, " << m_node_num << ", " << m_data_address << ", " << m_pc_address << ", " << m_type << ", Time: " << m_time << "]"; +} + +void TraceRecord::output(ostream& out) const +{ + out << m_node_num << " "; + m_data_address.output(out); + out << " "; + m_pc_address.output(out); + out << " "; + out << m_type; + out << endl; +} + +bool TraceRecord::input(istream& in) +{ + in >> m_node_num; + m_data_address.input(in); + m_pc_address.input(in); + string type; + if (!in.eof()) { + in >> type; + m_type = string_to_CacheRequestType(type); + + // Ignore the rest of the line + char c = '\0'; + while ((!in.eof()) && (c != '\n')) { + in.get(c); + } + + return true; + } else { + return false; + } +} diff --git a/src/mem/ruby/recorder/TraceRecord.hh b/src/mem/ruby/recorder/TraceRecord.hh new file mode 100644 index 000000000..df526156b --- /dev/null +++ b/src/mem/ruby/recorder/TraceRecord.hh @@ -0,0 +1,101 @@ + +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * $Id$ + * + * Description: A entry in the cache request record. It is aware of + * the ruby time and can issue the request back to the + * cache. + * + */ + +#ifndef TRACERECORD_H +#define TRACERECORD_H + +#include "Global.hh" +#include "Address.hh" +#include "NodeID.hh" +#include "CacheRequestType.hh" +class CacheMsg; + +class TraceRecord { +public: + // Constructors + TraceRecord(NodeID id, const Address& data_addr, const Address& pc_addr, CacheRequestType type, Time time); + TraceRecord() { m_node_num = 0; m_time = 0; m_type = CacheRequestType_NULL; } + + // Destructor + // ~TraceRecord(); + + // Public copy constructor and assignment operator + TraceRecord(const TraceRecord& obj); + TraceRecord& operator=(const TraceRecord& obj); + + // Public Methods + bool node_less_then_eq(const TraceRecord& rec) const { return (this->m_time <= rec.m_time); } + void issueRequest() const; + + void print(ostream& out) const; + void output(ostream& out) const; + bool input(istream& in); +private: + // Private Methods + + // Data Members (m_ prefix) + NodeID m_node_num; + Time m_time; + Address m_data_address; + Address m_pc_address; + CacheRequestType m_type; +}; + +inline extern bool node_less_then_eq(const TraceRecord& n1, const TraceRecord& n2); + +// Output operator declaration +ostream& operator<<(ostream& out, const TraceRecord& obj); + +// ******************* Definitions ******************* + +inline extern +bool node_less_then_eq(const TraceRecord& n1, const TraceRecord& n2) +{ + return n1.node_less_then_eq(n2); +} + +// Output operator definition +extern inline +ostream& operator<<(ostream& out, const TraceRecord& obj) +{ + obj.print(out); + out << flush; + return out; +} + +#endif //TRACERECORD_H diff --git a/src/mem/ruby/recorder/Tracer.cc b/src/mem/ruby/recorder/Tracer.cc new file mode 100644 index 000000000..2a0acba46 --- /dev/null +++ b/src/mem/ruby/recorder/Tracer.cc @@ -0,0 +1,126 @@ + +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * $Id$ + * + */ + +#include "Tracer.hh" +#include "TraceRecord.hh" +#include "EventQueue.hh" +#include "PrioHeap.hh" +#include "System.hh" + +Tracer::Tracer() +{ + m_enabled = false; +} + +Tracer::~Tracer() +{ +} + +void Tracer::startTrace(string filename) +{ + if (m_enabled) { + stopTrace(); + } + + if (filename != "") { + m_trace_file.open(filename.c_str()); + if (m_trace_file.fail()) { + cout << "Error: error opening file '" << filename << "'" << endl; + cout << "Trace not enabled." << endl; + return; + } + cout << "Request trace enabled to output file '" << filename << "'" << endl; + m_enabled = true; + } +} + +void Tracer::stopTrace() +{ + assert(m_enabled == true); + m_trace_file.close(); + cout << "Request trace file closed." << endl; + m_enabled = false; +} + +void Tracer::traceRequest(NodeID id, const Address& data_addr, const Address& pc_addr, CacheRequestType type, Time time) +{ + assert(m_enabled == true); + TraceRecord tr(id, data_addr, pc_addr, type, time); + tr.output(m_trace_file); +} + +// Class method +int Tracer::playbackTrace(string filename) +{ + igzstream in(filename.c_str()); + if (in.fail()) { + cout << "Error: error opening file '" << filename << "'" << endl; + return 0; + } + + time_t start_time = time(NULL); + + TraceRecord record; + int counter = 0; + // Read in the next TraceRecord + bool ok = record.input(in); + while (ok) { + // Put it in the right cache + record.issueRequest(); + counter++; + + // Read in the next TraceRecord + ok = record.input(in); + + // Clear the statistics after warmup + if (counter == g_trace_warmup_length) { + cout << "Clearing stats after warmup of length " << g_trace_warmup_length << endl; + g_system_ptr->clearStats(); + } + } + + // Flush the prefetches through the system + g_eventQueue_ptr->triggerEvents(g_eventQueue_ptr->getTime() + 1000); // FIXME - should be smarter + + time_t stop_time = time(NULL); + double seconds = difftime(stop_time, start_time); + double minutes = seconds / 60.0; + cout << "playbackTrace: " << minutes << " minutes" << endl; + + return counter; +} + +void Tracer::print(ostream& out) const +{ +} diff --git a/src/mem/ruby/recorder/Tracer.hh b/src/mem/ruby/recorder/Tracer.hh new file mode 100644 index 000000000..eb05ae12d --- /dev/null +++ b/src/mem/ruby/recorder/Tracer.hh @@ -0,0 +1,94 @@ + +/* + * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * $Id$ + * + * Description: Controller class of the tracer. Can stop/start/playback + * the ruby cache requests trace. + * + */ + +#ifndef TRACER_H +#define TRACER_H + +#include "Global.hh" +#include "NodeID.hh" +#include "CacheRequestType.hh" +#include "gzstream.hh" + +template <class TYPE> class PrioHeap; +class Address; +class TraceRecord; + +class Tracer { +public: + // Constructors + Tracer(); + + // Destructor + ~Tracer(); + + // Public Methods + void startTrace(string filename); + void stopTrace(); + bool traceEnabled() { return m_enabled; } + void traceRequest(NodeID id, const Address& data_addr, const Address& pc_addr, CacheRequestType type, Time time); + + void print(ostream& out) const; + + // Public Class Methods + static int playbackTrace(string filename); +private: + // Private Methods + + // Private copy constructor and assignment operator + Tracer(const Tracer& obj); + Tracer& operator=(const Tracer& obj); + + // Data Members (m_ prefix) + ogzstream m_trace_file; + bool m_enabled; +}; + +// Output operator declaration +ostream& operator<<(ostream& out, const Tracer& obj); + +// ******************* Definitions ******************* + +// Output operator definition +extern inline +ostream& operator<<(ostream& out, const Tracer& obj) +{ + obj.print(out); + out << flush; + return out; +} + +#endif //TRACER_H |