in simulation/src/traffic-control/model/pie-queue-disc.cc [334:468]
void PieQueueDisc::CalculateP ()
{
NS_LOG_FUNCTION (this);
Time qDelay;
double p = 0.0;
bool missingInitFlag = false;
if (m_useDqRateEstimator)
{
if (m_avgDqRate > 0)
{
qDelay = Seconds (GetInternalQueue (0)->GetNBytes () / m_avgDqRate);
}
else
{
qDelay = Seconds (0);
missingInitFlag = true;
}
m_qDelay = qDelay;
}
else
{
qDelay = m_qDelay;
}
NS_LOG_DEBUG ("Queue delay while calculating probability: " << qDelay.GetMilliSeconds () << "ms");
if (m_burstAllowance.GetSeconds () > 0)
{
m_dropProb = 0;
}
else
{
p = m_a * (qDelay.GetSeconds () - m_qDelayRef.GetSeconds ()) + m_b * (qDelay.GetSeconds () - m_qDelayOld.GetSeconds ());
if (m_dropProb < 0.000001)
{
p /= 2048;
}
else if (m_dropProb < 0.00001)
{
p /= 512;
}
else if (m_dropProb < 0.0001)
{
p /= 128;
}
else if (m_dropProb < 0.001)
{
p /= 32;
}
else if (m_dropProb < 0.01)
{
p /= 8;
}
else if (m_dropProb < 0.1)
{
p /= 2;
}
else
{
// The pseudocode in Section 4.2 of RFC 8033 suggests to use this for
// assignment of p, but this assignment causes build failure on Mac OS
// p = p;
}
// Cap Drop Adjustment (Section 5.5 of RFC 8033)
if (m_isCapDropAdjustment && (m_dropProb >= 0.1) && (p > 0.02))
{
p = 0.02;
}
}
p += m_dropProb;
// For non-linear drop in prob
// Decay the drop probability exponentially (Section 4.2 of RFC 8033)
if (qDelay.GetSeconds () == 0 && m_qDelayOld.GetSeconds () == 0)
{
p *= 0.98;
}
// bound the drop probability (Section 4.2 of RFC 8033)
if (p < 0)
{
m_dropProb = 0;
}
else if (p > 1)
{
m_dropProb = 1;
}
else
{
m_dropProb = p;
}
// Section 4.4 #2
if (m_burstAllowance < m_tUpdate)
{
m_burstAllowance = Seconds (0);
}
else
{
m_burstAllowance -= m_tUpdate;
}
uint32_t burstResetLimit = static_cast<uint32_t>(BURST_RESET_TIMEOUT / m_tUpdate.GetSeconds ());
if ( (qDelay.GetSeconds () < 0.5 * m_qDelayRef.GetSeconds ()) && (m_qDelayOld.GetSeconds () < (0.5 * m_qDelayRef.GetSeconds ())) && (m_dropProb == 0) && !missingInitFlag )
{
m_dqCount = DQCOUNT_INVALID;
m_avgDqRate = 0.0;
}
if ( (qDelay.GetSeconds () < 0.5 * m_qDelayRef.GetSeconds ()) && (m_qDelayOld.GetSeconds () < (0.5 * m_qDelayRef.GetSeconds ())) && (m_dropProb == 0) && (m_burstAllowance.GetSeconds () == 0))
{
if (m_burstState == IN_BURST_PROTECTING)
{
m_burstState = IN_BURST;
m_burstReset = 0;
}
else if (m_burstState == IN_BURST)
{
m_burstReset++;
if (m_burstReset > burstResetLimit)
{
m_burstReset = 0;
m_burstState = NO_BURST;
}
}
}
else if (m_burstState == IN_BURST)
{
m_burstReset = 0;
}
m_qDelayOld = qDelay;
m_rtrsEvent = Simulator::Schedule (m_tUpdate, &PieQueueDisc::CalculateP, this);
}