gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
packet_queue.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012,2015 ARM Limited
3  * All rights reserved.
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2006 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * Authors: Ali Saidi
41  * Andreas Hansson
42  */
43 
44 #include "mem/packet_queue.hh"
45 
46 #include "base/trace.hh"
47 #include "debug/Drain.hh"
48 #include "debug/PacketQueue.hh"
49 
50 using namespace std;
51 
52 PacketQueue::PacketQueue(EventManager& _em, const std::string& _label,
53  bool disable_sanity_check)
54  : em(_em), sendEvent(this), _disableSanityCheck(disable_sanity_check),
55  label(_label), waitingOnRetry(false)
56 {
57 }
58 
60 {
61 }
62 
63 void
65 {
66  DPRINTF(PacketQueue, "Queue %s received retry\n", name());
67  assert(waitingOnRetry);
68  waitingOnRetry = false;
70 }
71 
72 bool
74 {
75  // caller is responsible for ensuring that all packets have the
76  // same alignment
77  for (const auto& p : transmitList) {
78  if (p.pkt->getAddr() == addr)
79  return true;
80  }
81  return false;
82 }
83 
84 bool
86 {
87  pkt->pushLabel(label);
88 
89  auto i = transmitList.begin();
90  bool found = false;
91 
92  while (!found && i != transmitList.end()) {
93  // If the buffered packet contains data, and it overlaps the
94  // current packet, then update data
95  found = pkt->checkFunctional(i->pkt);
96  ++i;
97  }
98 
99  pkt->popLabel();
100 
101  return found;
102 }
103 
104 void
105 PacketQueue::schedSendTiming(PacketPtr pkt, Tick when, bool force_order)
106 {
107  DPRINTF(PacketQueue, "%s for %s address %x size %d when %lu ord: %i\n",
108  __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize(), when,
109  force_order);
110 
111  // we can still send a packet before the end of this tick
112  assert(when >= curTick());
113 
114  // express snoops should never be queued
115  assert(!pkt->isExpressSnoop());
116 
117  // add a very basic sanity check on the port to ensure the
118  // invisible buffer is not growing beyond reasonable limits
119  if (!_disableSanityCheck && transmitList.size() > 100) {
120  panic("Packet queue %s has grown beyond 100 packets\n",
121  name());
122  }
123 
124  // nothing on the list
125  if (transmitList.empty()) {
126  transmitList.emplace_front(when, pkt);
127  schedSendEvent(when);
128  return;
129  }
130 
131  // we should either have an outstanding retry, or a send event
132  // scheduled, but there is an unfortunate corner case where the
133  // x86 page-table walker and timing CPU send out a new request as
134  // part of the receiving of a response (called by
135  // PacketQueue::sendDeferredPacket), in which we end up calling
136  // ourselves again before we had a chance to update waitingOnRetry
137  // assert(waitingOnRetry || sendEvent.scheduled());
138 
139  // this belongs in the middle somewhere, so search from the end to
140  // order by tick; however, if force_order is set, also make sure
141  // not to re-order in front of some existing packet with the same
142  // address
143  auto i = transmitList.end();
144  --i;
145  while (i != transmitList.begin() && when < i->tick &&
146  !(force_order && i->pkt->getAddr() == pkt->getAddr()))
147  --i;
148 
149  // emplace inserts the element before the position pointed to by
150  // the iterator, so advance it one step
151  transmitList.emplace(++i, when, pkt);
152 }
153 
154 void
156 {
157  // if we are waiting on a retry just hold off
158  if (waitingOnRetry) {
159  DPRINTF(PacketQueue, "Not scheduling send as waiting for retry\n");
160  assert(!sendEvent.scheduled());
161  return;
162  }
163 
164  if (when != MaxTick) {
165  // we cannot go back in time, and to be consistent we stick to
166  // one tick in the future
167  when = std::max(when, curTick() + 1);
168  // @todo Revisit the +1
169 
170  if (!sendEvent.scheduled()) {
171  em.schedule(&sendEvent, when);
172  } else if (when < sendEvent.when()) {
173  // if the new time is earlier than when the event
174  // currently is scheduled, move it forward
175  em.reschedule(&sendEvent, when);
176  }
177  } else {
178  // we get a MaxTick when there is no more to send, so if we're
179  // draining, we may be done at this point
180  if (drainState() == DrainState::Draining &&
181  transmitList.empty() && !sendEvent.scheduled()) {
182 
183  DPRINTF(Drain, "PacketQueue done draining,"
184  "processing drain event\n");
185  signalDrainDone();
186  }
187  }
188 }
189 
190 void
192 {
193  // sanity checks
194  assert(!waitingOnRetry);
195  assert(deferredPacketReady());
196 
197  DeferredPacket dp = transmitList.front();
198 
199  // take the packet of the list before sending it, as sending of
200  // the packet in some cases causes a new packet to be enqueued
201  // (most notaly when responding to the timing CPU, leading to a
202  // new request hitting in the L1 icache, leading to a new
203  // response)
204  transmitList.pop_front();
205 
206  // use the appropriate implementation of sendTiming based on the
207  // type of queue
209 
210  // if we succeeded and are not waiting for a retry, schedule the
211  // next send
212  if (!waitingOnRetry) {
214  } else {
215  // put the packet back at the front of the list
216  transmitList.emplace_front(dp);
217  }
218 }
219 
220 void
222 {
223  assert(!waitingOnRetry);
225 }
226 
229 {
230  if (transmitList.empty()) {
231  return DrainState::Drained;
232  } else {
233  DPRINTF(Drain, "PacketQueue not drained\n");
234  return DrainState::Draining;
235  }
236 }
237 
239  const std::string _label)
240  : PacketQueue(_em, _label), masterPort(_masterPort)
241 {
242 }
243 
244 bool
246 {
247  return masterPort.sendTimingReq(pkt);
248 }
249 
251  MasterPort& _masterPort,
252  const std::string _label)
253  : PacketQueue(_em, _label), masterPort(_masterPort)
254 {
255 }
256 
257 bool
259 {
260  return masterPort.sendTimingSnoopResp(pkt);
261 }
262 
264  const std::string _label)
265  : PacketQueue(_em, _label), slavePort(_slavePort)
266 {
267 }
268 
269 bool
271 {
272  return slavePort.sendTimingResp(pkt);
273 }
A MasterPort is a specialisation of a BaseMasterPort, which implements the default protocol for the t...
Definition: port.hh:167
#define DPRINTF(x,...)
Definition: trace.hh:212
DrainState drain() override
Notify an object that it needs to drain its state.
RespPacketQueue(EventManager &_em, SlavePort &_slavePort, const std::string _label="RespPacketQueue")
Create a response packet queue, linked to an event manager, a slave port, and a label that will be us...
void retry()
Retry sending a packet from the queue.
Definition: packet_queue.cc:64
bool hasAddr(Addr addr) const
Check if a packets address exists in the queue.
Definition: packet_queue.cc:73
PacketPtr pkt
Pointer to the packet to transmit.
Definition: packet_queue.hh:72
Declaration of a simple PacketQueue that is associated with a port on which it attempts to send packe...
void schedSendTiming(PacketPtr pkt, Tick when, bool force_order=false)
Add a packet to the transmit list, and schedule a send event.
EventWrapper< PacketQueue,&PacketQueue::processSendEvent > sendEvent
Event used to call processSendEvent.
Definition: packet_queue.hh:90
Bitfield< 7 > i
Definition: miscregs.hh:1378
DrainState
Object drain/handover states.
Definition: drain.hh:71
#define panic(...)
Definition: misc.hh:153
Running normally.
bool _disableSanityCheck
Definition: packet_queue.hh:97
bool waitingOnRetry
Remember whether we're awaiting a retry.
bool sendTimingSnoopResp(PacketPtr pkt)
Attempt to send a timing snoop response packet to the slave port by calling its corresponding receive...
Definition: port.cc:187
bool isExpressSnoop() const
Definition: packet.hh:601
ip6_addr_t addr
Definition: inet.hh:335
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:381
Bitfield< 2 > em
Definition: misc.hh:603
A deferred packet, buffered to transmit later.
Definition: packet_queue.hh:69
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the slave port by calling its corresponding receive function...
Definition: port.cc:180
A SlavePort is a specialisation of a port.
Definition: port.hh:331
void schedSendEvent(Tick when)
Schedule a send event if we are not already waiting for a retry.
ReqPacketQueue(EventManager &_em, MasterPort &_masterPort, const std::string _label="ReqPacketQueue")
Create a request packet queue, linked to an event manager, a master port, and a label that will be us...
void pushLabel(const std::string &lbl)
Push label for PrintReq (safe to call unconditionally).
Definition: packet.hh:1160
bool deferredPacketReady() const
Check whether we have a packet ready to go on the transmit list.
MasterPort & masterPort
const Tick MaxTick
Definition: types.hh:65
bool sendTimingResp(PacketPtr pkt)
Attempt to send a timing response to the master port by calling its corresponding receive function...
Definition: port.cc:251
Tick curTick()
The current simulated tick.
Definition: core.hh:47
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:397
SlavePort & slavePort
uint64_t Tick
Tick count type.
Definition: types.hh:63
virtual bool sendTiming(PacketPtr pkt)=0
Send a packet using the appropriate method for the specific subclass (reuest, response or snoop respo...
EventManager & em
The manager which is used for the event queue.
Definition: packet_queue.hh:84
void popLabel()
Pop label for PrintReq (safe to call unconditionally).
Definition: packet.hh:1170
Tick deferredPacketReadyTime() const
Get the next packet ready time.
bool sendTiming(PacketPtr pkt)
Send a packet using the appropriate method for the specific subclass (reuest, response or snoop respo...
bool checkFunctional(PacketPtr pkt)
Check the list of buffered packets against the supplied functional request.
Definition: packet_queue.cc:85
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Draining buffers pending serialization/handover.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
bool sendTiming(PacketPtr pkt)
Send a packet using the appropriate method for the specific subclass (reuest, response or snoop respo...
bool checkFunctional(PacketPtr other)
Check a functional request against a memory value stored in another packet (i.e.
Definition: packet.hh:1115
void reschedule(Event &event, Tick when, bool always=false)
Definition: eventq.hh:740
A packet queue is a class that holds deferred packets and later sends them using the associated slave...
Definition: packet_queue.hh:65
MasterPort & masterPort
void processSendEvent()
Used to schedule sending of deferred packets.
virtual ~PacketQueue()
Virtual desctructor since the class may be used as a base class.
Definition: packet_queue.cc:59
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition: packet.hh:497
virtual const std::string name() const =0
Provide a name to simplify debugging.
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:267
void schedule(Event &event, Tick when)
Definition: eventq.hh:728
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:282
DeferredPacketList transmitList
A list of outgoing packets.
Definition: packet_queue.hh:81
unsigned getSize() const
Definition: packet.hh:649
bool sendTiming(PacketPtr pkt)
Send a packet using the appropriate method for the specific subclass (reuest, response or snoop respo...
Bitfield< 0 > p
SnoopRespPacketQueue(EventManager &_em, MasterPort &_masterPort, const std::string _label="SnoopRespPacketQueue")
Create a snoop response packet queue, linked to an event manager, a master port, and a label that wil...
PacketQueue(EventManager &_em, const std::string &_label, bool disable_sanity_check=false)
Create a packet queue, linked to an event manager, and a label that will be used for functional print...
Definition: packet_queue.cc:52
virtual void sendDeferredPacket()
Attempt to send a packet.
Addr getAddr() const
Definition: packet.hh:639
const std::string label
Label to use for print request packets label stack.

Generated on Fri Jun 9 2017 13:03:49 for gem5 by doxygen 1.8.6