diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 8f14806206..de9185651a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -229,7 +229,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_throttleClient
= new AdaptiveTokenBucket(
string.Format("adaptive throttle for {0} in {1}", AgentID, server.Scene.Name),
- parentThrottle, 0, rates.Total, rates.AdaptiveThrottlesEnabled);
+ parentThrottle, 0, rates.Total, rates.MinimumAdaptiveThrottleRate, rates.AdaptiveThrottlesEnabled);
// Create an array of token buckets for this clients different throttle categories
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs
index dd15cc7d4f..7a2756bab1 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs
@@ -58,7 +58,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Flag used to enable adaptive throttles
public bool AdaptiveThrottlesEnabled;
-
+
+ ///
+ /// Set the minimum rate that the adaptive throttles can set. The viewer
+ /// can still throttle lower than this, but the adaptive throttles will
+ /// never decrease rates below this no matter how many packets are dropped
+ ///
+ public Int64 MinimumAdaptiveThrottleRate;
+
/// Amount of the texture throttle to steal for the task throttle
public double CannibalizeTextureRate;
@@ -84,7 +91,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Total = throttleConfig.GetInt("client_throttle_max_bps", 0);
AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false);
-
+ MinimumAdaptiveThrottleRate = throttleConfig.GetInt("adaptive_throttle_min_bps", 32000);
+
CannibalizeTextureRate = (double)throttleConfig.GetFloat("CannibalizeTextureRate", 0.0f);
CannibalizeTextureRate = Util.Clamp(CannibalizeTextureRate,0.0, 0.9);
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
index d215595c7b..c0cdff6d90 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
@@ -392,13 +392,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
///
- /// The minimum rate for flow control. Minimum drip rate is one
- /// packet per second. Open the throttle to 15 packets per second
- /// or about 160kbps.
+ /// The minimum rate for adaptive flow control.
///
- protected const Int64 m_minimumFlow = m_minimumDripRate * 15;
+ protected Int64 m_minimumFlow = 32000;
+ public Int64 MinimumFlow
+ {
+ get { return m_minimumFlow; }
+ set
+ {
+ m_minimumFlow = value;
+ TargetDripRate = Math.Max(m_minimumFlow, TargetDripRate);
+ AdjustedDripRate = Math.Max(m_minimumFlow, AdjustedDripRate);
+ }
+ }
- public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 requestedDripRate, Int64 maxDripRate, bool enabled)
+ ///
+ /// Constructor for the AdaptiveTokenBucket class
+ /// Unique identifier for the client
+ /// Parent bucket in the hierarchy
+ ///
+ /// The ceiling rate for adaptation
+ /// The floor rate for adaptation
+ ///
+ public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 requestedDripRate, Int64 maxDripRate, Int64 minDripRate, bool enabled)
: base(identifier, parent, requestedDripRate, maxDripRate)
{
AdaptiveEnabled = enabled;
@@ -406,34 +422,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (AdaptiveEnabled)
{
// m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled");
+ m_minimumFlow = minDripRate;
TargetDripRate = m_minimumFlow;
AdjustedDripRate = m_minimumFlow;
}
}
- //
- // Reliable packets sent to the client for which we never received an ack adjust the drip rate down.
- //
- public void ExpirePackets(Int32 count)
+ ///
+ /// Reliable packets sent to the client for which we never received an ack adjust the drip rate down.
+ /// Number of packets that expired without successful delivery
+ ///
+ public void ExpirePackets(Int32 packets)
{
if (AdaptiveEnabled)
{
if (DebugLevel > 0)
m_log.WarnFormat(
"[ADAPTIVEBUCKET] drop {0} by {1} expired packets for {2}",
- AdjustedDripRate, count, Identifier);
+ AdjustedDripRate, packets, Identifier);
- AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count));
+ AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,packets));
}
}
- //
- // Reliable packets acked by the client adjust the drip rate up.
- //
- public void AcknowledgePackets(Int32 count)
+ ///
+ /// Reliable packets acked by the client adjust the drip rate up.
+ /// Number of bytes acknowledged
+ ///
+ public void AcknowledgePackets(Int32 bytes)
{
if (AdaptiveEnabled)
- AdjustedDripRate = AdjustedDripRate + count;
+ AdjustedDripRate = AdjustedDripRate + bytes;
}
}
}
\ No newline at end of file
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 3e9514ebbf..212baabc7f 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -544,6 +544,13 @@
;
;client_throttle_max_bps = 187500
+ ; Minimum bytes per second to send to any single client as a result of
+ ; adaptive throttling. Viewer preferences set to a lower number will
+ ; override the settin. The example given here ensures that adaptive
+ ; throttling will never decrease per client bandwidth below 256 kbps.
+ ;
+ ;adaptive_throttle_min_bps = 32000
+
; Adaptive throttling attempts to limit network overload when multiple
; clients login by starting each connection more slowly. Disabled by
; default