aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs82
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 }