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