void PieQueueDisc::CalculateP()

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);
}