}
packet = pkt;
- Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0);
+ Tick delay = (Tick)ceil(((double)pkt->simLength * ticksPerByte) + 1.0);
if (delayVar != 0)
delay += random_mt.random<Tick>(0, delayVar);
bool packet_exists;
UNSERIALIZE_SCALAR(packet_exists);
if (packet_exists) {
- packet = make_shared<EthPacketData>(16384);
+ packet = make_shared<EthPacketData>();
packet->unserialize("packet", cp);
}
Desc d = descQueue.front();
descQueue.pop();
d.sendTick = curTick();
- d.sendDelay = d.packet->size(); // assume 1 tick/byte max link speed
+ d.sendDelay = d.packet->simLength; // assume 1 tick/byte max link speed
v.push_back(d);
}
{
UNSERIALIZE_SCALAR(sendTick);
UNSERIALIZE_SCALAR(sendDelay);
- packet = std::make_shared<EthPacketData>(16384);
+ packet = std::make_shared<EthPacketData>();
packet->unserialize("rxPacket", cp);
}
header.sendTick = curTick();
header.sendDelay = send_delay;
- header.dataPacketLength = pkt->size();
+ header.dataPacketLength = pkt->length;
+ header.simLength = pkt->simLength;
// Send out the packet and the meta info.
sendPacket(header, pkt);
DPRINTF(DistEthernetPkt,
"DistIface::sendDataPacket() done size:%d send_delay:%llu\n",
- pkt->size(), send_delay);
+ pkt->length, send_delay);
}
void
*/
MsgType msgType;
Tick sendTick;
+ /**
+ * Length used for modeling timing in the simulator.
+ * (from EthPacketData::simLength).
+ */
+ unsigned simLength;
union {
Tick sendDelay;
Tick syncRepeat;
union {
/**
* Actual length of the simulated Ethernet packet.
+ * (from EthPacketData::length).
*/
unsigned dataPacketLength;
struct {
packet = pkt;
sender = sndr;
- int delay = (int)ceil(((double)pkt->length * ticksPerByte) + 1.0);
+ int delay = (int)ceil(((double)pkt->simLength * ticksPerByte) + 1.0);
DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
delay, ticksPerByte);
schedule(event, curTick() + delay);
DDUMP(EthernetData, pkt->data, pkt->length);
packet = pkt;
- Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0);
+ Tick delay = (Tick)ceil(((double)pkt->simLength * ticksPerByte) + 1.0);
if (delayVar != 0)
delay += random_mt.random<Tick>(0, delayVar);
bool packet_exists;
paramIn(cp, base + ".packet_exists", packet_exists);
if (packet_exists) {
- packet = make_shared<EthPacketData>(16384);
+ packet = make_shared<EthPacketData>();
packet->unserialize(base + ".packet", cp);
}
if (optParamIn(cp, base + ".tx_queue_size", tx_queue_size)) {
for (size_t idx = 0; idx < tx_queue_size; ++idx) {
Tick tick;
- EthPacketPtr delayed_packet = make_shared<EthPacketData>(16384);
+ EthPacketPtr delayed_packet = make_shared<EthPacketData>();
paramIn(cp, csprintf("%s.txQueue[%i].tick", base, idx), tick);
delayed_packet->unserialize(
void
EthPacketData::serialize(const string &base, CheckpointOut &cp) const
{
+ paramOut(cp, base + ".simLength", simLength);
paramOut(cp, base + ".length", length);
arrayParamOut(cp, base + ".data", data, length);
}
EthPacketData::unserialize(const string &base, CheckpointIn &cp)
{
paramIn(cp, base + ".length", length);
- if (length)
+ if (length) {
+ assert(data == nullptr);
+ data = new uint8_t[length];
arrayParamIn(cp, base + ".data", data, length);
+ }
+ if (!optParamIn(cp, base + ".simLength", simLength))
+ simLength = length;
}
class EthPacketData
{
public:
- /*
+ /**
* Pointer to packet data will be deleted
*/
uint8_t *data;
- /*
- * Length of the current packet
+ /**
+ * Amount of space occupied by the payload in the data buffer
*/
unsigned length;
- public:
+ /**
+ * Effective length, used for modeling timing in the simulator.
+ * This could be different from length if the packets are assumed
+ * to use a tightly packed or compressed format, but it's not worth
+ * the performance/complexity hit to perform that packing or compression
+ * in the simulation.
+ */
+ unsigned simLength;
+
EthPacketData()
- : data(NULL), length(0)
+ : data(nullptr), length(0), simLength(0)
{ }
explicit EthPacketData(unsigned size)
- : data(new uint8_t[size]), length(0)
+ : data(new uint8_t[size]), length(0), simLength(0)
{ }
~EthPacketData() { if (data) delete [] data; }
- public:
-
void serialize(const std::string &base, CheckpointOut &cp) const;
void unserialize(const std::string &base, CheckpointIn &cp);
-
- unsigned size() const { return length; }
};
typedef std::shared_ptr<EthPacketData> EthPacketPtr;
Tick
EtherSwitch::Interface::switchingDelay()
{
- Tick delay = (Tick)ceil(((double)outputFifo.front()->length
+ Tick delay = (Tick)ceil(((double)outputFifo.front()->simLength
* ticksPerByte) + 1.0);
if (delayVar != 0)
delay += random_mt.random<Tick>(0, delayVar);
EthPacketPtr packet;
packet = make_shared<EthPacketData>(data_len);
packet->length = data_len;
+ packet->simLength = data_len;
memcpy(packet->data, data, data_len);
assert(buffer_offset >= data_len + sizeof(uint32_t));
DPRINTF(EthernetDesc, "TSO: use: %d hdrlen: %d mss: %d total: %d "
"used: %d loaded hdr: %d\n", useTso, tsoHeaderLen, tsoMss,
tsoTotalLen, tsoUsedLen, tsoLoadedHeader);
+ pktPtr->simLength += tsoCopyBytes;
pktPtr->length += tsoCopyBytes;
tsoUsedLen += tsoCopyBytes;
DPRINTF(EthernetDesc, "TSO: descBytesUsed: %d copyBytes: %d\n",
tsoDescBytesUsed, tsoCopyBytes);
- } else
+ } else {
+ pktPtr->simLength += TxdOp::getLen(desc);
pktPtr->length += TxdOp::getLen(desc);
+ }
bool txPktExists;
UNSERIALIZE_SCALAR(txPktExists);
if (txPktExists) {
- txPacket = std::make_shared<EthPacketData>(16384);
+ txPacket = std::make_shared<EthPacketData>();
txPacket->unserialize("txpacket", cp);
}
}
}
+ txPacket->simLength = txPacketBufPtr - txPacket->data;
txPacket->length = txPacketBufPtr - txPacket->data;
// this is just because the receive can't handle a
// packet bigger want to make sure
bool txPacketExists = txPacket != nullptr;
SERIALIZE_SCALAR(txPacketExists);
if (txPacketExists) {
+ txPacket->simLength = txPacketBufPtr - txPacket->data;
txPacket->length = txPacketBufPtr - txPacket->data;
txPacket->serialize("txPacket", cp);
uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data);
bool txPacketExists;
UNSERIALIZE_SCALAR(txPacketExists);
if (txPacketExists) {
- txPacket = make_shared<EthPacketData>(16384);
+ txPacket = make_shared<EthPacketData>();
txPacket->unserialize("txPacket", cp);
uint32_t txPktBufPtr;
UNSERIALIZE_SCALAR(txPktBufPtr);
UNSERIALIZE_SCALAR(rxPacketExists);
rxPacket = 0;
if (rxPacketExists) {
- rxPacket = make_shared<EthPacketData>(16384);
+ rxPacket = make_shared<EthPacketData>();
rxPacket->unserialize("rxPacket", cp);
uint32_t rxPktBufPtr;
UNSERIALIZE_SCALAR(rxPktBufPtr);
void
PacketFifoEntry::unserialize(const string &base, CheckpointIn &cp)
{
- packet = make_shared<EthPacketData>(16384);
+ packet = make_shared<EthPacketData>();
packet->unserialize(base + ".packet", cp);
paramIn(cp, base + ".slack", slack);
paramIn(cp, base + ".number", number);
case txCopyDone:
vnic->TxDone = txDmaLen | Regs::TxDone_Complete;
+ txPacket->simLength += txDmaLen;
txPacket->length += txDmaLen;
if ((vnic->TxData & Regs::TxData_More)) {
txPacketOffset += txDmaLen;
UNSERIALIZE_SCALAR(txPacketExists);
txPacket = 0;
if (txPacketExists) {
- txPacket = make_shared<EthPacketData>(16384);
+ txPacket = make_shared<EthPacketData>();
txPacket->unserialize("txPacket", cp);
UNSERIALIZE_SCALAR(txPacketOffset);
UNSERIALIZE_SCALAR(txPacketBytes);
packet = make_shared<EthPacketData>(header.dataPacketLength);
bool ret = recvTCP(sock, packet->data, header.dataPacketLength);
panic_if(!ret, "Error while reading socket");
+ packet->simLength = header.simLength;
packet->length = header.dataPacketLength;
}