50c50
< p->delay_var, p->fabric_speed);
---
> p->delay_var, p->fabric_speed, i);
74a75,125
> bool
> EtherSwitch::Interface::PortFifo::push(EthPacketPtr ptr, unsigned senderId)
> {
> assert(ptr->length);
>
> _size += ptr->length;
> fifo.emplace_hint(fifo.end(), ptr, curTick(), senderId);
>
> // Drop the extra pushed packets from end of the fifo
> while (avail() < 0) {
> DPRINTF(Ethernet, "Fifo is full. Drop packet: len=%d\n",
> std::prev(fifo.end())->packet->length);
>
> _size -= std::prev(fifo.end())->packet->length;
> fifo.erase(std::prev(fifo.end()));
> }
>
> if (empty()) {
> warn("EtherSwitch: Packet length (%d) exceeds the maximum storage "
> "capacity of port fifo (%d)", ptr->length, _maxsize);
> }
>
> // Return true if the newly pushed packet gets inserted
> // at the head of the queue, otherwise return false
> // We need this information to deschedule the event that has been
> // scheduled for the old head of queue packet and schedule a new one
> if (!empty() && fifo.begin()->packet == ptr) {
> return true;
> }
> return false;
> }
>
> void
> EtherSwitch::Interface::PortFifo::pop()
> {
> if (empty())
> return;
>
> assert(_size >= fifo.begin()->packet->length);
> // Erase the packet at the head of the queue
> _size -= fifo.begin()->packet->length;
> fifo.erase(fifo.begin());
> }
>
> void
> EtherSwitch::Interface::PortFifo::clear()
> {
> fifo.clear();
> _size = 0;
> }
>
78c129
< Tick delay_var, double rate)
---
> Tick delay_var, double rate, unsigned id)
80,81c131,132
< delayVar(delay_var), parent(etherSwitch),
< outputFifo(outputBufferSize), txEvent(this)
---
> delayVar(delay_var), interfaceId(id), parent(etherSwitch),
> outputFifo(name + ".outputFifo", outputBufferSize), txEvent(this)
97c148
< it->enqueue(packet);
---
> it->enqueue(packet, interfaceId);
103c154
< receiver->enqueue(packet);
---
> receiver->enqueue(packet, interfaceId);
113c164
< EtherSwitch::Interface::enqueue(EthPacketPtr packet)
---
> EtherSwitch::Interface::enqueue(EthPacketPtr packet, unsigned senderId)
115,120d165
< if (!outputFifo.push(packet)) {
< // output buffer full, drop packet
< DPRINTF(Ethernet, "output buffer full, drop packet\n");
< return;
< }
<
122,124c167,172
< // if there was nothing in the Fifo before push the
< // current packet, then we need to schedule an event at
< // curTick + switchingDelay to send this packet out the external link
---
> // if the newly push packet gets inserted at the head of the queue
> // (either there was nothing in the queue or the priority of the new
> // packet was higher than the packets already in the fifo)
> // then we need to schedule an event at
> // "curTick" + "switchingDelay of the packet at the head of the fifo"
> // to send this packet out the external link
126,127c174,175
< if (!txEvent.scheduled()) {
< parent->schedule(txEvent, curTick() + switchingDelay());
---
> if (outputFifo.push(packet, senderId)) {
> parent->reschedule(txEvent, curTick() + switchingDelay());
214c262,263
< it->serialize(it->name(), cp);
---
> it->serializeSection(cp, it->name());
>
221c270,271
< it->unserialize(it->name(), cp);
---
> it->unserializeSection(cp, it->name());
>
225,226c275
< EtherSwitch::Interface::serialize(const std::string &base, CheckpointOut &cp)
< const
---
> EtherSwitch::Interface::serialize(CheckpointOut &cp) const
229c278,279
< paramOut(cp, base + ".event_scheduled", event_scheduled);
---
> SERIALIZE_SCALAR(event_scheduled);
>
232c282
< paramOut(cp, base + ".event_time", event_time);
---
> SERIALIZE_SCALAR(event_time);
234,235c284
<
< outputFifo.serialize(base + "outputFifo", cp);
---
> outputFifo.serializeSection(cp, "outputFifo");
239c288
< EtherSwitch::Interface::unserialize(const std::string &base, CheckpointIn &cp)
---
> EtherSwitch::Interface::unserialize(CheckpointIn &cp)
242c291,292
< paramIn(cp, base + ".event_scheduled", event_scheduled);
---
> UNSERIALIZE_SCALAR(event_scheduled);
>
245c295
< paramIn(cp, base + ".event_time", event_time);
---
> UNSERIALIZE_SCALAR(event_time);
247a298,299
> outputFifo.unserializeSection(cp, "outputFifo");
> }
249c301,306
< outputFifo.unserialize(base + "outputFifo", cp);
---
> void
> EtherSwitch::Interface::PortFifoEntry::serialize(CheckpointOut &cp) const
> {
> packet->serialize("packet", cp);
> SERIALIZE_SCALAR(recvTick);
> SERIALIZE_SCALAR(srcId);
251a309,349
> void
> EtherSwitch::Interface::PortFifoEntry::unserialize(CheckpointIn &cp)
> {
> packet = make_shared<EthPacketData>(16384);
> packet->unserialize("packet", cp);
> UNSERIALIZE_SCALAR(recvTick);
> UNSERIALIZE_SCALAR(srcId);
> }
>
> void
> EtherSwitch::Interface::PortFifo::serialize(CheckpointOut &cp) const
> {
> SERIALIZE_SCALAR(_size);
> int fifosize = fifo.size();
>
> SERIALIZE_SCALAR(fifosize);
>
> int i = 0;
> for (const auto &entry : fifo)
> entry.serializeSection(cp, csprintf("entry%d", i++));
> }
>
> void
> EtherSwitch::Interface::PortFifo::unserialize(CheckpointIn &cp)
> {
> UNSERIALIZE_SCALAR(_size);
> int fifosize;
>
> UNSERIALIZE_SCALAR(fifosize);
> fifo.clear();
>
> for (int i = 0; i < fifosize; ++i) {
> PortFifoEntry entry(nullptr, 0, 0);
>
> entry.unserializeSection(cp, csprintf("entry%d", i));
>
> fifo.insert(entry);
>
> }
> }
>