diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | 82 |
1 files changed, 37 insertions, 45 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 7be8a0a..ca5501d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -135,7 +135,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
135 | private int m_nextOnQueueEmpty = 1; | 135 | private int m_nextOnQueueEmpty = 1; |
136 | 136 | ||
137 | /// <summary>Throttle bucket for this agent's connection</summary> | 137 | /// <summary>Throttle bucket for this agent's connection</summary> |
138 | private readonly TokenBucket m_throttleClient; | 138 | private readonly AdaptiveTokenBucket m_throttleClient; |
139 | public AdaptiveTokenBucket FlowThrottle | ||
140 | { | ||
141 | get { return m_throttleClient; } | ||
142 | } | ||
143 | |||
139 | /// <summary>Throttle bucket for this agent's connection</summary> | 144 | /// <summary>Throttle bucket for this agent's connection</summary> |
140 | private readonly TokenBucket m_throttleCategory; | 145 | private readonly TokenBucket m_throttleCategory; |
141 | /// <summary>Throttle buckets for each packet category</summary> | 146 | /// <summary>Throttle buckets for each packet category</summary> |
@@ -176,9 +181,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
176 | m_maxRTO = maxRTO; | 181 | m_maxRTO = maxRTO; |
177 | 182 | ||
178 | // Create a token bucket throttle for this client that has the scene token bucket as a parent | 183 | // Create a token bucket throttle for this client that has the scene token bucket as a parent |
179 | m_throttleClient = new TokenBucket(parentThrottle, rates.TotalLimit); | 184 | m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled); |
180 | // Create a token bucket throttle for the total categary with the client bucket as a throttle | 185 | // Create a token bucket throttle for the total categary with the client bucket as a throttle |
181 | m_throttleCategory = new TokenBucket(m_throttleClient, rates.TotalLimit); | 186 | m_throttleCategory = new TokenBucket(m_throttleClient, 0); |
182 | // Create an array of token buckets for this clients different throttle categories | 187 | // Create an array of token buckets for this clients different throttle categories |
183 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; | 188 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; |
184 | 189 | ||
@@ -189,7 +194,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
189 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens | 194 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens |
190 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); | 195 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); |
191 | // Initialize the token buckets that control the throttling for each category | 196 | // Initialize the token buckets that control the throttling for each category |
192 | m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetLimit(type)); | 197 | m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type)); |
193 | } | 198 | } |
194 | 199 | ||
195 | // Default the retransmission timeout to three seconds | 200 | // Default the retransmission timeout to three seconds |
@@ -223,26 +228,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
223 | /// <returns>Information about the client connection</returns> | 228 | /// <returns>Information about the client connection</returns> |
224 | public ClientInfo GetClientInfo() | 229 | public ClientInfo GetClientInfo() |
225 | { | 230 | { |
226 | ///<mic> | ||
227 | TokenBucket tb; | ||
228 | |||
229 | tb = m_throttleClient.Parent; | ||
230 | m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest,"ROOT"); | ||
231 | |||
232 | tb = m_throttleClient; | ||
233 | m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CLIENT"); | ||
234 | |||
235 | tb = m_throttleCategory; | ||
236 | m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CATEGORY"); | ||
237 | |||
238 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) | ||
239 | { | ||
240 | tb = m_throttleCategories[i]; | ||
241 | m_log.WarnFormat("[TOKENS] {4} <{0}:{1}>: Actual={2},Requested={3}",AgentID,i,tb.DripRate,tb.RequestedDripRate," BUCKET"); | ||
242 | } | ||
243 | |||
244 | ///</mic> | ||
245 | |||
246 | // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists | 231 | // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists |
247 | // of pending and needed ACKs for every client every time some method wants information about | 232 | // of pending and needed ACKs for every client every time some method wants information about |
248 | // this connection is a recipe for poor performance | 233 | // this connection is a recipe for poor performance |
@@ -254,12 +239,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
254 | info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; | 239 | info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; |
255 | info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; | 240 | info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; |
256 | info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; | 241 | info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; |
257 | // info.taskThrottle = m_throttleCategories[(int)ThrottleOutPacketType.State].DripRate + m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; | ||
258 | info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; | 242 | info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; |
259 | info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; | 243 | info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; |
260 | info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; | 244 | info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; |
261 | info.totalThrottle = info.resendThrottle + info.landThrottle + info.windThrottle + info.cloudThrottle + | 245 | info.totalThrottle = (int)m_throttleCategory.DripRate; |
262 | info.taskThrottle + info.assetThrottle + info.textureThrottle; | ||
263 | 246 | ||
264 | return info; | 247 | return info; |
265 | } | 248 | } |
@@ -346,8 +329,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
346 | int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); | 329 | int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); |
347 | // State is a subcategory of task that we allocate a percentage to | 330 | // State is a subcategory of task that we allocate a percentage to |
348 | int state = 0; | 331 | int state = 0; |
349 | // int state = (int)((float)task * STATE_TASK_PERCENTAGE); | ||
350 | // task -= state; | ||
351 | 332 | ||
352 | // Make sure none of the throttles are set below our packet MTU, | 333 | // Make sure none of the throttles are set below our packet MTU, |
353 | // otherwise a throttle could become permanently clogged | 334 | // otherwise a throttle could become permanently clogged |
@@ -358,19 +339,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
358 | task = Math.Max(task, LLUDPServer.MTU); | 339 | task = Math.Max(task, LLUDPServer.MTU); |
359 | texture = Math.Max(texture, LLUDPServer.MTU); | 340 | texture = Math.Max(texture, LLUDPServer.MTU); |
360 | asset = Math.Max(asset, LLUDPServer.MTU); | 341 | asset = Math.Max(asset, LLUDPServer.MTU); |
361 | state = Math.Max(state, LLUDPServer.MTU); | ||
362 | |||
363 | int total = resend + land + wind + cloud + task + texture + asset + state; | ||
364 | 342 | ||
365 | //m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, Total={9}", | 343 | //int total = resend + land + wind + cloud + task + texture + asset; |
366 | // AgentID, resend, land, wind, cloud, task, texture, asset, state, total); | 344 | //m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}", |
345 | // AgentID, resend, land, wind, cloud, task, texture, asset, total); | ||
367 | 346 | ||
368 | // Update the token buckets with new throttle values | 347 | // Update the token buckets with new throttle values |
369 | TokenBucket bucket; | 348 | TokenBucket bucket; |
370 | 349 | ||
371 | bucket = m_throttleCategory; | ||
372 | bucket.RequestedDripRate = total; | ||
373 | |||
374 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; | 350 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; |
375 | bucket.RequestedDripRate = resend; | 351 | bucket.RequestedDripRate = resend; |
376 | 352 | ||
@@ -399,22 +375,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
399 | m_packedThrottles = null; | 375 | m_packedThrottles = null; |
400 | } | 376 | } |
401 | 377 | ||
402 | public byte[] GetThrottlesPacked() | 378 | public byte[] GetThrottlesPacked(float multiplier) |
403 | { | 379 | { |
404 | byte[] data = m_packedThrottles; | 380 | byte[] data = m_packedThrottles; |
405 | 381 | ||
406 | if (data == null) | 382 | if (data == null) |
407 | { | 383 | { |
384 | float rate; | ||
385 | |||
408 | data = new byte[7 * 4]; | 386 | data = new byte[7 * 4]; |
409 | int i = 0; | 387 | int i = 0; |
410 | 388 | ||
411 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate), 0, data, i, 4); i += 4; | 389 | // multiply by 8 to convert bytes back to bits |
412 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate), 0, data, i, 4); i += 4; | 390 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate * 8 * multiplier; |
413 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate), 0, data, i, 4); i += 4; | 391 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; |
414 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate), 0, data, i, 4); i += 4; | 392 | |
415 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate), 0, data, i, 4); i += 4; | 393 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate * 8 * multiplier; |
416 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate), 0, data, i, 4); i += 4; | 394 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; |
417 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate), 0, data, i, 4); i += 4; | 395 | |
396 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate * 8 * multiplier; | ||
397 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; | ||
398 | |||
399 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate * 8 * multiplier; | ||
400 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; | ||
401 | |||
402 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate * 8 * multiplier; | ||
403 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; | ||
404 | |||
405 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate * 8 * multiplier; | ||
406 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; | ||
407 | |||
408 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate * 8 * multiplier; | ||
409 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; | ||
418 | 410 | ||
419 | m_packedThrottles = data; | 411 | m_packedThrottles = data; |
420 | } | 412 | } |