diff --git a/src/traffic-control/model/codel-queue-disc.cc b/src/traffic-control/model/codel-queue-disc.cc index 6cc026462..089cfa4bb 100644 --- a/src/traffic-control/model/codel-queue-disc.cc +++ b/src/traffic-control/model/codel-queue-disc.cc @@ -136,24 +136,24 @@ CoDelQueueDisc::~CoDelQueueDisc () NS_LOG_FUNCTION (this); } -void -CoDelQueueDisc::NewtonStep (void) +uint16_t +CoDelQueueDisc::NewtonStep (uint16_t recInvSqrt, uint32_t count) { - NS_LOG_FUNCTION (this); - uint32_t invsqrt = ((uint32_t) m_recInvSqrt) << REC_INV_SQRT_SHIFT; + NS_LOG_FUNCTION_NOARGS (); + uint32_t invsqrt = ((uint32_t) recInvSqrt) << REC_INV_SQRT_SHIFT; uint32_t invsqrt2 = ((uint64_t) invsqrt * invsqrt) >> 32; - uint64_t val = (3ll << 32) - ((uint64_t) m_count * invsqrt2); + uint64_t val = (3ll << 32) - ((uint64_t) count * invsqrt2); val >>= 2; /* avoid overflow */ val = (val * invsqrt) >> (32 - 2 + 1); - m_recInvSqrt = static_cast(val >> REC_INV_SQRT_SHIFT); + return static_cast(val >> REC_INV_SQRT_SHIFT); } uint32_t -CoDelQueueDisc::ControlLaw (uint32_t t) +CoDelQueueDisc::ControlLaw (uint32_t t, uint32_t interval, uint32_t recInvSqrt) { - NS_LOG_FUNCTION (this); - return t + ReciprocalDivide (Time2CoDel (m_interval), m_recInvSqrt << REC_INV_SQRT_SHIFT); + NS_LOG_FUNCTION_NOARGS (); + return t + ReciprocalDivide (interval, recInvSqrt << REC_INV_SQRT_SHIFT); } bool @@ -268,7 +268,7 @@ CoDelQueueDisc::DoDequeue (void) DropAfterDequeue (item, TARGET_EXCEEDED_DROP); ++m_count; - NewtonStep (); + m_recInvSqrt = NewtonStep (m_recInvSqrt, m_count); item = GetInternalQueue (0)->Dequeue (); if (item) @@ -288,7 +288,7 @@ CoDelQueueDisc::DoDequeue (void) { /* schedule the next drop */ NS_LOG_LOGIC ("Running ControlLaw for input m_dropNext: " << (double)m_dropNext / 1000000); - m_dropNext = ControlLaw (m_dropNext); + m_dropNext = ControlLaw (m_dropNext, Time2CoDel (m_interval), m_recInvSqrt); NS_LOG_LOGIC ("Scheduled next drop at " << (double)m_dropNext / 1000000); } } @@ -326,7 +326,7 @@ CoDelQueueDisc::DoDequeue (void) if (delta > 1 && CoDelTimeBefore (now - m_dropNext, 16 * Time2CoDel (m_interval))) { m_count = delta; - NewtonStep (); + m_recInvSqrt = NewtonStep (m_recInvSqrt, m_count); } else { @@ -335,7 +335,7 @@ CoDelQueueDisc::DoDequeue (void) } m_lastCount = m_count; NS_LOG_LOGIC ("Running ControlLaw for input now: " << (double)now); - m_dropNext = ControlLaw (now); + m_dropNext = ControlLaw (now, Time2CoDel (m_interval), m_recInvSqrt); NS_LOG_LOGIC ("Scheduled next drop at " << (double)m_dropNext / 1000000 << " now " << (double)now / 1000000); } } diff --git a/src/traffic-control/model/codel-queue-disc.h b/src/traffic-control/model/codel-queue-disc.h index ce34ef06e..c6d24eecf 100644 --- a/src/traffic-control/model/codel-queue-disc.h +++ b/src/traffic-control/model/codel-queue-disc.h @@ -130,8 +130,11 @@ private: * \brief Calculate the reciprocal square root of m_count by using Newton's method * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots * m_recInvSqrt (new) = (m_recInvSqrt (old) / 2) * (3 - m_count * m_recInvSqrt^2) + * \param recInvSqrt reciprocal value of sqrt (count) + * \param count count value + * \return The new recInvSqrt value */ - void NewtonStep (void); + static uint16_t NewtonStep (uint16_t recInvSqrt, uint32_t count); /** * \brief Determine the time for next drop @@ -139,10 +142,12 @@ private: * Here, we use m_recInvSqrt calculated by Newton's method in NewtonStep() to avoid * both sqrt() and divide operations * - * \param t Current next drop time - * \returns The new next drop time: + * \param t Current next drop time (in units of CoDel time) + * \param interval interval (in units of CoDel time) + * \param recInvSqrt reciprocal value of sqrt (count) + * \return The new next drop time (in units of CoDel time) */ - uint32_t ControlLaw (uint32_t t); + static uint32_t ControlLaw (uint32_t t, uint32_t interval, uint32_t recInvSqrt); /** * \brief Determine whether a packet is OK to be dropped. The packet