aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
diff options
context:
space:
mode:
authorUbitUmarov2014-09-02 15:48:59 +0100
committerUbitUmarov2014-09-02 15:48:59 +0100
commit50433e089b548d3e9233b897568b7def489323fb (patch)
tree6e07ac5ce845ada8b2916736920278269079b53e /OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
parentmake use of it in GetMeshModule, and meshs are Assets not Task itens, (diff)
downloadopensim-SC-50433e089b548d3e9233b897568b7def489323fb.zip
opensim-SC-50433e089b548d3e9233b897568b7def489323fb.tar.gz
opensim-SC-50433e089b548d3e9233b897568b7def489323fb.tar.bz2
opensim-SC-50433e089b548d3e9233b897568b7def489323fb.tar.xz
*needs testing, not that good* change throttles math using floats and not
int64, etc. Limite brust bytes to the total rate client requested times a look ahead estimation time, Avoid queues starvation with updates waiting...
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs61
1 files changed, 36 insertions, 25 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index f91abfe..45013b3 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -144,8 +144,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
144 get { return m_throttleClient; } 144 get { return m_throttleClient; }
145 } 145 }
146 146
147 /// <summary>Throttle bucket for this agent's connection</summary>
148 private readonly TokenBucket m_throttleCategory;
149 /// <summary>Throttle buckets for each packet category</summary> 147 /// <summary>Throttle buckets for each packet category</summary>
150 private readonly TokenBucket[] m_throttleCategories; 148 private readonly TokenBucket[] m_throttleCategories;
151 /// <summary>Outgoing queues for throttled packets</summary> 149 /// <summary>Outgoing queues for throttled packets</summary>
@@ -163,6 +161,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
163 private int m_maxRTO = 60000; 161 private int m_maxRTO = 60000;
164 public bool m_deliverPackets = true; 162 public bool m_deliverPackets = true;
165 163
164 private float m_burstTime;
165
166 public int m_lastStartpingTimeMS; 166 public int m_lastStartpingTimeMS;
167 public int m_pingMS; 167 public int m_pingMS;
168 168
@@ -216,17 +216,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
216 if (maxRTO != 0) 216 if (maxRTO != 0)
217 m_maxRTO = maxRTO; 217 m_maxRTO = maxRTO;
218 218
219 m_burstTime = rates.BrustTime;
220 float m_burst = rates.ClientMaxRate * m_burstTime;
221
219 // Create a token bucket throttle for this client that has the scene token bucket as a parent 222 // Create a token bucket throttle for this client that has the scene token bucket as a parent
220 m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled); 223 m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.ClientMaxRate, m_burst, rates.AdaptiveThrottlesEnabled);
221 // Create a token bucket throttle for the total categary with the client bucket as a throttle
222 m_throttleCategory = new TokenBucket(m_throttleClient, 0);
223 // Create an array of token buckets for this clients different throttle categories 224 // Create an array of token buckets for this clients different throttle categories
224 m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; 225 m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
225 226
226 m_cannibalrate = rates.CannibalizeTextureRate; 227 m_cannibalrate = rates.CannibalizeTextureRate;
227 228
228 long totalrate = 0; 229 m_burst = rates.Total * rates.BrustTime;
229 long catrate = 0;
230 230
231 for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) 231 for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
232 { 232 {
@@ -235,13 +235,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
235 // Initialize the packet outboxes, where packets sit while they are waiting for tokens 235 // Initialize the packet outboxes, where packets sit while they are waiting for tokens
236 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>(); 236 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
237 // Initialize the token buckets that control the throttling for each category 237 // Initialize the token buckets that control the throttling for each category
238 catrate = rates.GetRate(type); 238 m_throttleCategories[i] = new TokenBucket(m_throttleClient, rates.GetRate(type), m_burst);
239 totalrate += catrate;
240 m_throttleCategories[i] = new TokenBucket(m_throttleCategory, catrate);
241 } 239 }
242 240
243 m_throttleCategory.RequestedDripRate = totalrate;
244
245 // Default the retransmission timeout to one second 241 // Default the retransmission timeout to one second
246 RTO = m_defaultRTO; 242 RTO = m_defaultRTO;
247 243
@@ -285,7 +281,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
285 m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; 281 m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate;
286 m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; 282 m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
287 m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; 283 m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
288 m_info.totalThrottle = (int)m_throttleCategory.DripRate; 284 m_info.totalThrottle = (int)m_throttleClient.DripRate;
289 285
290 return m_info; 286 return m_info;
291 } 287 }
@@ -373,6 +369,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
373 369
374 // Make sure none of the throttles are set below our packet MTU, 370 // Make sure none of the throttles are set below our packet MTU,
375 // otherwise a throttle could become permanently clogged 371 // otherwise a throttle could become permanently clogged
372
373/* not using floats
376 resend = Math.Max(resend, LLUDPServer.MTU); 374 resend = Math.Max(resend, LLUDPServer.MTU);
377 land = Math.Max(land, LLUDPServer.MTU); 375 land = Math.Max(land, LLUDPServer.MTU);
378 wind = Math.Max(wind, LLUDPServer.MTU); 376 wind = Math.Max(wind, LLUDPServer.MTU);
@@ -380,6 +378,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
380 task = Math.Max(task, LLUDPServer.MTU); 378 task = Math.Max(task, LLUDPServer.MTU);
381 texture = Math.Max(texture, LLUDPServer.MTU); 379 texture = Math.Max(texture, LLUDPServer.MTU);
382 asset = Math.Max(asset, LLUDPServer.MTU); 380 asset = Math.Max(asset, LLUDPServer.MTU);
381*/
383 382
384 // Since most textures are now delivered through http, make it possible 383 // Since most textures are now delivered through http, make it possible
385 // to cannibalize some of the bw from the texture throttle to use for 384 // to cannibalize some of the bw from the texture throttle to use for
@@ -388,7 +387,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
388 texture = (int)((1 - m_cannibalrate) * texture); 387 texture = (int)((1 - m_cannibalrate) * texture);
389 388
390 int total = resend + land + wind + cloud + task + texture + asset; 389 int total = resend + land + wind + cloud + task + texture + asset;
391 390
391 float m_burst = total * m_burstTime;
392
392 //m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}", 393 //m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}",
393 // AgentID, resend, land, wind, cloud, task, texture, asset, total); 394 // AgentID, resend, land, wind, cloud, task, texture, asset, total);
394 395
@@ -397,26 +398,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
397 398
398 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; 399 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend];
399 bucket.RequestedDripRate = resend; 400 bucket.RequestedDripRate = resend;
401 bucket.RequestedBurst = m_burst;
400 402
401 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; 403 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land];
402 bucket.RequestedDripRate = land; 404 bucket.RequestedDripRate = land;
405 bucket.RequestedBurst = m_burst;
403 406
404 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; 407 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind];
405 bucket.RequestedDripRate = wind; 408 bucket.RequestedDripRate = wind;
409 bucket.RequestedBurst = m_burst;
406 410
407 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; 411 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud];
408 bucket.RequestedDripRate = cloud; 412 bucket.RequestedDripRate = cloud;
413 bucket.RequestedBurst = m_burst;
409 414
410 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; 415 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset];
411 bucket.RequestedDripRate = asset; 416 bucket.RequestedDripRate = asset;
417 bucket.RequestedBurst = m_burst;
412 418
413 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; 419 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task];
414 bucket.RequestedDripRate = task; 420 bucket.RequestedDripRate = task;
421 bucket.RequestedBurst = m_burst;
415 422
416 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; 423 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture];
417 bucket.RequestedDripRate = texture; 424 bucket.RequestedDripRate = texture;
418 425 bucket.RequestedBurst = m_burst;
419 m_throttleCategory.RequestedDripRate = total;
420 426
421 // Reset the packed throttles cached data 427 // Reset the packed throttles cached data
422 m_packedThrottles = null; 428 m_packedThrottles = null;
@@ -465,10 +471,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
465 471
466 public int GetCatBytesCanSend(ThrottleOutPacketType cat, int timeMS) 472 public int GetCatBytesCanSend(ThrottleOutPacketType cat, int timeMS)
467 { 473 {
468 TokenBucket bucket = m_throttleCategories[(int)cat]; 474 int icat = (int)cat;
469 int bytes = timeMS * (int)(bucket.RequestedDripRate / 1000); 475 if (icat > 0 && icat < THROTTLE_CATEGORY_COUNT)
470 bytes += (int)bucket.CurrentTokenCount(); 476 {
471 return bytes; 477 TokenBucket bucket = m_throttleCategories[icat];
478 return bucket.GetCatBytesCanSend(timeMS);
479 }
480 else
481 return 0;
472 } 482 }
473 483
474 /// <summary> 484 /// <summary>
@@ -572,6 +582,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
572 m_udpServer.SendPacketFinal(nextPacket); 582 m_udpServer.SendPacketFinal(nextPacket);
573 m_nextPackets[i] = null; 583 m_nextPackets[i] = null;
574 packetSent = true; 584 packetSent = true;
585
586 if (m_packetOutboxes[i].Count < 5)
587 emptyCategories |= CategoryToFlag(i);
575 } 588 }
576 } 589 }
577 else 590 else
@@ -599,6 +612,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
599 // Send the packet 612 // Send the packet
600 m_udpServer.SendPacketFinal(packet); 613 m_udpServer.SendPacketFinal(packet);
601 packetSent = true; 614 packetSent = true;
615
616 if (queue.Count < 5)
617 emptyCategories |= CategoryToFlag(i);
602 } 618 }
603 else 619 else
604 { 620 {
@@ -606,11 +622,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
606 m_nextPackets[i] = packet; 622 m_nextPackets[i] = packet;
607 } 623 }
608 624
609 // If the queue is empty after this dequeue, fire the queue
610 // empty callback now so it has a chance to fill before we
611 // get back here
612 if (queue.Count == 0)
613 emptyCategories |= CategoryToFlag(i);
614 } 625 }
615 else 626 else
616 { 627 {