X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fcomm_monitor.cc;h=d21741b205de0d5d5d5e0e6817e3e7cb28f31a14;hb=d2fd3b2ec2c265eb9ed3bdcc1db3e4c3feee3846;hp=aea0286928f0841aafd81fb726952ac92420fd62;hpb=2a740aa09682c32eb8f1f8880f279c943d8c6ee1;p=gem5.git diff --git a/src/mem/comm_monitor.cc b/src/mem/comm_monitor.cc index aea028692..d21741b20 100644 --- a/src/mem/comm_monitor.cc +++ b/src/mem/comm_monitor.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 ARM Limited + * Copyright (c) 2012-2013 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -38,8 +38,12 @@ * Andreas Hansson */ +#include "base/callback.hh" +#include "base/output.hh" +#include "base/trace.hh" #include "debug/CommMonitor.hh" #include "mem/comm_monitor.hh" +#include "proto/packet.pb.h" #include "sim/stats.hh" CommMonitor::CommMonitor(Params* params) @@ -50,8 +54,31 @@ CommMonitor::CommMonitor(Params* params) samplePeriodTicks(params->sample_period), readAddrMask(params->read_addr_mask), writeAddrMask(params->write_addr_mask), - stats(params) + stats(params), + traceStream(NULL) { + // If we are using a trace file, then open the file, + if (params->trace_file != "") { + // If the trace file is not specified as an absolute path, + // append the current simulation output directory + std::string filename = simout.resolve(params->trace_file); + traceStream = new ProtoOutputStream(filename); + + // Create a protobuf message for the header and write it to + // the stream + Message::PacketHeader header_msg; + header_msg.set_obj_id(name()); + header_msg.set_tick_freq(SimClock::Frequency); + traceStream->write(header_msg); + + // Register a callback to compensate for the destructor not + // being called. The callback forces the stream to flush and + // closes the output file. + Callback* cb = new MakeCallback(this); + registerExitCallback(cb); + } + // keep track of the sample period both in ticks and absolute time samplePeriod.setTick(params->sample_period); @@ -60,6 +87,13 @@ CommMonitor::CommMonitor(Params* params) name(), samplePeriodTicks, samplePeriod); } +void +CommMonitor::closeStreams() +{ + if (traceStream != NULL) + delete traceStream; +} + CommMonitor* CommMonitorParams::create() { @@ -128,19 +162,19 @@ CommMonitor::recvTimingReq(PacketPtr pkt) // or even deleted when sendTiming() is called. bool isRead = pkt->isRead(); bool isWrite = pkt->isWrite(); + int cmd = pkt->cmdToIndex(); + Request::FlagsType req_flags = pkt->req->getFlags(); unsigned size = pkt->getSize(); Addr addr = pkt->getAddr(); bool needsResponse = pkt->needsResponse(); bool memInhibitAsserted = pkt->memInhibitAsserted(); - Packet::SenderState* senderState = pkt->senderState; // If a cache miss is served by a cache, a monitor near the memory // would see a request which needs a response, but this response // would be inhibited and not come back from the memory. Therefore // we additionally have to check the inhibit flag. if (needsResponse && !memInhibitAsserted && !stats.disableLatencyHists) { - pkt->senderState = new CommMonitorSenderState(senderState, - curTick()); + pkt->pushSenderState(new CommMonitorSenderState(curTick())); } // Attempt to send the packet (always succeeds for inhibited @@ -149,8 +183,21 @@ CommMonitor::recvTimingReq(PacketPtr pkt) // If not successful, restore the sender state if (!successful && needsResponse && !stats.disableLatencyHists) { - delete pkt->senderState; - pkt->senderState = senderState; + delete pkt->popSenderState(); + } + + if (successful && traceStream != NULL) { + // Create a protobuf message representing the + // packet. Currently we do not preserve the flags in the + // trace. + Message::Packet pkt_msg; + pkt_msg.set_tick(curTick()); + pkt_msg.set_cmd(cmd); + pkt_msg.set_flags(req_flags); + pkt_msg.set_addr(addr); + pkt_msg.set_size(size); + + traceStream->write(pkt_msg); } if (successful && isRead) { @@ -258,7 +305,7 @@ CommMonitor::recvTimingResp(PacketPtr pkt) panic("Monitor got a response without monitor sender state\n"); // Restore the sate - pkt->senderState = commReceivedState->origSenderState; + pkt->senderState = commReceivedState->predecessor; } // Attempt to send the packet