A Discrete-Event Network Simulator
API
red-queue-disc.cc
Go to the documentation of this file.
1 // /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright © 2011 Marcos Talau
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Marcos Talau (talau@users.sourceforge.net)
19  *
20  * Thanks to: Duy Nguyen<duy@soe.ucsc.edu> by RED efforts in NS3
21  *
22  *
23  * This file incorporates work covered by the following copyright and
24  * permission notice:
25  *
26  * Copyright (c) 1990-1997 Regents of the University of California.
27  * All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions
31  * are met:
32  * 1. Redistributions of source code must retain the above copyright
33  * notice, this list of conditions and the following disclaimer.
34  * 2. Redistributions in binary form must reproduce the above copyright
35  * notice, this list of conditions and the following disclaimer in the
36  * documentation and/or other materials provided with the distribution.
37  * 3. Neither the name of the University nor of the Laboratory may be used
38  * to endorse or promote products derived from this software without
39  * specific prior written permission.
40  *
41  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  */
53 
54 /*
55  * PORT NOTE: This code was ported from ns-2 (queue/red.cc). Almost all
56  * comments have also been ported from NS-2
57  */
58 
59 #include "ns3/log.h"
60 #include "ns3/enum.h"
61 #include "ns3/uinteger.h"
62 #include "ns3/double.h"
63 #include "ns3/simulator.h"
64 #include "ns3/abort.h"
65 #include "red-queue-disc.h"
66 #include "ns3/drop-tail-queue.h"
67 
68 namespace ns3 {
69 
70 NS_LOG_COMPONENT_DEFINE ("RedQueueDisc");
71 
72 NS_OBJECT_ENSURE_REGISTERED (RedQueueDisc);
73 
75 {
76  static TypeId tid = TypeId ("ns3::RedQueueDisc")
77  .SetParent<QueueDisc> ()
78  .SetGroupName("TrafficControl")
79  .AddConstructor<RedQueueDisc> ()
80  .AddAttribute ("Mode",
81  "Determines unit for QueueLimit",
84  MakeEnumChecker (Queue::QUEUE_MODE_BYTES, "QUEUE_MODE_BYTES",
85  Queue::QUEUE_MODE_PACKETS, "QUEUE_MODE_PACKETS"))
86  .AddAttribute ("MeanPktSize",
87  "Average of packet size",
88  UintegerValue (500),
90  MakeUintegerChecker<uint32_t> ())
91  .AddAttribute ("IdlePktSize",
92  "Average packet size used during idle times. Used when m_cautions = 3",
93  UintegerValue (0),
95  MakeUintegerChecker<uint32_t> ())
96  .AddAttribute ("Wait",
97  "True for waiting between dropped packets",
98  BooleanValue (true),
101  .AddAttribute ("Gentle",
102  "True to increases dropping probability slowly when average queue exceeds maxthresh",
103  BooleanValue (true),
106  .AddAttribute ("ARED",
107  "True to enable ARED",
108  BooleanValue (false),
111  .AddAttribute ("AdaptMaxP",
112  "True to adapt m_curMaxP",
113  BooleanValue (false),
116  .AddAttribute ("MinTh",
117  "Minimum average length threshold in packets/bytes",
118  DoubleValue (5),
120  MakeDoubleChecker<double> ())
121  .AddAttribute ("MaxTh",
122  "Maximum average length threshold in packets/bytes",
123  DoubleValue (15),
125  MakeDoubleChecker<double> ())
126  .AddAttribute ("QueueLimit",
127  "Queue limit in bytes/packets",
128  UintegerValue (25),
130  MakeUintegerChecker<uint32_t> ())
131  .AddAttribute ("QW",
132  "Queue weight related to the exponential weighted moving average (EWMA)",
133  DoubleValue (0.002),
135  MakeDoubleChecker <double> ())
136  .AddAttribute ("LInterm",
137  "The maximum probability of dropping a packet",
138  DoubleValue (50),
140  MakeDoubleChecker <double> ())
141  .AddAttribute ("TargetDelay",
142  "Target average queuing delay in ARED",
143  TimeValue (Seconds (0.005)),
145  MakeTimeChecker ())
146  .AddAttribute ("Interval",
147  "Time interval to update m_curMaxP",
148  TimeValue (Seconds (0.5)),
150  MakeTimeChecker ())
151  .AddAttribute ("Top",
152  "Upper bound for m_curMaxP in ARED",
153  DoubleValue (0.5),
155  MakeDoubleChecker <double> (0, 1))
156  .AddAttribute ("Bottom",
157  "Lower bound for m_curMaxP in ARED",
158  DoubleValue (0.0),
160  MakeDoubleChecker <double> (0, 1))
161  .AddAttribute ("Alpha",
162  "Increment parameter for m_curMaxP in ARED",
163  DoubleValue (0.01),
165  MakeDoubleChecker <double> (0, 1))
166  .AddAttribute ("Beta",
167  "Decrement parameter for m_curMaxP in ARED",
168  DoubleValue (0.9),
170  MakeDoubleChecker <double> (0, 1))
171  .AddAttribute ("LastSet",
172  "Store the last time m_curMaxP was updated",
173  TimeValue (Seconds (0.0)),
175  MakeTimeChecker ())
176  .AddAttribute ("Rtt",
177  "Round Trip Time to be considered while automatically setting m_bottom",
178  TimeValue (Seconds (0.1)),
180  MakeTimeChecker ())
181  .AddAttribute ("Ns1Compat",
182  "NS-1 compatibility",
183  BooleanValue (false),
186  .AddAttribute ("LinkBandwidth",
187  "The RED link bandwidth",
188  DataRateValue (DataRate ("1.5Mbps")),
191  .AddAttribute ("LinkDelay",
192  "The RED link delay",
193  TimeValue (MilliSeconds (20)),
195  MakeTimeChecker ())
196  ;
197 
198  return tid;
199 }
200 
202  QueueDisc ()
203 {
204  NS_LOG_FUNCTION (this);
205  m_uv = CreateObject<UniformRandomVariable> ();
206 }
207 
209 {
210  NS_LOG_FUNCTION (this);
211 }
212 
213 void
215 {
216  NS_LOG_FUNCTION (this);
217  m_uv = 0;
219 }
220 
221 void
223 {
224  NS_LOG_FUNCTION (this << mode);
225  m_mode = mode;
226 }
227 
230 {
231  NS_LOG_FUNCTION (this);
232  return m_mode;
233 }
234 
235 void
237 {
238  NS_LOG_FUNCTION (this << alpha);
239  m_alpha = alpha;
240 
241  if (m_alpha > 0.01)
242  {
243  NS_LOG_WARN ("Alpha value is above the recommended bound!");
244  }
245 }
246 
247 double
249 {
250  NS_LOG_FUNCTION (this);
251  return m_alpha;
252 }
253 
254 void
256 {
257  NS_LOG_FUNCTION (this << beta);
258  m_beta = beta;
259 
260  if (m_beta < 0.83)
261  {
262  NS_LOG_WARN ("Beta value is below the recommended bound!");
263  }
264 }
265 
266 double
268 {
269  NS_LOG_FUNCTION (this);
270  return m_beta;
271 }
272 
273 void
275 {
276  NS_LOG_FUNCTION (this << lim);
277  m_queueLimit = lim;
278 }
279 
280 void
281 RedQueueDisc::SetTh (double minTh, double maxTh)
282 {
283  NS_LOG_FUNCTION (this << minTh << maxTh);
284  NS_ASSERT (minTh <= maxTh);
285  m_minTh = minTh;
286  m_maxTh = maxTh;
287 }
288 
291 {
292  NS_LOG_FUNCTION (this);
293  return m_stats;
294 }
295 
296 int64_t
298 {
299  NS_LOG_FUNCTION (this << stream);
300  m_uv->SetStream (stream);
301  return 1;
302 }
303 
304 bool
306 {
307  NS_LOG_FUNCTION (this << item);
308 
309  uint32_t nQueued = 0;
310 
312  {
313  NS_LOG_DEBUG ("Enqueue in bytes mode");
314  nQueued = GetInternalQueue (0)->GetNBytes ();
315  }
316  else if (GetMode () == Queue::QUEUE_MODE_PACKETS)
317  {
318  NS_LOG_DEBUG ("Enqueue in packets mode");
319  nQueued = GetInternalQueue (0)->GetNPackets ();
320  }
321 
322  // simulate number of packets arrival during idle period
323  uint32_t m = 0;
324 
325  if (m_idle == 1)
326  {
327  NS_LOG_DEBUG ("RED Queue Disc is idle.");
328  Time now = Simulator::Now ();
329 
330  if (m_cautious == 3)
331  {
332  double ptc = m_ptc * m_meanPktSize / m_idlePktSize;
333  m = uint32_t (ptc * (now - m_idleTime).GetSeconds ());
334  }
335  else
336  {
337  m = uint32_t (m_ptc * (now - m_idleTime).GetSeconds ());
338  }
339 
340  m_idle = 0;
341  }
342 
343  m_qAvg = Estimator (nQueued, m + 1, m_qAvg, m_qW);
344 
345  NS_LOG_DEBUG ("\t bytesInQueue " << GetInternalQueue (0)->GetNBytes () << "\tQavg " << m_qAvg);
346  NS_LOG_DEBUG ("\t packetsInQueue " << GetInternalQueue (0)->GetNPackets () << "\tQavg " << m_qAvg);
347 
348  m_count++;
349  m_countBytes += item->GetPacketSize ();
350 
351  uint32_t dropType = DTYPE_NONE;
352  if (m_qAvg >= m_minTh && nQueued > 1)
353  {
354  if ((!m_isGentle && m_qAvg >= m_maxTh) ||
355  (m_isGentle && m_qAvg >= 2 * m_maxTh))
356  {
357  NS_LOG_DEBUG ("adding DROP FORCED MARK");
358  dropType = DTYPE_FORCED;
359  }
360  else if (m_old == 0)
361  {
362  /*
363  * The average queue size has just crossed the
364  * threshold from below to above "minthresh", or
365  * from above "minthresh" with an empty queue to
366  * above "minthresh" with a nonempty queue.
367  */
368  m_count = 1;
369  m_countBytes = item->GetPacketSize ();
370  m_old = 1;
371  }
372  else if (DropEarly (item, nQueued))
373  {
374  NS_LOG_LOGIC ("DropEarly returns 1");
375  dropType = DTYPE_UNFORCED;
376  }
377  }
378  else
379  {
380  // No packets are being dropped
381  m_vProb = 0.0;
382  m_old = 0;
383  }
384 
385  if ((GetMode () == Queue::QUEUE_MODE_PACKETS && nQueued >= m_queueLimit) ||
386  (GetMode () == Queue::QUEUE_MODE_BYTES && nQueued + item->GetPacketSize() > m_queueLimit))
387  {
388  NS_LOG_DEBUG ("\t Dropping due to Queue Full " << nQueued);
389  dropType = DTYPE_FORCED;
390  m_stats.qLimDrop++;
391  }
392 
393  if (dropType == DTYPE_UNFORCED)
394  {
395  NS_LOG_DEBUG ("\t Dropping due to Prob Mark " << m_qAvg);
397  Drop (item);
398  return false;
399  }
400  else if (dropType == DTYPE_FORCED)
401  {
402  NS_LOG_DEBUG ("\t Dropping due to Hard Mark " << m_qAvg);
404  Drop (item);
405  if (m_isNs1Compat)
406  {
407  m_count = 0;
408  m_countBytes = 0;
409  }
410  return false;
411  }
412 
413  GetInternalQueue (0)->Enqueue (item);
414 
415  NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
416  NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
417 
418  return true;
419 }
420 
421 /*
422  * Note: if the link bandwidth changes in the course of the
423  * simulation, the bandwidth-dependent RED parameters do not change.
424  * This should be fixed, but it would require some extra parameters,
425  * and didn't seem worth the trouble...
426  */
427 void
429 {
430  NS_LOG_FUNCTION (this);
431  NS_LOG_INFO ("Initializing RED params.");
432 
433  m_cautious = 0;
435 
436  if (m_isARED)
437  {
438  // Set m_minTh, m_maxTh and m_qW to zero for automatic setting
439  m_minTh = 0;
440  m_maxTh = 0;
441  m_qW = 0;
442 
443  // Turn on m_isAdaptMaxP to adapt m_curMaxP
444  m_isAdaptMaxP = true;
445  }
446 
447  if (m_minTh == 0 && m_maxTh == 0)
448  {
449  m_minTh = 5.0;
450 
451  // set m_minTh to max(m_minTh, targetqueue/2.0) [Ref: http://www.icir.org/floyd/papers/adaptiveRed.pdf]
452  double targetqueue = m_targetDelay.GetSeconds() * m_ptc;
453 
454  if (m_minTh < targetqueue / 2.0 )
455  {
456  m_minTh = targetqueue / 2.0;
457  }
459  {
461  }
462 
463  // set m_maxTh to three times m_minTh [Ref: http://www.icir.org/floyd/papers/adaptiveRed.pdf]
464  m_maxTh = 3 * m_minTh;
465  }
466 
468  m_stats.forcedDrop = 0;
469  m_stats.unforcedDrop = 0;
470  m_stats.qLimDrop = 0;
471 
472  m_qAvg = 0.0;
473  m_count = 0;
474  m_countBytes = 0;
475  m_old = 0;
476  m_idle = 1;
477 
478  double th_diff = (m_maxTh - m_minTh);
479  if (th_diff == 0)
480  {
481  th_diff = 1.0;
482  }
483  m_vA = 1.0 / th_diff;
484  m_curMaxP = 1.0 / m_lInterm;
485  m_vB = -m_minTh / th_diff;
486 
487  if (m_isGentle)
488  {
489  m_vC = (1.0 - m_curMaxP) / m_maxTh;
490  m_vD = 2.0 * m_curMaxP - 1.0;
491  }
492  m_idleTime = NanoSeconds (0);
493 
494 /*
495  * If m_qW=0, set it to a reasonable value of 1-exp(-1/C)
496  * This corresponds to choosing m_qW to be of that value for
497  * which the packet time constant -1/ln(1-m)qW) per default RTT
498  * of 100ms is an order of magnitude more than the link capacity, C.
499  *
500  * If m_qW=-1, then the queue weight is set to be a function of
501  * the bandwidth and the link propagation delay. In particular,
502  * the default RTT is assumed to be three times the link delay and
503  * transmission delay, if this gives a default RTT greater than 100 ms.
504  *
505  * If m_qW=-2, set it to a reasonable value of 1-exp(-10/C).
506  */
507  if (m_qW == 0.0)
508  {
509  m_qW = 1.0 - std::exp (-1.0 / m_ptc);
510  }
511  else if (m_qW == -1.0)
512  {
513  double rtt = 3.0 * (m_linkDelay.GetSeconds () + 1.0 / m_ptc);
514 
515  if (rtt < 0.1)
516  {
517  rtt = 0.1;
518  }
519  m_qW = 1.0 - std::exp (-1.0 / (10 * rtt * m_ptc));
520  }
521  else if (m_qW == -2.0)
522  {
523  m_qW = 1.0 - std::exp (-10.0 / m_ptc);
524  }
525 
526  if (m_bottom == 0)
527  {
528  m_bottom = 0.01;
529  // Set bottom to at most 1/W, where W is the delay-bandwidth
530  // product in packets for a connection.
531  // So W = m_linkBandwidth.GetBitRate () / (8.0 * m_meanPktSize * m_rtt.GetSeconds())
532  double bottom1 = (8.0 * m_meanPktSize * m_rtt.GetSeconds()) / m_linkBandwidth.GetBitRate();
533  if (bottom1 < m_bottom)
534  {
535  m_bottom = bottom1;
536  }
537  }
538 
539  NS_LOG_DEBUG ("\tm_delay " << m_linkDelay.GetSeconds () << "; m_isWait "
540  << m_isWait << "; m_qW " << m_qW << "; m_ptc " << m_ptc
541  << "; m_minTh " << m_minTh << "; m_maxTh " << m_maxTh
542  << "; m_isGentle " << m_isGentle << "; th_diff " << th_diff
543  << "; lInterm " << m_lInterm << "; va " << m_vA << "; cur_max_p "
544  << m_curMaxP << "; v_b " << m_vB << "; m_vC "
545  << m_vC << "; m_vD " << m_vD);
546 }
547 
548 // Update m_curMaxP to keep the average queue length within the target range.
549 void
550 RedQueueDisc::UpdateMaxP (double newAve, Time now)
551 {
552  double m_part = 0.4 * (m_maxTh - m_minTh);
553  // AIMD rule to keep target Q~1/2(m_minTh + m_maxTh)
554  if (newAve < m_minTh + m_part && m_curMaxP > m_bottom)
555  {
556  // we should increase the average queue size, so decrease m_curMaxP
558  m_lastSet = now;
559  }
560  else if (newAve > m_maxTh - m_part && m_top > m_curMaxP)
561  {
562  // we should decrease the average queue size, so increase m_curMaxP
563  double alpha = m_alpha;
564  if (alpha > 0.25 * m_curMaxP)
565  {
566  alpha = 0.25 * m_curMaxP;
567  }
568  m_curMaxP = m_curMaxP + alpha;
569  m_lastSet = now;
570  }
571 }
572 
573 // Compute the average queue size
574 double
575 RedQueueDisc::Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW)
576 {
577  NS_LOG_FUNCTION (this << nQueued << m << qAvg << qW);
578 
579  double newAve = qAvg * pow(1.0-qW, m);
580  newAve += qW * nQueued;
581 
582  Time now = Simulator::Now();
583  if (m_isAdaptMaxP && now > m_lastSet + m_interval)
584  {
585  UpdateMaxP(newAve, now);
586  }
587 
588  return newAve;
589 }
590 
591 // Check if packet p needs to be dropped due to probability mark
592 uint32_t
594 {
595  NS_LOG_FUNCTION (this << item << qSize);
597  m_vProb = ModifyP (m_vProb1, m_count, m_countBytes, m_meanPktSize, m_isWait, item->GetPacketSize ());
598 
599  // Drop probability is computed, pick random number and act
600  if (m_cautious == 1)
601  {
602  /*
603  * Don't drop/mark if the instantaneous queue is much below the average.
604  * For experimental purposes only.
605  * pkts: the number of packets arriving in 50 ms
606  */
607  double pkts = m_ptc * 0.05;
608  double fraction = std::pow ((1 - m_qW), pkts);
609 
610  if ((double) qSize < fraction * m_qAvg)
611  {
612  // Queue could have been empty for 0.05 seconds
613  return 0;
614  }
615  }
616 
617  double u = m_uv->GetValue ();
618 
619  if (m_cautious == 2)
620  {
621  /*
622  * Decrease the drop probability if the instantaneous
623  * queue is much below the average.
624  * For experimental purposes only.
625  * pkts: the number of packets arriving in 50 ms
626  */
627  double pkts = m_ptc * 0.05;
628  double fraction = std::pow ((1 - m_qW), pkts);
629  double ratio = qSize / (fraction * m_qAvg);
630 
631  if (ratio < 1.0)
632  {
633  u *= 1.0 / ratio;
634  }
635  }
636 
637  if (u <= m_vProb)
638  {
639  NS_LOG_LOGIC ("u <= m_vProb; u " << u << "; m_vProb " << m_vProb);
640 
641  // DROP or MARK
642  m_count = 0;
643  m_countBytes = 0;
645 
646  return 1; // drop
647  }
648 
649  return 0; // no drop/mark
650 }
651 
652 // Returns a probability using these function parameters for the DropEarly funtion
653 double
654 RedQueueDisc::CalculatePNew (double qAvg, double maxTh, bool isGentle, double vA,
655  double vB, double vC, double vD, double maxP)
656 {
657  NS_LOG_FUNCTION (this << qAvg << maxTh << isGentle << vA << vB << vC << vD << maxP);
658  double p;
659 
660  if (isGentle && qAvg >= maxTh)
661  {
662  // p ranges from maxP to 1 as the average queue
663  // Size ranges from maxTh to twice maxTh
664  p = vC * qAvg + vD;
665  }
666  else if (!isGentle && qAvg >= maxTh)
667  {
668  /*
669  * OLD: p continues to range linearly above max_p as
670  * the average queue size ranges above th_max.
671  * NEW: p is set to 1.0
672  */
673  p = 1.0;
674  }
675  else
676  {
677  /*
678  * p ranges from 0 to max_p as the average queue size ranges from
679  * th_min to th_max
680  */
681  p = vA * qAvg + vB;
682  p *= maxP;
683  }
684 
685  if (p > 1.0)
686  {
687  p = 1.0;
688  }
689 
690  return p;
691 }
692 
693 // Returns a probability using these function parameters for the DropEarly funtion
694 double
695 RedQueueDisc::ModifyP (double p, uint32_t count, uint32_t countBytes,
696  uint32_t meanPktSize, bool isWait, uint32_t size)
697 {
698  NS_LOG_FUNCTION (this << p << count << countBytes << meanPktSize << isWait << size);
699  double count1 = (double) count;
700 
702  {
703  count1 = (double) (countBytes / meanPktSize);
704  }
705 
706  if (isWait)
707  {
708  if (count1 * p < 1.0)
709  {
710  p = 0.0;
711  }
712  else if (count1 * p < 2.0)
713  {
714  p /= (2.0 - count1 * p);
715  }
716  else
717  {
718  p = 1.0;
719  }
720  }
721  else
722  {
723  if (count1 * p < 1.0)
724  {
725  p /= (1.0 - count1 * p);
726  }
727  else
728  {
729  p = 1.0;
730  }
731  }
732 
733  if ((GetMode () == Queue::QUEUE_MODE_BYTES) && (p < 1.0))
734  {
735  p = (p * size) / meanPktSize;
736  }
737 
738  if (p > 1.0)
739  {
740  p = 1.0;
741  }
742 
743  return p;
744 }
745 
746 uint32_t
748 {
749  NS_LOG_FUNCTION (this);
751  {
752  return GetInternalQueue (0)->GetNBytes ();
753  }
754  else if (GetMode () == Queue::QUEUE_MODE_PACKETS)
755  {
756  return GetInternalQueue (0)->GetNPackets ();
757  }
758  else
759  {
760  NS_ABORT_MSG ("Unknown RED mode.");
761  }
762 }
763 
766 {
767  NS_LOG_FUNCTION (this);
768 
769  if (GetInternalQueue (0)->IsEmpty ())
770  {
771  NS_LOG_LOGIC ("Queue empty");
772  m_idle = 1;
774 
775  return 0;
776  }
777  else
778  {
779  m_idle = 0;
780  Ptr<QueueDiscItem> item = StaticCast<QueueDiscItem> (GetInternalQueue (0)->Dequeue ());
781 
782  NS_LOG_LOGIC ("Popped " << item);
783 
784  NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
785  NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
786 
787  return item;
788  }
789 }
790 
793 {
794  NS_LOG_FUNCTION (this);
795  if (GetInternalQueue (0)->IsEmpty ())
796  {
797  NS_LOG_LOGIC ("Queue empty");
798  return 0;
799  }
800 
801  Ptr<const QueueDiscItem> item = StaticCast<const QueueDiscItem> (GetInternalQueue (0)->Peek ());
802 
803  NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
804  NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
805 
806  return item;
807 }
808 
809 bool
811 {
812  NS_LOG_FUNCTION (this);
813  if (GetNQueueDiscClasses () > 0)
814  {
815  NS_LOG_ERROR ("RedQueueDisc cannot have classes");
816  return false;
817  }
818 
819  if (GetNPacketFilters () > 0)
820  {
821  NS_LOG_ERROR ("RedQueueDisc cannot have packet filters");
822  return false;
823  }
824 
825  if (GetNInternalQueues () == 0)
826  {
827  // create a DropTail queue
828  Ptr<Queue> queue = CreateObjectWithAttributes<DropTailQueue> ("Mode", EnumValue (m_mode));
830  {
831  queue->SetMaxPackets (m_queueLimit);
832  }
833  else
834  {
835  queue->SetMaxBytes (m_queueLimit);
836  }
837  AddInternalQueue (queue);
838  }
839 
840  if (GetNInternalQueues () != 1)
841  {
842  NS_LOG_ERROR ("RedQueueDisc needs 1 internal queue");
843  return false;
844  }
845 
846  if (GetInternalQueue (0)->GetMode () != m_mode)
847  {
848  NS_LOG_ERROR ("The mode of the provided queue does not match the mode set on the RedQueueDisc");
849  return false;
850  }
851 
852  if ((m_mode == Queue::QUEUE_MODE_PACKETS && GetInternalQueue (0)->GetMaxPackets () < m_queueLimit) ||
853  (m_mode == Queue::QUEUE_MODE_BYTES && GetInternalQueue (0)->GetMaxBytes () < m_queueLimit))
854  {
855  NS_LOG_ERROR ("The size of the internal queue is less than the queue disc limit");
856  return false;
857  }
858 
859  return true;
860 }
861 
862 } // namespace ns3
bool m_isGentle
True to increases dropping prob.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
uint32_t GetQueueSize(void)
Get the current value of the queue in bytes or packets.
uint32_t GetNQueueDiscClasses(void) const
Get the number of queue disc classes.
Definition: queue-disc.cc:367
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
double m_beta
Decrement parameter for m_curMaxP in ARED.
AttributeValue implementation for Boolean.
Definition: boolean.h:34
uint32_t m_count
Number of packets since last random number generation.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
bool m_isARED
True to enable Adaptive RED.
void SetTh(double minTh, double maxTh)
Set the thresh limits of RED.
virtual bool DoEnqueue(Ptr< QueueDiscItem > item)
This function actually enqueues a packet into the queue disc.
Ptr< Queue > GetInternalQueue(uint32_t i) const
Get the i-th internal queue.
Definition: queue-disc.cc:319
uint32_t GetNBytes(void) const
Get the amount of bytes stored by the queue disc.
Definition: queue-disc.cc:235
double m_qAvg
Average queue length.
Use number of bytes for maximum queue size.
Definition: queue.h:128
Time m_linkDelay
Link delay.
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: enum.h:209
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
void SetAredBeta(double beta)
Set the beta value to adapt m_curMaxP.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
uint32_t m_idle
0/1 idle status
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:903
double m_vD
2.0 * m_curMaxP - 1.0 - used in "gentle" mode
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
double m_vC
(1.0 - m_curMaxP) / m_maxTh - used in "gentle" mode
double m_qW
Queue weight given to cur queue size sample.
QueueDisc is an abstract base class providing the interface and implementing the operations common to...
Definition: queue-disc.h:205
A RED packet queue disc.
Stats m_stats
RED statistics.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
double GetAredAlpha(void)
Get the alpha value to adapt m_curMaxP.
Time m_rtt
Rtt to be considered while automatically setting m_bottom in ARED.
double m_alpha
Increment parameter for m_curMaxP in ARED.
Time m_lastSet
Last time m_curMaxP was updated.
void UpdateMaxP(double newAve, Time now)
Update m_curMaxP.
bool m_isAdaptMaxP
True to adapt m_curMaxP.
Ptr< const AttributeChecker > MakeDataRateChecker(void)
Definition: data-rate.cc:30
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
static TypeId GetTypeId(void)
Get the type ID.
Class for representing data rates.
Definition: data-rate.h:88
double m_curMaxP
Current max_p.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
QueueMode
Enumeration of the modes supported in the class.
Definition: queue.h:125
void SetQueueLimit(uint32_t lim)
Set the limit of the queue.
uint32_t GetNInternalQueues(void) const
Get the number of internal queues.
Definition: queue-disc.cc:326
Time m_idleTime
Start of current idle period.
uint32_t forcedDrop
Forced drops, qavg > max threshold.
Hold variables of type enum.
Definition: enum.h:54
AttributeValue implementation for Time.
Definition: nstime.h:957
uint32_t m_queueLimit
Queue limit in bytes / packets.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:919
virtual bool CheckConfig(void)
Check whether the current configuration is correct.
Hold an unsigned integer type.
Definition: uinteger.h:44
virtual void InitializeParams(void)
Initialize the queue parameters.
uint32_t m_cautious
0 for default RED 1 experimental (see red-queue.cc) 2 experimental (see red-queue.cc) 3 use Idle packet size in the ptc
uint32_t qLimDrop
Drops due to queue limits.
void AddInternalQueue(Ptr< Queue > queue)
Add an internal queue to the tail of the list of queues.
Definition: queue-disc.cc:312
Ptr< UniformRandomVariable > m_uv
rng stream
Queue::QueueMode m_mode
Mode (Bytes or packets)
double m_vB
-m_minTh / (m_maxTh - m_minTh)
virtual void DoDispose(void)
Dispose of the object.
Definition: queue-disc.cc:188
uint32_t GetNPacketFilters(void) const
Get the number of packet filters.
Definition: queue-disc.cc:346
Ptr< const AttributeAccessor > MakeDataRateAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: data-rate.h:241
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
double m_minTh
Min avg length threshold (bytes)
uint32_t m_idlePktSize
Avg pkt size used during idle times.
double m_vProb1
Prob.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double m_vA
1.0 / (m_maxTh - m_minTh)
double CalculatePNew(double qAvg, double, bool gentle, double vA, double vB, double vC, double vD, double maxP)
Returns a probability using these function parameters for the DropEarly function. ...
uint32_t m_countBytes
Number of bytes since last drop.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
double m_lInterm
The max probability of dropping a packet.
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition: data-rate.cc:249
Queue::QueueMode GetMode(void)
Get the encapsulation mode of this queue.
uint32_t DropEarly(Ptr< QueueDiscItem > item, uint32_t qSize)
Check if a packet needs to be dropped due to probability mark.
RedQueueDisc()
RedQueueDisc Constructor.
double m_bottom
Lower bound for m_curMaxP in ARED.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:958
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
virtual Ptr< QueueDiscItem > DoDequeue(void)
This function actually extracts a packet from the queue disc.
An "unforced" (random) drop.
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: double.h:42
void Drop(Ptr< QueueDiscItem > item)
Drop a packet.
Definition: queue-disc.cc:393
uint32_t m_old
0 when average queue first exceeds threshold
Ptr< const AttributeChecker > MakeEnumChecker(int v1, std::string n1, int v2, std::string n2, int v3, std::string n3, int v4, std::string n4, int v5, std::string n5, int v6, std::string n6, int v7, std::string n7, int v8, std::string n8, int v9, std::string n9, int v10, std::string n10, int v11, std::string n11, int v12, std::string n12, int v13, std::string n13, int v14, std::string n14, int v15, std::string n15, int v16, std::string n16, int v17, std::string n17, int v18, std::string n18, int v19, std::string n19, int v20, std::string n20, int v21, std::string n21, int v22, std::string n22)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.cc:184
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
AttributeValue implementation for DataRate.
Definition: data-rate.h:241
double ModifyP(double p, uint32_t count, uint32_t countBytes, uint32_t meanPktSize, bool wait, uint32_t size)
Returns a probability using these function parameters for the DropEarly function. ...
DataRate m_linkBandwidth
Link bandwidth.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
Time m_interval
Time interval to update m_curMaxP.
void SetMode(Queue::QueueMode mode)
Set the operating mode of this queue.
bool m_isWait
True for waiting between dropped packets.
Time m_targetDelay
Target average queuing delay in ARED.
double GetAredBeta(void)
Get the beta value to adapt m_curMaxP.
double m_ptc
packet time constant in packets/second
virtual ~RedQueueDisc()
Destructor.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:220
double m_top
Upper bound for m_curMaxP in ARED.
Use number of packets for maximum queue size.
Definition: queue.h:127
double Estimator(uint32_t nQueued, uint32_t m, double qAvg, double qW)
Compute the average queue size.
uint32_t m_meanPktSize
Avg pkt size.
void SetAredAlpha(double alpha)
Set the alpha value to adapt m_curMaxP.
virtual Ptr< const QueueDiscItem > DoPeek(void) const
This function returns a copy of the next packet the queue disc will extract.
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
virtual void DoDispose(void)
Dispose of the object.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:826
double m_vProb
Prob.
Stats GetStats()
Get the RED statistics after running.
double m_maxTh
Max avg length threshold (bytes), should be >= 2*minTh.
uint32_t unforcedDrop
Early probability drops.
uint32_t GetNPackets(void) const
Get the number of packets stored by the queue disc.
Definition: queue-disc.cc:228
bool m_isNs1Compat
Ns-1 compatibility.