traffic-control: Update API for CoDel to better support testing

This commit is contained in:
Tom Henderson
2019-10-11 06:51:07 -07:00
parent da3789cc66
commit be11a079ce
2 changed files with 22 additions and 17 deletions

View File

@@ -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<uint16_t>(val >> REC_INV_SQRT_SHIFT);
return static_cast<uint16_t>(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);
}
}

View File

@@ -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