aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs122
1 files changed, 84 insertions, 38 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
index d696265..e0633d3 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
@@ -113,36 +113,65 @@ namespace OpenSim.Region.ClientStack.LindenUDP
113 /// The speed limit of this bucket in bytes per second. This is the 113 /// The speed limit of this bucket in bytes per second. This is the
114 /// number of tokens that are added to the bucket per quantum 114 /// number of tokens that are added to the bucket per quantum
115 /// </summary> 115 /// </summary>
116 /// <remarks>Tokens are added to the bucket any time 116 /// <remarks>
117 /// RequestedDripRate can never be above MaxDripRate.
118 /// Tokens are added to the bucket any time
117 /// <seealso cref="RemoveTokens"/> is called, at the granularity of 119 /// <seealso cref="RemoveTokens"/> is called, at the granularity of
118 /// the system tick interval (typically around 15-22ms)</remarks> 120 /// the system tick interval (typically around 15-22ms)</remarks>
119 protected Int64 m_dripRate; 121 protected Int64 m_dripRate;
120 public virtual Int64 RequestedDripRate 122 public virtual Int64 RequestedDripRate
121 { 123 {
122 get { return (m_dripRate == 0 ? TotalDripRequest : m_dripRate); } 124 get { return (m_dripRate == 0 ? TotalDripRequest : m_dripRate); }
123 set { 125 set
124 m_dripRate = (value < 0 ? 0 : value); 126 {
125 m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); 127 if (value <= 0)
128 m_dripRate = 0;
129 else if (MaxDripRate > 0 && value > MaxDripRate)
130 m_dripRate = MaxDripRate;
131 else
132 m_dripRate = value;
133
126 TotalDripRequest = m_dripRate; 134 TotalDripRequest = m_dripRate;
135 m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst);
136
127 if (Parent != null) 137 if (Parent != null)
128 Parent.RegisterRequest(this,m_dripRate); 138 Parent.RegisterRequest(this, m_dripRate);
129 } 139 }
130 } 140 }
131 141
142 /// <summary>
143 /// Gets the drip rate.
144 /// </summary>
145 /// <value>DripRate can never be above max.</value>
132 public virtual Int64 DripRate 146 public virtual Int64 DripRate
133 { 147 {
134 get { 148 get
149 {
135 if (Parent == null) 150 if (Parent == null)
136 return Math.Min(RequestedDripRate, TotalDripRequest); 151 return Math.Min(RequestedDripRate, TotalDripRequest);
137 152
138 double rate = (double)RequestedDripRate * Parent.DripRateModifier(); 153 double rate = (double)RequestedDripRate * Parent.DripRateModifier();
139 if (rate < m_minimumDripRate) 154 if (rate < m_minimumDripRate)
140 rate = m_minimumDripRate; 155 rate = m_minimumDripRate;
156 else if (MaxDripRate > 0 && rate > MaxDripRate)
157 rate = MaxDripRate;
141 158
142 return (Int64)rate; 159 return (Int64)rate;
143 } 160 }
144 } 161 }
145 162
163 // <summary>
164 // The maximum rate for flow control. Drip rate can never be greater than this.
165 // </summary>
166// protected Int64 m_maxDripRate;
167// public Int64 MaxDripRate
168// {
169// get { return m_maxDripRate; }
170// //get { return (m_maxDripRate == 0 ? TotalDripRequest : m_maxDripRate); }
171// set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value, m_minimumFlow)); }
172// }
173 public Int64 MaxDripRate { get; set; }
174
146 /// <summary> 175 /// <summary>
147 /// The current total of the requested maximum burst rates of 176 /// The current total of the requested maximum burst rates of
148 /// this bucket's children buckets. 177 /// this bucket's children buckets.
@@ -161,12 +190,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
161 /// null if this is a root bucket</param> 190 /// null if this is a root bucket</param>
162 /// <param name="dripRate">Rate that the bucket fills, in bytes per 191 /// <param name="dripRate">Rate that the bucket fills, in bytes per
163 /// second. If zero, the bucket always remains full</param> 192 /// second. If zero, the bucket always remains full</param>
164 public TokenBucket(string identifier, TokenBucket parent, Int64 dripRate) 193 public TokenBucket(string identifier, TokenBucket parent, Int64 dripRate, Int64 maxDripRate)
165 { 194 {
166 Identifier = identifier; 195 Identifier = identifier;
167 196
168 Parent = parent; 197 Parent = parent;
169 RequestedDripRate = dripRate; 198 RequestedDripRate = dripRate;
199 MaxDripRate = maxDripRate;
170 // TotalDripRequest = dripRate; // this will be overwritten when a child node registers 200 // TotalDripRequest = dripRate; // this will be overwritten when a child node registers
171 // MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst); 201 // MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst);
172 m_lastDrip = Util.EnvironmentTickCount(); 202 m_lastDrip = Util.EnvironmentTickCount();
@@ -184,7 +214,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
184 protected double DripRateModifier() 214 protected double DripRateModifier()
185 { 215 {
186 Int64 driprate = DripRate; 216 Int64 driprate = DripRate;
187 return driprate >= TotalDripRequest ? 1.0 : (double)driprate / (double)TotalDripRequest; 217 double modifier = driprate >= TotalDripRequest ? 1.0 : (double)driprate / (double)TotalDripRequest;
218
219// if (DebugLevel > 0)
220// m_log.DebugFormat(
221// "[TOKEN BUCKET]: Returning drip modifier {0}/{1} = {2} from {3}",
222// driprate, TotalDripRequest, modifier, Identifier);
223
224 return modifier;
188 } 225 }
189 226
190 /// <summary> 227 /// <summary>
@@ -215,7 +252,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
215 252
216 // Pass the new values up to the parent 253 // Pass the new values up to the parent
217 if (Parent != null) 254 if (Parent != null)
218 Parent.RegisterRequest(this,Math.Min(RequestedDripRate, TotalDripRequest)); 255 {
256 Int64 effectiveDripRate;
257
258 if (MaxDripRate > 0)
259 effectiveDripRate = Math.Min(MaxDripRate, TotalDripRequest);
260 else
261 effectiveDripRate = TotalDripRequest;
262
263 //Parent.RegisterRequest(this, Math.Min(RequestedDripRate, TotalDripRequest));
264 Parent.RegisterRequest(this, effectiveDripRate);
265 }
219 } 266 }
220 267
221 /// <summary> 268 /// <summary>
@@ -309,61 +356,60 @@ namespace OpenSim.Region.ClientStack.LindenUDP
309 356
310 public class AdaptiveTokenBucket : TokenBucket 357 public class AdaptiveTokenBucket : TokenBucket
311 { 358 {
312 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 359 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
360
361 public bool AdaptiveEnabled { get; set; }
313 362
314 /// <summary> 363 /// <summary>
315 /// The minimum rate for flow control. Minimum drip rate is one 364 /// Target drip rate for this bucket.
316 /// packet per second. Open the throttle to 15 packets per second
317 /// or about 160kbps.
318 /// </summary> 365 /// </summary>
319 protected const Int64 m_minimumFlow = m_minimumDripRate * 15; 366 /// <remarks>Usually set by the client. If adaptive is enabled then throttles will increase until we reach this.</remarks>
320 367 public Int64 TargetDripRate
321 // <summary> 368 {
322 // The maximum rate for flow control. Drip rate can never be 369 get { return m_targetDripRate; }
323 // greater than this. 370 set { m_targetDripRate = Math.Max(0, value); }
324 // </summary>
325 protected Int64 m_maxDripRate = 0;
326 public Int64 MaxDripRate
327 {
328 get { return (m_maxDripRate == 0 ? TotalDripRequest : m_maxDripRate); }
329 set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); }
330 } 371 }
372 protected Int64 m_targetDripRate;
331 373
332 public bool Enabled { get; set; }
333
334 // <summary> 374 // <summary>
335 // 375 // Adjust drip rate in response to network conditions.
336 // </summary> 376 // </summary>
337 public virtual Int64 AdjustedDripRate 377 public virtual Int64 AdjustedDripRate
338 { 378 {
339 get { return m_dripRate; } 379 get { return m_dripRate; }
340 set { 380 set {
341 m_dripRate = OpenSim.Framework.Util.Clamp<Int64>(value,m_minimumFlow,MaxDripRate); 381 m_dripRate = OpenSim.Framework.Util.Clamp<Int64>(value, m_minimumFlow, TargetDripRate);
342 m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); 382 m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst);
343 if (Parent != null) 383 if (Parent != null)
344 Parent.RegisterRequest(this, m_dripRate); 384 Parent.RegisterRequest(this, m_dripRate);
345 } 385 }
346 } 386 }
387
388 /// <summary>
389 /// The minimum rate for flow control. Minimum drip rate is one
390 /// packet per second. Open the throttle to 15 packets per second
391 /// or about 160kbps.
392 /// </summary>
393 protected const Int64 m_minimumFlow = m_minimumDripRate * 15;
347 394
348 public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 maxDripRate, bool enabled) 395 public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 dripRate, Int64 maxDripRate, bool enabled)
349 : base(identifier, parent, maxDripRate) 396 : base(identifier, parent, dripRate, maxDripRate)
350 { 397 {
351 Enabled = enabled; 398 AdaptiveEnabled = enabled;
352 399
353 if (Enabled) 400 if (AdaptiveEnabled)
354 { 401 {
355// m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled"); 402// m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled");
356 MaxDripRate = maxDripRate;
357 AdjustedDripRate = m_minimumFlow; 403 AdjustedDripRate = m_minimumFlow;
358 } 404 }
359 } 405 }
360 406
361 // <summary> 407 // <summary>
362 // 408 // Reliable packets sent to the client for which we never received an ack adjust the drip rate down.
363 // </summary> 409 // </summary>
364 public void ExpirePackets(Int32 count) 410 public void ExpirePackets(Int32 count)
365 { 411 {
366 if (Enabled) 412 if (AdaptiveEnabled)
367 { 413 {
368 if (DebugLevel > 0) 414 if (DebugLevel > 0)
369 m_log.WarnFormat( 415 m_log.WarnFormat(
@@ -375,12 +421,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
375 } 421 }
376 422
377 // <summary> 423 // <summary>
378 // 424 // Reliable packets acked by the client adjust the drip rate up.
379 // </summary> 425 // </summary>
380 public void AcknowledgePackets(Int32 count) 426 public void AcknowledgePackets(Int32 count)
381 { 427 {
382 if (Enabled) 428 if (AdaptiveEnabled)
383 AdjustedDripRate = AdjustedDripRate + count; 429 AdjustedDripRate = AdjustedDripRate + count;
384 } 430 }
385 } 431 }
386} 432} \ No newline at end of file