3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include "mem/ruby/recorder/Tracer.hh"
36 #include "mem/ruby/recorder/TraceRecord.hh"
37 #include "mem/ruby/eventqueue/RubyEventQueue.hh"
38 #include "mem/gems_common/PrioHeap.hh"
39 #include "mem/ruby/system/System.hh"
40 #include "mem/ruby/config/RubyConfig.hh"
43 Tracer::Tracer(const string
& name
)
59 void Tracer::init(const vector
<string
> & argv
)
63 for (size_t i
=0; i
<argv
.size(); i
+=2) {
64 if ( argv
[i
] == "warmup_length") {
65 m_warmup_length
= atoi(argv
[i
+1].c_str());
68 cerr
<< "WARNING: Tracer: Unkown configuration parameter: " << argv
[i
] << endl
;
72 assert(m_warmup_length
> 0);
75 void Tracer::startTrace(string filename
)
82 m_trace_file
.open(filename
.c_str());
83 if (m_trace_file
.fail()) {
84 cout
<< "Error: error opening file '" << filename
<< "'" << endl
;
85 cout
<< "Trace not enabled." << endl
;
88 cout
<< "Request trace enabled to output file '" << filename
<< "'" << endl
;
93 void Tracer::stopTrace()
95 if (m_enabled
== true) {
97 cout
<< "Request trace file closed." << endl
;
102 void Tracer::traceRequest(const string
& sequencer_name
, const Address
& data_addr
, const Address
& pc_addr
, RubyRequestType type
, Time time
)
104 assert(m_enabled
== true);
105 TraceRecord
tr(sequencer_name
, data_addr
, pc_addr
, type
, time
);
106 tr
.output(m_trace_file
);
110 int Tracer::playbackTrace(string filename
)
112 igzstream
in(filename
.c_str());
114 cout
<< "Error: error opening file '" << filename
<< "'" << endl
;
118 time_t start_time
= time(NULL
);
122 // Read in the next TraceRecord
123 bool ok
= record
.input(in
);
125 // Put it in the right cache
126 record
.issueRequest();
129 // Read in the next TraceRecord
130 ok
= record
.input(in
);
132 // Clear the statistics after warmup
133 /* if (counter == RubyConfig::getTraceWarmupLength()) {
134 cout << "Clearing stats after warmup of length " << RubyConfig::getTraceWarmupLength() << endl;
135 g_system_ptr->clearStats();
138 if (counter
== m_warmup_length
) {
139 cout
<< "Clearing stats after warmup of length " << m_warmup_length
<< endl
;
140 g_system_ptr
->clearStats();
145 // Flush the prefetches through the system
146 g_eventQueue_ptr
->triggerEvents(g_eventQueue_ptr
->getTime() + 1000); // FIXME - should be smarter
148 time_t stop_time
= time(NULL
);
149 double seconds
= difftime(stop_time
, start_time
);
150 double minutes
= seconds
/ 60.0;
151 cout
<< "playbackTrace: " << minutes
<< " minutes" << endl
;
156 void Tracer::print(ostream
& out
) const