Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * This code was ported from NS-2.34, with licence: | 3 * This code was ported from NS-2.34, with licence: |
4 * | 4 * |
5 * Copyright (c) 1990-1997 Regents of the University of California. | 5 * Copyright (c) 1990-1997 Regents of the University of California. |
6 * All rights reserved. | 6 * All rights reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
(...skipping 16 matching lines...) Expand all Loading... | |
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
34 * SUCH DAMAGE. | 34 * SUCH DAMAGE. |
35 * | 35 * |
36 * | 36 * |
37 * This port: Copyright © 2011 Marcos Talau (talau@users.sourceforge.net) | 37 * This port:· |
38 * | |
39 * Copyright © 2011 Marcos Talau | |
38 * | 40 * |
39 * This program is free software: you can redistribute it and/or modify | 41 * This program is free software: you can redistribute it and/or modify |
40 * it under the terms of the GNU General Public License as published by | 42 * it under the terms of the GNU General Public License as published by |
41 * the Free Software Foundation, either version 3 of the License, or | 43 * the Free Software Foundation, either version 3 of the License, or |
42 * (at your option) any later version. | 44 * (at your option) any later version. |
43 * | 45 * |
44 * This program is distributed in the hope that it will be useful, | 46 * This program is distributed in the hope that it will be useful, |
45 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 47 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
46 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 48 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
47 * GNU General Public License for more details. | 49 * GNU General Public License for more details. |
48 * | 50 * |
49 * You should have received a copy of the GNU General Public License | 51 * You should have received a copy of the GNU General Public License |
50 * along with this program. If not, see <http://www.gnu.org/licenses/>. | 52 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
51 * | 53 * |
54 * Author: Marcos Talau (talau@users.sourceforge.net) | |
55 * | |
52 * Thanks to: Duy Nguyen<duy@soe.ucsc.edu> by RED efforts in NS3 | 56 * Thanks to: Duy Nguyen<duy@soe.ucsc.edu> by RED efforts in NS3 |
53 * | 57 * |
58 */ | |
59 | |
60 /* | |
61 * PORT NOTE: Almost all comments have also been ported from NS-2 | |
54 */ | 62 */ |
55 | 63 |
56 #include "ns3/log.h" | 64 #include "ns3/log.h" |
57 #include "ns3/enum.h" | 65 #include "ns3/enum.h" |
58 #include "ns3/uinteger.h" | 66 #include "ns3/uinteger.h" |
59 #include "ns3/double.h" | 67 #include "ns3/double.h" |
60 #include "ns3/simulator.h" | 68 #include "ns3/simulator.h" |
69 #include "ns3/abort.h" | |
61 #include "red-queue.h" | 70 #include "red-queue.h" |
62 | 71 |
63 NS_LOG_COMPONENT_DEFINE ("RedQueue"); | 72 NS_LOG_COMPONENT_DEFINE ("RedQueue"); |
64 | 73 |
65 namespace ns3 { | 74 namespace ns3 { |
66 | 75 |
67 NS_OBJECT_ENSURE_REGISTERED (RedQueue); | 76 NS_OBJECT_ENSURE_REGISTERED (RedQueue); |
68 | 77 |
69 TypeId RedQueue::GetTypeId (void) | 78 TypeId RedQueue::GetTypeId (void) |
70 { | 79 { |
71 static TypeId tid = TypeId ("ns3::RedQueue") | 80 static TypeId tid = TypeId ("ns3::RedQueue") |
72 .SetParent<Queue> () | 81 .SetParent<Queue> () |
73 .AddConstructor<RedQueue> () | 82 .AddConstructor<RedQueue> () |
74 .AddAttribute ("Mode", | 83 .AddAttribute ("Mode", |
75 "Bytes or Packets", | 84 "Bytes or packets", |
76 EnumValue (PACKETS), | 85 EnumValue (PACKETS), |
77 MakeEnumAccessor (&RedQueue::SetMode), | 86 MakeEnumAccessor (&RedQueue::SetMode), |
78 MakeEnumChecker (BYTES, "Bytes", | 87 MakeEnumChecker (BYTES, "Bytes", |
79 PACKETS, "Packets")) | 88 PACKETS, "Packets")) |
80 .AddAttribute ("MeanPktSize", | 89 .AddAttribute ("MeanPktSize", |
81 "Average of Packet Size", | 90 "Average of packet size", |
82 UintegerValue (500), | 91 UintegerValue (500), |
83 MakeUintegerAccessor (&RedQueue::m_meanPktSize), | 92 MakeUintegerAccessor (&RedQueue::m_meanPktSize), |
84 MakeUintegerChecker<uint32_t> ()) | 93 MakeUintegerChecker<uint32_t> ()) |
85 .AddAttribute ("IdlePktSize", | 94 .AddAttribute ("IdlePktSize", |
86 "Avg pkt size used during idle times. Used when m_cautions = 3", | 95 "Average packet size used during idle times. Used when m_caut ions = 3", |
87 UintegerValue (0), | 96 UintegerValue (0), |
88 MakeUintegerAccessor (&RedQueue::m_idlePktSize), | 97 MakeUintegerAccessor (&RedQueue::m_idlePktSize), |
89 MakeUintegerChecker<uint32_t> ()) | 98 MakeUintegerChecker<uint32_t> ()) |
90 .AddAttribute ("Wait", | 99 .AddAttribute ("Wait", |
91 "True for waiting between dropped packets", | 100 "True for waiting between dropped packets", |
92 BooleanValue (true), | 101 BooleanValue (true), |
93 MakeBooleanAccessor (&RedQueue::m_wait), | 102 MakeBooleanAccessor (&RedQueue::m_isWait), |
94 MakeBooleanChecker ()) | 103 MakeBooleanChecker ()) |
95 .AddAttribute ("Gentle", | 104 .AddAttribute ("Gentle", |
96 "True to increases dropping prob. slowly when ave queue excee ds maxthresh", | 105 "True to increases dropping probability slowly when average q ueue exceeds maxthresh", |
Duy
2011/08/18 08:01:27
ave? it's better if we spell the description out t
talau
2011/08/22 17:54:41
Done.
| |
97 BooleanValue (true), | 106 BooleanValue (true), |
98 MakeBooleanAccessor (&RedQueue::m_gentle), | 107 MakeBooleanAccessor (&RedQueue::m_isGentle), |
99 MakeBooleanChecker ()) | 108 MakeBooleanChecker ()) |
100 .AddAttribute ("m_minTh", | 109 .AddAttribute ("MinTh", |
101 "Min avg length threshold in packets/bytes", | 110 "Minimum average length threshold in packets/bytes", |
102 DoubleValue (5), | 111 DoubleValue (5), |
103 MakeDoubleAccessor (&RedQueue::m_minTh), | 112 MakeDoubleAccessor (&RedQueue::m_minTh), |
104 MakeDoubleChecker<double> ()) | 113 MakeDoubleChecker<double> ()) |
105 .AddAttribute ("m_maxTh", | 114 .AddAttribute ("MaxTh", |
106 "Max avg length threshold in packets/bytes", | 115 "Maximum average length threshold in packets/bytes", |
107 DoubleValue (15), | 116 DoubleValue (15), |
108 MakeDoubleAccessor (&RedQueue::m_maxTh), | 117 MakeDoubleAccessor (&RedQueue::m_maxTh), |
109 MakeDoubleChecker<double> ()) | 118 MakeDoubleChecker<double> ()) |
110 .AddAttribute ("QueueLimit", | 119 .AddAttribute ("QueueLimit", |
111 "Queue limit in bytes/packets", | 120 "Queue limit in bytes/packets", |
112 UintegerValue (25), | 121 UintegerValue (25), |
113 MakeUintegerAccessor (&RedQueue::m_queueLimit), | 122 MakeUintegerAccessor (&RedQueue::m_queueLimit), |
114 MakeUintegerChecker<uint32_t> ()) | 123 MakeUintegerChecker<uint32_t> ()) |
115 .AddAttribute ("m_qW", | 124 .AddAttribute ("QW", |
116 "Queue weight given to cur q size sample", | 125 "Queue weight related to the exponential weighted moving aver age (EWMA)", |
117 DoubleValue (0.002), | 126 DoubleValue (0.002), |
118 MakeDoubleAccessor (&RedQueue::m_qW), | 127 MakeDoubleAccessor (&RedQueue::m_qW), |
119 MakeDoubleChecker <double> ()) | 128 MakeDoubleChecker <double> ()) |
120 .AddAttribute ("m_lInterm", | 129 .AddAttribute ("LInterm", |
121 "The max probability of dropping a packet", | 130 "The maximum probability of dropping a packet", |
122 DoubleValue (50), | 131 DoubleValue (50), |
123 MakeDoubleAccessor (&RedQueue::m_lInterm), | 132 MakeDoubleAccessor (&RedQueue::m_lInterm), |
124 MakeDoubleChecker <double> ()) | 133 MakeDoubleChecker <double> ()) |
125 .AddAttribute ("m_ns1Compat", | 134 .AddAttribute ("Ns1Compat", |
126 "NS-1 compatibility", | 135 "NS-1 compatibility", |
127 BooleanValue (false), | 136 BooleanValue (false), |
128 MakeBooleanAccessor (&RedQueue::m_ns1Compat), | 137 MakeBooleanAccessor (&RedQueue::m_isNs1Compat), |
129 MakeBooleanChecker ()) | 138 MakeBooleanChecker ()) |
130 .AddAttribute ("LinkBandwidth",· | 139 .AddAttribute ("LinkBandwidth",· |
131 "The RED link bandwidth", | 140 "The RED link bandwidth", |
132 DataRateValue (DataRate ("1.5Mbps")), | 141 DataRateValue (DataRate ("1.5Mbps")), |
133 MakeDataRateAccessor (&RedQueue::m_linkBandwidth), | 142 MakeDataRateAccessor (&RedQueue::m_linkBandwidth), |
134 MakeDataRateChecker ()) | 143 MakeDataRateChecker ()) |
135 .AddAttribute ("LinkDelay",· | 144 .AddAttribute ("LinkDelay",· |
136 "The RED link delay", | 145 "The RED link delay", |
137 TimeValue (MilliSeconds (20)), | 146 TimeValue (MilliSeconds (20)), |
138 MakeTimeAccessor (&RedQueue::m_linkDelay), | 147 MakeTimeAccessor (&RedQueue::m_linkDelay), |
139 MakeTimeChecker ()) | 148 MakeTimeChecker ()) |
140 ; | 149 ; |
141 | 150 |
142 return tid; | 151 return tid; |
143 } | 152 } |
144 | 153 |
145 RedQueue::RedQueue () : | 154 RedQueue::RedQueue () : |
146 Queue (), | 155 Queue (), |
147 m_packets (), | 156 m_packets (), |
148 m_bytesInQueue (0), | 157 m_bytesInQueue (0), |
149 m_redParams(false) | 158 m_hasRedStarted (false) |
150 { | 159 { |
John Abraham
2011/11/09 00:08:27
If we intend to use LinkBandwidth and delay , they
| |
151 NS_LOG_FUNCTION_NOARGS (); | 160 NS_LOG_FUNCTION_NOARGS (); |
152 } | 161 } |
153 | 162 |
154 RedQueue::~RedQueue () | 163 RedQueue::~RedQueue () |
155 { | 164 { |
156 NS_LOG_FUNCTION_NOARGS (); | 165 NS_LOG_FUNCTION_NOARGS (); |
157 } | 166 } |
158 | 167 |
159 void | 168 void |
160 RedQueue::SetMode (enum Mode mode) | 169 RedQueue::SetMode (enum Mode mode) |
161 { | 170 { |
162 NS_LOG_FUNCTION (mode); | 171 NS_LOG_FUNCTION (mode); |
163 m_mode = mode; | 172 m_mode = mode; |
164 } | 173 } |
165 | 174 |
166 RedQueue::Mode | 175 RedQueue::Mode |
167 RedQueue::GetMode (void) | 176 RedQueue::GetMode (void) |
168 { | 177 { |
169 NS_LOG_FUNCTION_NOARGS (); | 178 NS_LOG_FUNCTION_NOARGS (); |
170 return m_mode; | 179 return m_mode; |
171 } | 180 } |
172 | 181 |
173 void | 182 void |
174 RedQueue::SetQueueLimit(uint32_t lim) | 183 RedQueue::SetQueueLimit (uint32_t lim) |
Duy
2011/08/18 08:01:27
add a space here SetQueueLimit (uint32_t...
talau
2011/08/22 17:54:41
Done.
| |
175 { | 184 { |
176 NS_LOG_FUNCTION (lim); | 185 NS_LOG_FUNCTION (lim); |
177 m_queueLimit = lim; | 186 m_queueLimit = lim; |
178 } | 187 } |
179 | 188 |
180 void | 189 void |
181 RedQueue::SetTh(double min, double max) | 190 RedQueue::SetTh (double minTh, double maxTh) |
John Abraham
2011/11/09 00:08:27
as min and max are functions/macros in the std nam
talau
2011/11/27 16:16:29
Done.
| |
182 { | 191 { |
Duy
2011/08/18 08:01:27
SetTh (double...
talau
2011/08/22 17:54:41
Done.
| |
183 NS_LOG_FUNCTION (this << min << max); | 192 NS_LOG_FUNCTION (this << minTh << maxTh); |
184 m_minTh = min; | 193 NS_ASSERT(minTh <= maxTh); |
185 m_maxTh = max; | 194 m_minTh = minTh; |
195 m_maxTh = maxTh; | |
186 } | 196 } |
187 | 197 |
188 RedQueue::Stats | 198 RedQueue::Stats |
189 RedQueue::GetStats() | 199 RedQueue::GetStats () |
Duy
2011/08/18 08:01:27
GetStats ()
talau
2011/08/22 17:54:41
Done.
| |
190 { | 200 { |
191 return m_stats; | 201 return m_stats; |
192 } | 202 } |
193 | 203 |
194 bool | 204 bool |
195 RedQueue::DoEnqueue (Ptr<Packet> p) | 205 RedQueue::DoEnqueue (Ptr<Packet> p) |
196 { | 206 { |
197 NS_LOG_FUNCTION (this << p); | 207 NS_LOG_FUNCTION (this << p); |
198 | 208 |
199 if (! m_redParams ) | 209 if (! m_hasRedStarted ) |
200 { | 210 { |
201 NS_LOG_INFO ("Initializing RED params."); | 211 NS_LOG_INFO ("Initializing RED params."); |
202 InitializeParams (); | 212 InitializeParams (); |
John Abraham
2011/11/09 00:08:27
What is the advantage of calling InitializeParams
talau
2011/11/27 16:16:29
Hum, thanks for the comment. Try it.. some variabl
| |
203 m_redParams = true; | 213 m_hasRedStarted = true; |
204 } | 214 } |
205 | 215 |
206 uint32_t nQueued; | 216 uint32_t nQueued; |
207 | 217 |
208 if (GetMode () == BYTES) | 218 if (GetMode () == BYTES) |
209 { | 219 { |
210 /* | 220 NS_LOG_DEBUG ("Enqueue in bytes mode"); |
211 if (m_bytesInQueue + p->GetSize () >= m_maxBytes) | |
212 { | |
213 NS_LOG_LOGIC ("Queue full (packet would exceed max bytes) -- droppping pkt"); | |
214 Drop (p); | |
215 return false; | |
216 } | |
217 */ | |
Duy
2011/08/18 08:01:27
Why commenting this out? If it's not needed, you s
talau
2011/08/22 17:54:41
Done.
| |
218 NS_LOG_DEBUG("Enqueue in bytes mode"); | |
Duy
2011/08/18 08:01:27
NS_LOG_DEBUG ("En...
could you make sure there it'
talau
2011/08/22 17:54:41
Done.
| |
219 nQueued = m_bytesInQueue; | 221 nQueued = m_bytesInQueue; |
220 } | 222 } |
221 else if (GetMode () == PACKETS) | 223 else if (GetMode () == PACKETS) |
222 { | 224 { |
223 /* | 225 NS_LOG_DEBUG ("Enqueue in packets mode"); |
224 if (m_packets.size () >= m_maxPackets) | |
225 { | |
226 NS_LOG_LOGIC ("Queue full (at max packets) -- droppping pkt"); | |
227 Drop (p); | |
228 return false; | |
229 } | |
230 */ | |
Duy
2011/08/18 08:01:27
same thing here
talau
2011/08/22 17:54:41
Done.
| |
231 NS_LOG_DEBUG("Enqueue in packets mode"); | |
232 nQueued = m_packets.size (); | 226 nQueued = m_packets.size (); |
233 } | 227 } |
234 | 228 |
229 // simulate number of packets arrival during idle period | |
235 uint32_t m = 0; | 230 uint32_t m = 0; |
236 | 231 |
237 if (m_idle == 1) | 232 if (m_idle == 1) |
238 { | 233 { |
239 NS_LOG_DEBUG("RED Queue is idle."); | 234 NS_LOG_DEBUG ("RED Queue is idle."); |
240 Time now = Simulator::Now (); | 235 Time now = Simulator::Now (); |
241 | 236 |
242 if (m_cautious == 3) | 237 if (m_cautious == 3) |
243 { | 238 { |
244 double ptc = m_ptc * m_meanPktSize / m_idlePktSize; | 239 double ptc = m_ptc * m_meanPktSize / m_idlePktSize; |
245 m = uint32_t(ptc * (now - m_idleTime).GetSeconds()); | 240 m = uint32_t (ptc * (now - m_idleTime).GetSeconds ()); |
Duy
2011/08/18 08:01:27
make sure the coding style is consistently space,
talau
2011/08/22 17:54:41
Done.
| |
246 } | 241 } |
247 else | 242 else |
248 { | 243 { |
249 m = uint32_t(m_ptc * (now - m_idleTime).GetSeconds()); | 244 m = uint32_t (m_ptc * (now - m_idleTime).GetSeconds ()); |
250 } | 245 } |
251 | 246 |
252 m_idle = 0; | 247 m_idle = 0; |
253 } | 248 } |
254 | 249 |
255 m_qAvg = Estimator (nQueued, m + 1, m_qAvg, m_qW); | 250 m_qAvg = Estimator (nQueued, m + 1, m_qAvg, m_qW); |
256 | 251 |
257 NS_LOG_DEBUG ("\t bytesInQueue " << m_bytesInQueue << "\tQavg " << m_qAvg); | 252 NS_LOG_DEBUG ("\t bytesInQueue " << m_bytesInQueue << "\tQavg " << m_qAvg); |
258 NS_LOG_DEBUG ("\t packetsInQueue " << m_packets.size () << "\tQavg " << m_qAv g); | 253 NS_LOG_DEBUG ("\t packetsInQueue " << m_packets.size () << "\tQavg " << m_qAv g); |
259 | 254 |
260 m_count++; | 255 m_count++; |
261 m_countBytes += p->GetSize (); | 256 m_countBytes += p->GetSize (); |
262 | 257 |
263 uint32_t dropType = DTYPE_NONE; | 258 uint32_t dropType = DTYPE_NONE; |
264 if (m_qAvg >= m_minTh && nQueued > 1) | 259 if (m_qAvg >= m_minTh && nQueued > 1) |
265 { | 260 { |
266 if ((! m_gentle && m_qAvg >= m_maxTh) || | 261 if ((! m_isGentle && m_qAvg >= m_maxTh) || |
267 (m_gentle && m_qAvg >= 2 * m_maxTh)) | 262 (m_isGentle && m_qAvg >= 2 * m_maxTh)) |
268 { | 263 { |
269 NS_LOG_DEBUG ("adding DROP FORCED MARK"); | 264 NS_LOG_DEBUG ("adding DROP FORCED MARK"); |
270 dropType = DTYPE_FORCED; | 265 dropType = DTYPE_FORCED; |
271 } | 266 } |
272 else if (m_old == 0) | 267 else if (m_old == 0) |
273 { | 268 { |
274 /*· | 269 /*· |
275 * The average queue size has just crossed the | 270 * The average queue size has just crossed the |
276 * threshold from below to above "minthresh", or | 271 * threshold from below to above "minthresh", or |
277 * from above "minthresh" with an empty queue to | 272 * from above "minthresh" with an empty queue to |
278 * above "minthresh" with a nonempty queue. | 273 * above "minthresh" with a nonempty queue. |
279 */ | 274 */ |
280 m_count = 1; | 275 m_count = 1; |
281 m_countBytes = p->GetSize(); | 276 m_countBytes = p->GetSize(); |
282 m_old = 1; | 277 m_old = 1; |
283 } | 278 } |
284 else if (DropEarly(p, nQueued)) | 279 else if (DropEarly (p, nQueued)) |
John Abraham
2011/11/09 00:08:27
DropEarly (
talau
2011/11/27 16:16:29
Done.
| |
285 { | 280 { |
286 NS_LOG_LOGIC ("DropEarly returns 1"); | 281 NS_LOG_LOGIC ("DropEarly returns 1"); |
287 dropType = DTYPE_UNFORCED; | 282 dropType = DTYPE_UNFORCED; |
288 } | 283 } |
289 } | 284 } |
290 else· | 285 else· |
291 { | 286 { |
292 /* No packets are being dropped. */ | 287 // No packets are being dropped |
293 m_vProb = 0.0; | 288 m_vProb = 0.0; |
294 m_old = 0; | 289 m_old = 0; |
295 } | 290 } |
296 | 291 |
297 if (nQueued >= m_queueLimit) | 292 if (nQueued >= m_queueLimit) |
298 { | 293 { |
299 NS_LOG_LOGIC ("Queue full -- droppping pkt"); | 294 NS_LOG_DEBUG ("\t Dropping due to Queue Full " << nQueued); |
300 // see if we've exceeded the queue size | |
301 dropType = DTYPE_FORCED; | 295 dropType = DTYPE_FORCED; |
302 m_stats.pdrop++; | 296 m_stats.qLimDrop++; |
303 } | 297 } |
304 | 298 |
305 if (dropType == DTYPE_UNFORCED) | 299 if (dropType == DTYPE_UNFORCED) |
306 { | 300 { |
307 NS_LOG_DEBUG ("\t Dropping due to Prob Mark " << m_qAvg); | 301 NS_LOG_DEBUG ("\t Dropping due to Prob Mark " << m_qAvg); |
308 m_stats.unforcedDrop++; | 302 m_stats.unforcedDrop++; |
309 Drop (p); | 303 Drop (p); |
310 return false; | 304 return false; |
311 } | 305 } |
312 else if (dropType == DTYPE_FORCED) | 306 else if (dropType == DTYPE_FORCED) |
313 { | 307 { |
314 NS_LOG_DEBUG ("\t Dropping due to Hard Mark " << m_qAvg); | 308 NS_LOG_DEBUG ("\t Dropping due to Hard Mark " << m_qAvg); |
315 m_stats.forcedDrop++; | 309 m_stats.forcedDrop++; |
316 Drop (p); | 310 Drop (p); |
317 if (m_ns1Compat) | 311 if (m_isNs1Compat) |
318 { | 312 { |
319 m_count = 0; | 313 m_count = 0; |
320 m_countBytes = 0; | 314 m_countBytes = 0; |
321 } | 315 } |
322 return false; | 316 return false; |
323 } | 317 } |
324 | 318 |
325 m_bytesInQueue += p->GetSize (); | 319 m_bytesInQueue += p->GetSize (); |
326 m_packets.push_back (p); | 320 m_packets.push_back (p); |
327 | 321 |
328 NS_LOG_LOGIC ("Number packets " << m_packets.size ()); | 322 NS_LOG_LOGIC ("Number packets " << m_packets.size ()); |
329 NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue); | 323 NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue); |
330 ·· | 324 ·· |
331 return true; | 325 return true; |
332 } | 326 } |
333 | 327 |
334 /* | 328 /* |
335 * Note: if the link bandwidth changes in the course of the | 329 * Note: if the link bandwidth changes in the course of the |
336 * simulation, the bandwidth-dependent RED parameters do not change. | 330 * simulation, the bandwidth-dependent RED parameters do not change. |
337 * This should be fixed, but it would require some extra parameters, | 331 * This should be fixed, but it would require some extra parameters, |
338 * and didn't seem worth the trouble... | 332 * and didn't seem worth the trouble... |
339 */ | 333 */ |
Duy
2011/08/18 08:01:27
Does this mean that we need to make RED parameters
talau
2011/08/22 17:54:41
If the RED queue is running, yes.
| |
340 void | 334 void |
341 RedQueue::InitializeParams (void) | 335 RedQueue::InitializeParams (void) |
342 { | 336 { |
343 NS_LOG_FUNCTION_NOARGS (); | 337 NS_LOG_FUNCTION_NOARGS (); |
338 | |
339 m_stats.forcedDrop = 0; | |
340 m_stats.unforcedDrop = 0; | |
341 m_stats.qLimDrop = 0; | |
342 | |
344 m_cautious = 0; | 343 m_cautious = 0; |
345 m_ptc = m_linkBandwidth.GetBitRate () / (8.0 * m_meanPktSize); | 344 m_ptc = m_linkBandwidth.GetBitRate () / (8.0 * m_meanPktSize); |
346 ·· | 345 ·· |
347 m_curMaxP = 0.02; | |
348 | |
349 m_qAvg = 0.0; | 346 m_qAvg = 0.0; |
350 m_count = 0; | 347 m_count = 0; |
351 m_countBytes = 0; | 348 m_countBytes = 0; |
352 m_old = 0; | 349 m_old = 0; |
353 m_idle = 1; | 350 m_idle = 1; |
354 | 351 |
355 double th_diff = (m_maxTh - m_minTh); | 352 double th_diff = (m_maxTh - m_minTh); |
John Abraham
2011/11/09 00:08:27
Have we done tests where max and min are the same,
| |
356 if (th_diff == 0) | 353 if (th_diff == 0) |
357 { | 354 { |
358 //XXX this last check was added by a person who knows | |
359 //nothing of this code just to stop FP div by zero. | |
360 //Values for thresholds were equal at time 0. If you | |
361 //know what should be here, please cleanup and remove | |
362 //this comment. | |
Duy
2011/08/18 08:01:27
use block comments for longer comments
talau
2011/08/22 17:54:41
Done.
| |
363 th_diff = 1.0;· | 355 th_diff = 1.0;· |
364 } | 356 } |
365 m_vA = 1.0 / th_diff; | 357 m_vA = 1.0 / th_diff; |
366 m_curMaxP = 1.0 / m_lInterm; | 358 m_curMaxP = 1.0 / m_lInterm; |
367 m_vB = - m_minTh / th_diff; | 359 m_vB = - m_minTh / th_diff; |
368 ·· | 360 ·· |
369 if (m_gentle) | 361 if (m_isGentle) |
370 { | 362 { |
371 m_vC = (1.0 - m_curMaxP) / m_maxTh; | 363 m_vC = (1.0 - m_curMaxP) / m_maxTh; |
372 m_vD = 2.0 * m_curMaxP - 1.0; | 364 m_vD = 2.0 * m_curMaxP - 1.0; |
373 } | 365 } |
374 m_idleTime = NanoSeconds (0); | 366 m_idleTime = NanoSeconds (0); |
375 | 367 |
376 /* | 368 /* |
377 * If q_weight=0, set it to a reasonable value of 1-exp(-1/C) | 369 * If m_qW=0, set it to a reasonable value of 1-exp(-1/C) |
378 * This corresponds to choosing q_weight to be of that value for | 370 * This corresponds to choosing m_qW to be of that value for |
379 * which the packet time constant -1/ln(1-q_weight) per default RTT· | 371 * which the packet time constant -1/ln(1-m)qW) per default RTT· |
380 * of 100ms is an order of magnitude more than the link capacity, C. | 372 * of 100ms is an order of magnitude more than the link capacity, C. |
381 * | 373 * |
382 * If q_weight=-1, then the queue weight is set to be a function of | 374 * If m_qW=-1, then the queue weight is set to be a function of |
383 * the bandwidth and the link propagation delay. In particular,· | 375 * the bandwidth and the link propagation delay. In particular,· |
384 * the default RTT is assumed to be three times the link delay and· | 376 * the default RTT is assumed to be three times the link delay and· |
385 * transmission delay, if this gives a default RTT greater than 100 ms.· | 377 * transmission delay, if this gives a default RTT greater than 100 ms.· |
386 * | 378 * |
387 * If q_weight=-2, set it to a reasonable value of 1-exp(-10/C). | 379 * If m_qW=-2, set it to a reasonable value of 1-exp(-10/C). |
388 */ | 380 */ |
389 if (m_qW == 0.0) | 381 if (m_qW == 0.0) |
390 { | 382 { |
391 m_qW = 1.0 - exp(-1.0 / m_ptc); | 383 m_qW = 1.0 - exp(-1.0 / m_ptc); |
392 } | 384 } |
393 else if (m_qW == -1.0) | 385 else if (m_qW == -1.0) |
394 { | 386 { |
395 double rtt = 3.0 * (m_linkDelay.GetSeconds () + 1.0 / m_ptc); | 387 double rtt = 3.0 * (m_linkDelay.GetSeconds () + 1.0 / m_ptc); |
396 | 388 |
397 if (rtt < 0.1) | 389 if (rtt < 0.1) |
398 { | 390 { |
399 rtt = 0.1; | 391 rtt = 0.1; |
400 } | 392 } |
401 m_qW = 1.0 - exp(-1.0 / (10 * rtt * m_ptc)); | 393 m_qW = 1.0 - exp(-1.0 / (10 * rtt * m_ptc)); |
402 } | 394 } |
403 else if (m_qW == -2.0) | 395 else if (m_qW == -2.0) |
404 { | 396 { |
405 m_qW = 1.0 - exp(-10.0 / m_ptc); | 397 m_qW = 1.0 - exp(-10.0 / m_ptc); |
406 } | 398 } |
407 | 399 |
408 if (m_minPacketsTh == 0) | 400 // TODO: implement adaptive RED |
409 { | 401 |
410 m_minPacketsTh = 5.0; | 402 NS_LOG_DEBUG ("\tm_delay " << m_linkDelay.GetSeconds () << "; m_isWait " << m_ isWait << "; m_qW " << m_qW << "; m_ptc " << m_ptc << "; m_minTh " << m_minTh << "; m_maxTh " << m_maxTh << "; m_isGentle " << m_isGentle << "; th_diff " << th_ diff << "; lInterm " << m_lInterm << "; va " << m_vA << "; cur_max_p " << m_cur MaxP << "; v_b " << m_vB << "; m_vC " << m_vC << "; m_vD " << m_vD); |
411 | 403 } |
412 // TODO: implement adaptive RED | 404 |
413 } | 405 // Compute the average queue size |
414 | |
415 NS_LOG_DEBUG ("\tm_delay " << m_linkDelay.GetSeconds () << "; m_wait " << m_wa it << "; m_qW " << m_qW << "; m_ptc " << m_ptc << "; m_minTh " << m_minTh << "; m_maxTh " << m_maxTh << "; m_gentle " << m_gentle << "; th_diff " << th_diff << "; lInternm " << m_lInterm << "; va " << m_vA << "; cur_max_p " << m_curMaxP << "; v_b " << m_vB << "; m_vC " << m_vC << "; m_vD " << m_vD); | |
416 } | |
417 | |
418 // compute the average queue size | |
419 double | 406 double |
420 RedQueue::Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW) | 407 RedQueue::Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW) |
421 { | 408 { |
422 NS_LOG_FUNCTION (this << nQueued << m << qAvg << qW); | 409 NS_LOG_FUNCTION (this << nQueued << m << qAvg << qW); |
423 double newAve; | 410 double newAve; |
424 | 411 |
425 newAve = qAvg; | 412 newAve = qAvg; |
426 while (--m >= 1) | 413 while (--m >= 1) |
427 { | 414 { |
428 newAve *= 1.0 - qW; | 415 newAve *= 1.0 - qW; |
429 } | 416 } |
430 newAve *= 1.0 - qW; | 417 newAve *= 1.0 - qW; |
431 newAve += qW * nQueued; | 418 newAve += qW * nQueued; |
432 | 419 |
433 // TODO: implement adaptive RED | 420 // TODO: implement adaptive RED |
434 /* | |
435 Time now = Simulator::Now (); | |
436 if (m_adaptative == 1) | |
437 { | |
438 if (m_fengAdaptative == 1) | |
439 { | |
440 UpdateMaxPFeng(newAve); | |
441 } | |
442 else if () | |
443 } | |
444 */ | |
Duy
2011/08/18 08:01:27
You can remove this block of comments as well
talau
2011/08/22 17:54:41
Done.
| |
445 | 421 |
446 return newAve; | 422 return newAve; |
447 } | 423 } |
448 | 424 |
425 // Check if packet p needs to be dropped due to probability mark | |
449 uint32_t | 426 uint32_t |
450 RedQueue::DropEarly (Ptr<Packet> p, uint32_t qSize) | 427 RedQueue::DropEarly (Ptr<Packet> p, uint32_t qSize) |
451 { | 428 { |
452 NS_LOG_FUNCTION (this << p << qSize); | 429 NS_LOG_FUNCTION (this << p << qSize); |
453 m_vProb1 = CalculatePNew(m_qAvg, m_maxTh, m_gentle, m_vA, m_vB, m_vC, m_vD, m_ curMaxP); | 430 m_vProb1 = CalculatePNew(m_qAvg, m_maxTh, m_isGentle, m_vA, m_vB, m_vC, m_vD, m_curMaxP); |
454 m_vProb = ModifyP(m_vProb1, m_count, m_countBytes, m_meanPktSize, m_wait, p->G etSize ()); | 431 m_vProb = ModifyP(m_vProb1, m_count, m_countBytes, m_meanPktSize, m_isWait, p- >GetSize ()); |
455 | 432 |
456 // drop probability is computed, pick random number and act | 433 // Drop probability is computed, pick random number and act |
457 if (m_cautious == 1) | 434 if (m_cautious == 1) |
458 { | 435 { |
459 // Don't drop/mark if the instantaneous queue is much | 436 /* |
460 // below the average. | 437 * Don't drop/mark if the instantaneous queue is much below the average. |
461 // For experimental purposes only. | 438 * For experimental purposes only. |
462 // pkts: the number of packets arriving in 50 ms | 439 * pkts: the number of packets arriving in 50 ms |
Duy
2011/08/18 08:01:27
use block comments
talau
2011/08/22 17:54:41
Done.
| |
440 */ | |
463 double pkts = m_ptc * 0.05; | 441 double pkts = m_ptc * 0.05; |
464 double fraction = pow ((1 - m_qW), pkts); | 442 double fraction = pow ((1 - m_qW), pkts); |
465 // double fraction = 0.9; | 443 |
466 if ((double) qSize < fraction * m_qAvg) | 444 if ((double) qSize < fraction * m_qAvg) |
467 { | 445 { |
468 // queue could have been empty for 0.05 seconds | 446 // Queue could have been empty for 0.05 seconds |
469 // printf("fraction: %5.2f\n", fraction); don't worry :P | |
470 return 0; | 447 return 0; |
471 } | 448 } |
472 } | 449 } |
473 | 450 |
474 UniformVariable uV; | 451 UniformVariable uV; |
475 double u = uV.GetValue (); | 452 double u = uV.GetValue (); |
476 | 453 |
477 if (m_cautious == 2) | 454 if (m_cautious == 2) |
478 { | 455 { |
479 // Decrease the drop probability if the instantaneous | 456 /* |
480 // queue is much below the average. | 457 * Decrease the drop probability if the instantaneous |
481 // For experimental purposes only. | 458 * queue is much below the average. |
482 // pkts: the number of packets arriving in 50 ms | 459 * For experimental purposes only. |
Duy
2011/08/18 08:01:27
use block comment
talau
2011/08/22 17:54:41
Done.
| |
460 * pkts: the number of packets arriving in 50 ms | |
461 */ | |
483 double pkts = m_ptc * 0.05; | 462 double pkts = m_ptc * 0.05; |
484 double fraction = pow ((1 - m_qW), pkts); | 463 double fraction = pow ((1 - m_qW), pkts); |
485 // double fraction = 0.9; | |
486 double ratio = qSize / (fraction * m_qAvg); | 464 double ratio = qSize / (fraction * m_qAvg); |
487 | 465 |
488 if (ratio < 1.0) | 466 if (ratio < 1.0) |
489 { | 467 { |
490 u *= 1.0 / ratio; | 468 u *= 1.0 / ratio; |
491 } | 469 } |
492 } | 470 } |
493 | 471 |
494 if (u <= m_vProb) | 472 if (u <= m_vProb) |
495 { | 473 { |
474 NS_LOG_LOGIC ("u <= m_vProb; u " << u << "; m_vProb " << m_vProb); | |
475 | |
496 // DROP or MARK | 476 // DROP or MARK |
497 m_count = 0; | 477 m_count = 0; |
498 m_countBytes = 0; | 478 m_countBytes = 0; |
499 /* TODO: implement set bit to mark */ | 479 // TODO: Implement set bit to mark |
500 | 480 |
501 return 1; // drop | 481 return 1; // drop |
502 } | 482 } |
503 | 483 |
504 return 0; // no drop/mark | 484 return 0; // no drop/mark |
505 } | 485 } |
506 | 486 |
487 // Returns a probability using these function parameters for the DropEarly funti on | |
507 double | 488 double |
508 RedQueue::CalculatePNew (double qAvg, double maxTh, bool gentle, double vA, | 489 RedQueue::CalculatePNew (double qAvg, double maxTh, bool isGentle, double vA, |
509 double vB, double vC, double vD, double maxP) | 490 double vB, double vC, double vD, double maxP) |
510 { | 491 { |
511 NS_LOG_FUNCTION (this << qAvg << maxTh << gentle << vA << vB << vC << vD << ma xP); | 492 NS_LOG_FUNCTION (this << qAvg << maxTh << isGentle << vA << vB << vC << vD << maxP); |
512 double p; | 493 double p; |
513 | 494 |
514 if (gentle && qAvg >= maxTh) | 495 if (isGentle && qAvg >= maxTh) |
515 { | 496 { |
516 // p ranges from maxP to 1 as the average queue | 497 // p ranges from maxP to 1 as the average queue |
517 // size ranges from maxTh to twice maxTh | 498 // Size ranges from maxTh to twice maxTh |
518 p = vC * qAvg + vD; | 499 p = vC * qAvg + vD; |
519 } | 500 } |
520 else if (!gentle && qAvg >= maxTh) | 501 else if (!isGentle && qAvg >= maxTh) |
521 { | 502 { |
522 // OLD: p continues to range linearly above max_p as | 503 /*· |
523 // the average queue size ranges above th_max. | 504 * OLD: p continues to range linearly above max_p as |
524 // NEW: p is set to 1.0 | 505 * the average queue size ranges above th_max. |
506 * NEW: p is set to 1.0 | |
507 */ | |
525 p = 1.0; | 508 p = 1.0; |
526 } | 509 } |
527 else | 510 else |
528 { | 511 { |
529 // p ranges from 0 to max_p as the average queue | 512 /* |
530 // size ranges from th_min to th_max | 513 * p ranges from 0 to max_p as the average queue size ranges from |
514 * th_min to th_max | |
515 */ | |
531 p = vA * qAvg + vB; | 516 p = vA * qAvg + vB; |
532 // p = (qAvg - m_minTh) / (maxTh - minTh) | |
Duy
2011/08/18 08:01:27
if you don't need it, you should remove it
talau
2011/08/22 17:54:41
Done.
| |
533 p *= maxP; | 517 p *= maxP; |
534 } | 518 } |
535 | 519 |
536 if (p > 1.0) | 520 if (p > 1.0) |
537 { | 521 { |
538 p = 1.0; | 522 p = 1.0; |
539 } | 523 } |
540 | 524 |
541 return p; | 525 return p; |
542 } | 526 } |
543 | 527 |
528 // Returns a probability using these function parameters for the DropEarly funti on | |
544 double· | 529 double· |
545 RedQueue::ModifyP(double p, uint32_t count, uint32_t countBytes, | 530 RedQueue::ModifyP (double p, uint32_t count, uint32_t countBytes, |
546 uint32_t meanPktSize, bool wait, uint32_t size) | 531 uint32_t meanPktSize, bool isWait, uint32_t size) |
547 { | 532 { |
548 NS_LOG_FUNCTION (this << p << count << countBytes << meanPktSize << wait << si ze); | 533 NS_LOG_FUNCTION (this << p << count << countBytes << meanPktSize << isWait << size); |
549 double count1 = (double) count; | 534 double count1 = (double) count; |
550 | 535 |
551 if (GetMode () == BYTES) | 536 if (GetMode () == BYTES) |
552 { | 537 { |
553 count1 = (double) (countBytes / meanPktSize); | 538 count1 = (double) (countBytes / meanPktSize); |
554 } | 539 } |
555 | 540 |
556 if (wait) | 541 if (isWait) |
557 { | 542 { |
558 if (count1 * p < 1.0) | 543 if (count1 * p < 1.0) |
559 { | 544 { |
560 p = 0.0; | 545 p = 0.0; |
561 } | 546 } |
562 else if (count1 * p < 2.0) | 547 else if (count1 * p < 2.0) |
563 { | 548 { |
564 p /= (2.0 - count1 * p); | 549 p /= (2.0 - count1 * p); |
565 } | 550 } |
566 else | 551 else |
567 { | 552 { |
568 p = 1.0; | 553 p = 1.0; |
569 } | 554 } |
570 } | 555 } |
571 else | 556 else |
572 { | 557 { |
573 if (count1 * p < 1.0) | 558 if (count1 * p < 1.0) |
574 { | 559 { |
575 p /= (1.0 - count1 * p); | 560 p /= (1.0 - count1 * p); |
576 } | 561 } |
577 else | 562 else |
578 { | 563 { |
579 p = 1.0; | 564 p = 1.0; |
580 } | 565 } |
581 } | 566 } |
582 | 567 |
583 if ((GetMode () == BYTES) && (p < 1.0)) | 568 if ((GetMode () == BYTES) && (p < 1.0)) |
584 { | 569 { |
585 p = (p * size) / meanPktSize; | 570 p = (p * size) / meanPktSize; |
586 //p = p * (size / meanPktSize); | |
Duy
2011/08/18 08:01:27
remove this dead code as well
talau
2011/08/22 17:54:41
Done.
| |
587 } | 571 } |
588 | 572 |
589 if (p > 1.0) | 573 if (p > 1.0) |
590 { | 574 { |
591 p = 1.0; | 575 p = 1.0; |
592 } | 576 } |
593 | 577 |
594 return p; | 578 return p; |
595 } | 579 } |
596 | 580 |
597 uint32_t | 581 uint32_t |
598 RedQueue::GetQueueSize (void) | 582 RedQueue::GetQueueSize (void) |
599 { | 583 { |
600 NS_LOG_FUNCTION_NOARGS (); | 584 NS_LOG_FUNCTION_NOARGS (); |
601 if (GetMode () == BYTES) | 585 if (GetMode () == BYTES) |
602 { | 586 { |
603 return m_bytesInQueue; | 587 return m_bytesInQueue; |
604 } | 588 } |
605 else // packets | 589 else if (GetMode () == PACKETS) |
Duy
2011/08/18 08:01:27
It's better if we make it explicit,
else if (GetM
talau
2011/08/22 17:54:41
Done.
| |
606 { | 590 { |
607 return m_packets.size (); | 591 return m_packets.size (); |
592 } | |
593 else | |
594 { | |
595 NS_ABORT_MSG ("Unknown RED mode."); | |
608 } | 596 } |
609 } | 597 } |
610 | 598 |
611 Ptr<Packet> | 599 Ptr<Packet> |
612 RedQueue::DoDequeue (void) | 600 RedQueue::DoDequeue (void) |
613 { | 601 { |
614 NS_LOG_FUNCTION (this); | 602 NS_LOG_FUNCTION (this); |
615 | 603 |
616 if (m_packets.empty ()) | 604 if (m_packets.empty ()) |
617 { | 605 { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
649 | 637 |
650 Ptr<Packet> p = m_packets.front (); | 638 Ptr<Packet> p = m_packets.front (); |
651 | 639 |
652 NS_LOG_LOGIC ("Number packets " << m_packets.size ()); | 640 NS_LOG_LOGIC ("Number packets " << m_packets.size ()); |
653 NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue); | 641 NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue); |
654 | 642 |
655 return p; | 643 return p; |
656 } | 644 } |
657 | 645 |
658 } // namespace ns3 | 646 } // namespace ns3 |
LEFT | RIGHT |