diff options
author | John Hurliman | 2009-10-21 00:18:35 -0700 |
---|---|---|
committer | John Hurliman | 2009-10-21 00:18:35 -0700 |
commit | cde47c2b3d7089be556252246eb03365c1f39b54 (patch) | |
tree | b0b1cddc57f786a2d5945c1117cddda75e52b1ed /OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |
parent | * Added a sanity check to GetScriptAssemblies() and GetScriptStates() for the... (diff) | |
download | opensim-SC_OLD-cde47c2b3d7089be556252246eb03365c1f39b54.zip opensim-SC_OLD-cde47c2b3d7089be556252246eb03365c1f39b54.tar.gz opensim-SC_OLD-cde47c2b3d7089be556252246eb03365c1f39b54.tar.bz2 opensim-SC_OLD-cde47c2b3d7089be556252246eb03365c1f39b54.tar.xz |
Committing Jim's optimization to replace the 20ms sleep in outgoing packet handling with an interruptible wait handle
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 134cfe5..b9d2c15 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -105,9 +105,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
105 | public int TickLastPacketReceived; | 105 | public int TickLastPacketReceived; |
106 | /// <summary>Environment.TickCount of the last time the outgoing packet handler executed for this client</summary> | 106 | /// <summary>Environment.TickCount of the last time the outgoing packet handler executed for this client</summary> |
107 | public int TickLastOutgoingPacketHandler; | 107 | public int TickLastOutgoingPacketHandler; |
108 | /// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler executed for this client</summary> | ||
109 | public int ElapsedMSOutgoingPacketHandler; | ||
110 | /// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed for this client</summary> | ||
111 | public int Elapsed100MSOutgoingPacketHandler; | ||
112 | /// <summary>Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed for this client</summary> | ||
113 | public int Elapsed500MSOutgoingPacketHandler; | ||
108 | 114 | ||
109 | /// <summary>Timer granularity. This is set to the measured resolution of Environment.TickCount</summary> | ||
110 | public readonly float G; | ||
111 | /// <summary>Smoothed round-trip time. A smoothed average of the round-trip time for sending a | 115 | /// <summary>Smoothed round-trip time. A smoothed average of the round-trip time for sending a |
112 | /// reliable packet to the client and receiving an ACK</summary> | 116 | /// reliable packet to the client and receiving an ACK</summary> |
113 | public float SRTT; | 117 | public float SRTT; |
@@ -182,15 +186,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
182 | m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type)); | 186 | m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type)); |
183 | } | 187 | } |
184 | 188 | ||
185 | // Set the granularity variable used for retransmission calculations to | ||
186 | // the measured resolution of Environment.TickCount | ||
187 | G = server.TickCountResolution; | ||
188 | |||
189 | // Default the retransmission timeout to three seconds | 189 | // Default the retransmission timeout to three seconds |
190 | RTO = 3000; | 190 | RTO = 3000; |
191 | 191 | ||
192 | // Initialize this to a sane value to prevent early disconnects | 192 | // Initialize this to a sane value to prevent early disconnects |
193 | TickLastPacketReceived = Environment.TickCount; | 193 | TickLastPacketReceived = Environment.TickCount & Int32.MaxValue; |
194 | ElapsedMSOutgoingPacketHandler = 0; | ||
195 | Elapsed100MSOutgoingPacketHandler = 0; | ||
196 | Elapsed500MSOutgoingPacketHandler = 0; | ||
194 | } | 197 | } |
195 | 198 | ||
196 | /// <summary> | 199 | /// <summary> |
@@ -391,6 +394,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
391 | { | 394 | { |
392 | // Not enough tokens in the bucket, queue this packet | 395 | // Not enough tokens in the bucket, queue this packet |
393 | queue.Enqueue(packet); | 396 | queue.Enqueue(packet); |
397 | m_udpServer.SignalOutgoingPacketHandler(); | ||
394 | return true; | 398 | return true; |
395 | } | 399 | } |
396 | } | 400 | } |
@@ -407,13 +411,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
407 | /// </summary> | 411 | /// </summary> |
408 | /// <remarks>This function is only called from a synchronous loop in the | 412 | /// <remarks>This function is only called from a synchronous loop in the |
409 | /// UDPServer so we don't need to bother making this thread safe</remarks> | 413 | /// UDPServer so we don't need to bother making this thread safe</remarks> |
410 | /// <returns>True if any packets were sent, otherwise false</returns> | 414 | /// <returns>The minimum amount of time before the next packet |
411 | public bool DequeueOutgoing() | 415 | /// can be sent to this client</returns> |
416 | public int DequeueOutgoing() | ||
412 | { | 417 | { |
413 | OutgoingPacket packet; | 418 | OutgoingPacket packet; |
414 | OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; | 419 | OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; |
415 | TokenBucket bucket; | 420 | TokenBucket bucket; |
416 | bool packetSent = false; | 421 | int dataLength; |
422 | int minTimeout = Int32.MaxValue; | ||
417 | 423 | ||
418 | //string queueDebugOutput = String.Empty; // Serious debug business | 424 | //string queueDebugOutput = String.Empty; // Serious debug business |
419 | 425 | ||
@@ -428,12 +434,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
428 | // leaving a dequeued packet still waiting to be sent out. Try to | 434 | // leaving a dequeued packet still waiting to be sent out. Try to |
429 | // send it again | 435 | // send it again |
430 | OutgoingPacket nextPacket = m_nextPackets[i]; | 436 | OutgoingPacket nextPacket = m_nextPackets[i]; |
431 | if (bucket.RemoveTokens(nextPacket.Buffer.DataLength)) | 437 | dataLength = nextPacket.Buffer.DataLength; |
438 | if (bucket.RemoveTokens(dataLength)) | ||
432 | { | 439 | { |
433 | // Send the packet | 440 | // Send the packet |
434 | m_udpServer.SendPacketFinal(nextPacket); | 441 | m_udpServer.SendPacketFinal(nextPacket); |
435 | m_nextPackets[i] = null; | 442 | m_nextPackets[i] = null; |
436 | packetSent = true; | 443 | minTimeout = 0; |
444 | } | ||
445 | else if (minTimeout != 0) | ||
446 | { | ||
447 | // Check the minimum amount of time we would have to wait before this packet can be sent out | ||
448 | minTimeout = Math.Min(minTimeout, ((dataLength - bucket.Content) / bucket.DripPerMS) + 1); | ||
437 | } | 449 | } |
438 | } | 450 | } |
439 | else | 451 | else |
@@ -445,16 +457,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
445 | { | 457 | { |
446 | // A packet was pulled off the queue. See if we have | 458 | // A packet was pulled off the queue. See if we have |
447 | // enough tokens in the bucket to send it out | 459 | // enough tokens in the bucket to send it out |
448 | if (bucket.RemoveTokens(packet.Buffer.DataLength)) | 460 | dataLength = packet.Buffer.DataLength; |
461 | if (bucket.RemoveTokens(dataLength)) | ||
449 | { | 462 | { |
450 | // Send the packet | 463 | // Send the packet |
451 | m_udpServer.SendPacketFinal(packet); | 464 | m_udpServer.SendPacketFinal(packet); |
452 | packetSent = true; | 465 | minTimeout = 0; |
453 | } | 466 | } |
454 | else | 467 | else |
455 | { | 468 | { |
456 | // Save the dequeued packet for the next iteration | 469 | // Save the dequeued packet for the next iteration |
457 | m_nextPackets[i] = packet; | 470 | m_nextPackets[i] = packet; |
471 | |||
472 | if (minTimeout != 0) | ||
473 | { | ||
474 | // Check the minimum amount of time we would have to wait before this packet can be sent out | ||
475 | minTimeout = Math.Min(minTimeout, ((dataLength - bucket.Content) / bucket.DripPerMS) + 1); | ||
476 | } | ||
458 | } | 477 | } |
459 | 478 | ||
460 | // If the queue is empty after this dequeue, fire the queue | 479 | // If the queue is empty after this dequeue, fire the queue |
@@ -473,7 +492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
473 | } | 492 | } |
474 | 493 | ||
475 | //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business | 494 | //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business |
476 | return packetSent; | 495 | return minTimeout; |
477 | } | 496 | } |
478 | 497 | ||
479 | /// <summary> | 498 | /// <summary> |
@@ -504,7 +523,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
504 | } | 523 | } |
505 | 524 | ||
506 | // Always round retransmission timeout up to two seconds | 525 | // Always round retransmission timeout up to two seconds |
507 | RTO = Math.Max(2000, (int)(SRTT + Math.Max(G, K * RTTVAR))); | 526 | RTO = Math.Max(2000, (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR))); |
508 | //m_log.Debug("[LLUDPCLIENT]: Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " + | 527 | //m_log.Debug("[LLUDPCLIENT]: Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " + |
509 | // RTTVAR + " based on new RTT of " + r + "ms"); | 528 | // RTTVAR + " based on new RTT of " + r + "ms"); |
510 | } | 529 | } |