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  bool retval = GetInternalQueue (0)->Enqueue (item);
414 
415  // If Queue::Enqueue fails, QueueDisc::Drop is called by the internal queue
416  // because QueueDisc::AddInternalQueue sets the drop callback
417 
418  NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
419  NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
420 
421  return retval;
422 }
423 
424 /*
425  * Note: if the link bandwidth changes in the course of the
426  * simulation, the bandwidth-dependent RED parameters do not change.
427  * This should be fixed, but it would require some extra parameters,
428  * and didn't seem worth the trouble...
429  */
430 void
432 {
433  NS_LOG_FUNCTION (this);
434  NS_LOG_INFO ("Initializing RED params.");
435 
436  m_cautious = 0;
438 
439  if (m_isARED)
440  {
441  // Set m_minTh, m_maxTh and m_qW to zero for automatic setting
442  m_minTh = 0;
443  m_maxTh = 0;
444  m_qW = 0;
445 
446  // Turn on m_isAdaptMaxP to adapt m_curMaxP
447  m_isAdaptMaxP = true;
448  }
449 
450  if (m_minTh == 0 && m_maxTh == 0)
451  {
452  m_minTh = 5.0;
453 
454  // set m_minTh to max(m_minTh, targetqueue/2.0) [Ref: http://www.icir.org/floyd/papers/adaptiveRed.pdf]
455  double targetqueue = m_targetDelay.GetSeconds() * m_ptc;
456 
457  if (m_minTh < targetqueue / 2.0 )
458  {
459  m_minTh = targetqueue / 2.0;
460  }
462  {
464  }
465 
466  // set m_maxTh to three times m_minTh [Ref: http://www.icir.org/floyd/papers/adaptiveRed.pdf]
467  m_maxTh = 3 * m_minTh;
468  }
469 
471  m_stats.forcedDrop = 0;
472  m_stats.unforcedDrop = 0;
473  m_stats.qLimDrop = 0;
474 
475  m_qAvg = 0.0;
476  m_count = 0;
477  m_countBytes = 0;
478  m_old = 0;
479  m_idle = 1;
480 
481  double th_diff = (m_maxTh - m_minTh);
482  if (th_diff == 0)
483  {
484  th_diff = 1.0;
485  }
486  m_vA = 1.0 / th_diff;
487  m_curMaxP = 1.0 / m_lInterm;
488  m_vB = -m_minTh / th_diff;
489 
490  if (m_isGentle)
491  {
492  m_vC = (1.0 - m_curMaxP) / m_maxTh;
493  m_vD = 2.0 * m_curMaxP - 1.0;
494  }
495  m_idleTime = NanoSeconds (0);
496 
497 /*
498  * If m_qW=0, set it to a reasonable value of 1-exp(-1/C)
499  * This corresponds to choosing m_qW to be of that value for
500  * which the packet time constant -1/ln(1-m)qW) per default RTT
501  * of 100ms is an order of magnitude more than the link capacity, C.
502  *
503  * If m_qW=-1, then the queue weight is set to be a function of
504  * the bandwidth and the link propagation delay. In particular,
505  * the default RTT is assumed to be three times the link delay and
506  * transmission delay, if this gives a default RTT greater than 100 ms.
507  *
508  * If m_qW=-2, set it to a reasonable value of 1-exp(-10/C).
509  */
510  if (m_qW == 0.0)
511  {
512  m_qW = 1.0 - std::exp (-1.0 / m_ptc);
513  }
514  else if (m_qW == -1.0)
515  {
516  double rtt = 3.0 * (m_linkDelay.GetSeconds () + 1.0 / m_ptc);
517 
518  if (rtt < 0.1)
519  {
520  rtt = 0.1;
521  }
522  m_qW = 1.0 - std::exp (-1.0 / (10 * rtt * m_ptc));
523  }
524  else if (m_qW == -2.0)
525  {
526  m_qW = 1.0 - std::exp (-10.0 / m_ptc);
527  }
528 
529  if (m_bottom == 0)
530  {
531  m_bottom = 0.01;
532  // Set bottom to at most 1/W, where W is the delay-bandwidth
533  // product in packets for a connection.
534  // So W = m_linkBandwidth.GetBitRate () / (8.0 * m_meanPktSize * m_rtt.GetSeconds())
535  double bottom1 = (8.0 * m_meanPktSize * m_rtt.GetSeconds()) / m_linkBandwidth.GetBitRate();
536  if (bottom1 < m_bottom)
537  {
538  m_bottom = bottom1;
539  }
540  }
541 
542  NS_LOG_DEBUG ("\tm_delay " << m_linkDelay.GetSeconds () << "; m_isWait "
543  << m_isWait << "; m_qW " << m_qW << "; m_ptc " << m_ptc
544  << "; m_minTh " << m_minTh << "; m_maxTh " << m_maxTh
545  << "; m_isGentle " << m_isGentle << "; th_diff " << th_diff
546  << "; lInterm " << m_lInterm << "; va " << m_vA << "; cur_max_p "
547  << m_curMaxP << "; v_b " << m_vB << "; m_vC "
548  << m_vC << "; m_vD " << m_vD);
549 }
550 
551 // Update m_curMaxP to keep the average queue length within the target range.
552 void
553 RedQueueDisc::UpdateMaxP (double newAve, Time now)
554 {
555  double m_part = 0.4 * (m_maxTh - m_minTh);
556  // AIMD rule to keep target Q~1/2(m_minTh + m_maxTh)
557  if (newAve < m_minTh + m_part && m_curMaxP > m_bottom)
558  {
559  // we should increase the average queue size, so decrease m_curMaxP
561  m_lastSet = now;
562  }
563  else if (newAve > m_maxTh - m_part && m_top > m_curMaxP)
564  {
565  // we should decrease the average queue size, so increase m_curMaxP
566  double alpha = m_alpha;
567  if (alpha > 0.25 * m_curMaxP)
568  {
569  alpha = 0.25 * m_curMaxP;
570  }
571  m_curMaxP = m_curMaxP + alpha;
572  m_lastSet = now;
573  }
574 }
575 
576 // Compute the average queue size
577 double
578 RedQueueDisc::Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW)
579 {
580  NS_LOG_FUNCTION (this << nQueued << m << qAvg << qW);
581 
582  double newAve = qAvg * pow(1.0-qW, m);
583  newAve += qW * nQueued;
584 
585  Time now = Simulator::Now();
586  if (m_isAdaptMaxP && now > m_lastSet + m_interval)
587  {
588  UpdateMaxP(newAve, now);
589  }
590 
591  return newAve;
592 }
593 
594 // Check if packet p needs to be dropped due to probability mark
595 uint32_t
597 {
598  NS_LOG_FUNCTION (this << item << qSize);
600  m_vProb = ModifyP (m_vProb1, m_count, m_countBytes, m_meanPktSize, m_isWait, item->GetPacketSize ());
601 
602  // Drop probability is computed, pick random number and act
603  if (m_cautious == 1)
604  {
605  /*
606  * Don't drop/mark if the instantaneous queue is much below the average.
607  * For experimental purposes only.
608  * pkts: the number of packets arriving in 50 ms
609  */
610  double pkts = m_ptc * 0.05;
611  double fraction = std::pow ((1 - m_qW), pkts);
612 
613  if ((double) qSize < fraction * m_qAvg)
614  {
615  // Queue could have been empty for 0.05 seconds
616  return 0;
617  }
618  }
619 
620  double u = m_uv->GetValue ();
621 
622  if (m_cautious == 2)
623  {
624  /*
625  * Decrease the drop probability if the instantaneous
626  * queue is much below the average.
627  * For experimental purposes only.
628  * pkts: the number of packets arriving in 50 ms
629  */
630  double pkts = m_ptc * 0.05;
631  double fraction = std::pow ((1 - m_qW), pkts);
632  double ratio = qSize / (fraction * m_qAvg);
633 
634  if (ratio < 1.0)
635  {
636  u *= 1.0 / ratio;
637  }
638  }
639 
640  if (u <= m_vProb)
641  {
642  NS_LOG_LOGIC ("u <= m_vProb; u " << u << "; m_vProb " << m_vProb);
643 
644  // DROP or MARK
645  m_count = 0;
646  m_countBytes = 0;
648 
649  return 1; // drop
650  }
651 
652  return 0; // no drop/mark
653 }
654 
655 // Returns a probability using these function parameters for the DropEarly funtion
656 double
657 RedQueueDisc::CalculatePNew (double qAvg, double maxTh, bool isGentle, double vA,
658  double vB, double vC, double vD, double maxP)
659 {
660  NS_LOG_FUNCTION (this << qAvg << maxTh << isGentle << vA << vB << vC << vD << maxP);
661  double p;
662 
663  if (isGentle && qAvg >= maxTh)
664  {
665  // p ranges from maxP to 1 as the average queue
666  // Size ranges from maxTh to twice maxTh
667  p = vC * qAvg + vD;
668  }
669  else if (!isGentle && qAvg >= maxTh)
670  {
671  /*
672  * OLD: p continues to range linearly above max_p as
673  * the average queue size ranges above th_max.
674  * NEW: p is set to 1.0
675  */
676  p = 1.0;
677  }
678  else
679  {
680  /*
681  * p ranges from 0 to max_p as the average queue size ranges from
682  * th_min to th_max
683  */
684  p = vA * qAvg + vB;
685  p *= maxP;
686  }
687 
688  if (p > 1.0)
689  {
690  p = 1.0;
691  }
692 
693  return p;
694 }
695 
696 // Returns a probability using these function parameters for the DropEarly funtion
697 double
698 RedQueueDisc::ModifyP (double p, uint32_t count, uint32_t countBytes,
699  uint32_t meanPktSize, bool isWait, uint32_t size)
700 {
701  NS_LOG_FUNCTION (this << p << count << countBytes << meanPktSize << isWait << size);
702  double count1 = (double) count;
703 
705  {
706  count1 = (double) (countBytes / meanPktSize);
707  }
708 
709  if (isWait)
710  {
711  if (count1 * p < 1.0)
712  {
713  p = 0.0;
714  }
715  else if (count1 * p < 2.0)
716  {
717  p /= (2.0 - count1 * p);
718  }
719  else
720  {
721  p = 1.0;
722  }
723  }
724  else
725  {
726  if (count1 * p < 1.0)
727  {
728  p /= (1.0 - count1 * p);
729  }
730  else
731  {
732  p = 1.0;
733  }
734  }
735 
736  if ((GetMode () == Queue::QUEUE_MODE_BYTES) && (p < 1.0))
737  {
738  p = (p * size) / meanPktSize;
739  }
740 
741  if (p > 1.0)
742  {
743  p = 1.0;
744  }
745 
746  return p;
747 }
748 
749 uint32_t
751 {
752  NS_LOG_FUNCTION (this);
754  {
755  return GetInternalQueue (0)->GetNBytes ();
756  }
757  else if (GetMode () == Queue::QUEUE_MODE_PACKETS)
758  {
759  return GetInternalQueue (0)->GetNPackets ();
760  }
761  else
762  {
763  NS_ABORT_MSG ("Unknown RED mode.");
764  }
765 }
766 
769 {
770  NS_LOG_FUNCTION (this);
771 
772  if (GetInternalQueue (0)->IsEmpty ())
773  {
774  NS_LOG_LOGIC ("Queue empty");
775  m_idle = 1;
777 
778  return 0;
779  }
780  else
781  {
782  m_idle = 0;
783  Ptr<QueueDiscItem> item = StaticCast<QueueDiscItem> (GetInternalQueue (0)->Dequeue ());
784 
785  NS_LOG_LOGIC ("Popped " << item);
786 
787  NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
788  NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
789 
790  return item;
791  }
792 }
793 
796 {
797  NS_LOG_FUNCTION (this);
798  if (GetInternalQueue (0)->IsEmpty ())
799  {
800  NS_LOG_LOGIC ("Queue empty");
801  return 0;
802  }
803 
804  Ptr<const QueueDiscItem> item = StaticCast<const QueueDiscItem> (GetInternalQueue (0)->Peek ());
805 
806  NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
807  NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
808 
809  return item;
810 }
811 
812 bool
814 {
815  NS_LOG_FUNCTION (this);
816  if (GetNQueueDiscClasses () > 0)
817  {
818  NS_LOG_ERROR ("RedQueueDisc cannot have classes");
819  return false;
820  }
821 
822  if (GetNPacketFilters () > 0)
823  {
824  NS_LOG_ERROR ("RedQueueDisc cannot have packet filters");
825  return false;
826  }
827 
828  if (GetNInternalQueues () == 0)
829  {
830  // create a DropTail queue
831  Ptr<Queue> queue = CreateObjectWithAttributes<DropTailQueue> ("Mode", EnumValue (m_mode));
833  {
834  queue->SetMaxPackets (m_queueLimit);
835  }
836  else
837  {
838  queue->SetMaxBytes (m_queueLimit);
839  }
840  AddInternalQueue (queue);
841  }
842 
843  if (GetNInternalQueues () != 1)
844  {
845  NS_LOG_ERROR ("RedQueueDisc needs 1 internal queue");
846  return false;
847  }
848 
849  if (GetInternalQueue (0)->GetMode () != m_mode)
850  {
851  NS_LOG_ERROR ("The mode of the provided queue does not match the mode set on the RedQueueDisc");
852  return false;
853  }
854 
855  if ((m_mode == Queue::QUEUE_MODE_PACKETS && GetInternalQueue (0)->GetMaxPackets () < m_queueLimit) ||
856  (m_mode == Queue::QUEUE_MODE_BYTES && GetInternalQueue (0)->GetMaxBytes () < m_queueLimit))
857  {
858  NS_LOG_ERROR ("The size of the internal queue is less than the queue disc limit");
859  return false;
860  }
861 
862  return true;
863 }
864 
865 } // 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:379
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:324
uint32_t GetNBytes(void) const
Get the amount of bytes stored by the queue disc.
Definition: queue-disc.cc:237
double m_qAvg
Average queue length.
Use number of bytes for maximum queue size.
Definition: queue.h:133
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:130
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:331
Time m_idleTime
Start of current idle period.
void Drop(Ptr< QueueItem > item)
Drop a packet.
Definition: queue-disc.cc:411
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:314
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:190
uint32_t GetNPacketFilters(void) const
Get the number of packet filters.
Definition: queue-disc.cc:351
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:242
#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.
An "unforced" (random) drop.
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:224
virtual Ptr< QueueDiscItem > DoDequeue(void)
This function actually extracts a packet from the queue disc.
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
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:242
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:132
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:904
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:230
bool m_isNs1Compat
Ns-1 compatibility.