network: (merges !424) Fix instant send in SimpleNetDevice for empty queue

Also consolidate scheduling logic into ScheduleTransmit() rather than
repeating in both SendFrom() and TransmitComplete()
This commit is contained in:
Greg Steinbrecher
2020-09-25 12:16:53 -07:00
committed by Tom Henderson
parent b90d4dee6d
commit a77e4d39b2
2 changed files with 37 additions and 28 deletions

View File

@@ -446,39 +446,51 @@ SimpleNetDevice::SendFrom (Ptr<Packet> p, const Address& source, const Address&
if (m_queue->Enqueue (p))
{
if (m_queue->GetNPackets () == 1 && !TransmitCompleteEvent.IsRunning ())
if (m_queue->GetNPackets () == 1 && !FinishTransmissionEvent.IsRunning ())
{
p = m_queue->Dequeue ();
p->RemovePacketTag (tag);
Time txTime = Time (0);
if (m_bps > DataRate (0))
{
txTime = m_bps.CalculateBytesTxTime (packet->GetSize ());
}
m_channel->Send (p, protocolNumber, to, from, this);
TransmitCompleteEvent = Simulator::Schedule (txTime, &SimpleNetDevice::TransmitComplete, this);
StartTransmission();
}
return true;
}
m_channel->Send (packet, protocolNumber, to, from, this);
return true;
return false;
}
void
SimpleNetDevice::TransmitComplete ()
SimpleNetDevice::StartTransmission ()
{
NS_LOG_FUNCTION (this);
if (m_queue->GetNPackets () == 0)
{
return;
}
NS_ASSERT_MSG (!FinishTransmissionEvent.IsRunning (),
"Tried to transmit a packet while another transmission was in progress");
Ptr<Packet> packet = m_queue->Dequeue ();
/**
* SimpleChannel will deliver the packet to the far end(s) of the link as soon as Send is called
* (or after its fixed delay, if one is configured). So we have to handle the rate of the link here,
* which we do by scheudling FinishTransmission (packetSize / linkRate) time in the future. While
* that event is running, the transmit path of this NetDevice is busy, so we can't send other packets.
*
* SimpleChannel doesn't have a locking mechanism, and doesn't check for collisions, so there's nothing
* we need to do with the channel until the transmisison has "completed" from the perspective of this
* NetDevice.
*/
Time txTime = Time (0);
if (m_bps > DataRate (0))
{
txTime = m_bps.CalculateBytesTxTime (packet->GetSize ());
}
FinishTransmissionEvent = Simulator::Schedule (txTime, &SimpleNetDevice::FinishTransmission, this, packet);
}
void
SimpleNetDevice::FinishTransmission (Ptr<Packet> packet)
{
NS_LOG_FUNCTION (this);
SimpleTag tag;
packet->RemovePacketTag (tag);
@@ -488,12 +500,7 @@ SimpleNetDevice::TransmitComplete ()
m_channel->Send (packet, proto, dst, src, this);
Time txTime = Time (0);
if (m_bps > DataRate (0))
{
txTime = m_bps.CalculateBytesTxTime (packet->GetSize ());
}
TransmitCompleteEvent = Simulator::Schedule (txTime, &SimpleNetDevice::TransmitComplete, this);
StartTransmission();
return;
}
@@ -535,9 +542,9 @@ SimpleNetDevice::DoDispose (void)
m_node = 0;
m_receiveErrorModel = 0;
m_queue->Flush ();
if (TransmitCompleteEvent.IsRunning ())
if (FinishTransmissionEvent.IsRunning ())
{
TransmitCompleteEvent.Cancel ();
FinishTransmissionEvent.Cancel ();
}
NetDevice::DoDispose ();
}

View File

@@ -158,11 +158,13 @@ private:
*/
TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
void StartTransmission(void);
/**
* The TransmitComplete method is used internally to finish the process
* The FinishTransmission method is used internally to finish the process
* of sending a packet out on the channel.
*/
void TransmitComplete (void);
void FinishTransmission (Ptr<Packet> packet);
bool m_linkUp; //!< Flag indicating whether or not the link is up
@@ -174,7 +176,7 @@ private:
Ptr<Queue<Packet> > m_queue; //!< The Queue for outgoing packets.
DataRate m_bps; //!< The device nominal Data rate. Zero means infinite
EventId TransmitCompleteEvent; //!< the Tx Complete event
EventId FinishTransmissionEvent; //!< the Tx Complete event
/**
* List of callbacks to fire if the link changes state (up or down).