aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-10-11 23:28:53 +0100
committerJustin Clark-Casey (justincc)2012-10-11 23:28:53 +0100
commit1f2472d0fcd86a7ae09c01ecb3508eab001ce033 (patch)
tree2668a8dc7ede987d1b104292508c311c03a37e59 /OpenSim
parentAssign endVector before control leaves ObjectCommandsModule.TryParseVectorRan... (diff)
downloadopensim-SC-1f2472d0fcd86a7ae09c01ecb3508eab001ce033.zip
opensim-SC-1f2472d0fcd86a7ae09c01ecb3508eab001ce033.tar.gz
opensim-SC-1f2472d0fcd86a7ae09c01ecb3508eab001ce033.tar.bz2
opensim-SC-1f2472d0fcd86a7ae09c01ecb3508eab001ce033.tar.xz
Extend "show stats" command to "show stats [list|all|<category name>]"
This allows different categories of stats to be shown, with options to list categories or show all stats. Currently categories are scene and simulator and only a very few stats are currently registered via this mechanism. This commit also adds percentage stats for packets and blocks reused from the packet pool.
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs16
-rw-r--r--OpenSim/Framework/Monitoring/StatsManager.cs193
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs32
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs72
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs43
5 files changed, 259 insertions, 97 deletions
diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
index 8ac9090..aa86202 100644
--- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
@@ -359,13 +359,19 @@ Asset service request failures: {3}" + Environment.NewLine,
359 inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime, 359 inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
360 netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime)); 360 netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
361 361
362 foreach (KeyValuePair<string, Stat> kvp in StatsManager.RegisteredStats) 362 Dictionary<string, Dictionary<string, Stat>> sceneStats;
363 {
364 Stat stat = kvp.Value;
365 363
366 if (stat.Category == "scene" && stat.Verbosity == StatVerbosity.Info) 364 if (StatsManager.TryGetStats("scene", out sceneStats))
365 {
366 foreach (KeyValuePair<string, Dictionary<string, Stat>> kvp in sceneStats)
367 { 367 {
368 sb.AppendFormat("Slow frames ({0}): {1}\n", stat.Container, stat.Value); 368 foreach (Stat stat in kvp.Value.Values)
369 {
370 if (stat.Verbosity == StatVerbosity.Info)
371 {
372 sb.AppendFormat("{0} ({1}): {2}{3}\n", stat.Name, stat.Container, stat.Value, stat.UnitName);
373 }
374 }
369 } 375 }
370 } 376 }
371 377
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index b5dc24f..a67c5f8 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenSim.Framework.Console;
30 31
31namespace OpenSim.Framework.Monitoring 32namespace OpenSim.Framework.Monitoring
32{ 33{
@@ -35,13 +36,23 @@ namespace OpenSim.Framework.Monitoring
35 /// </summary> 36 /// </summary>
36 public class StatsManager 37 public class StatsManager
37 { 38 {
39 // Subcommand used to list other stats.
40 public const string AllSubCommand = "all";
41
42 // Subcommand used to list other stats.
43 public const string ListSubCommand = "list";
44
45 // All subcommands
46 public static HashSet<string> SubCommands = new HashSet<string> { AllSubCommand, ListSubCommand };
47
38 /// <summary> 48 /// <summary>
39 /// Registered stats. 49 /// Registered stats categorized by category/container/shortname
40 /// </summary> 50 /// </summary>
41 /// <remarks> 51 /// <remarks>
42 /// Do not add or remove from this dictionary. 52 /// Do not add or remove directly from this dictionary.
43 /// </remarks> 53 /// </remarks>
44 public static Dictionary<string, Stat> RegisteredStats = new Dictionary<string, Stat>(); 54 public static Dictionary<string, Dictionary<string, Dictionary<string, Stat>>> RegisteredStats
55 = new Dictionary<string, Dictionary<string, Dictionary<string, Stat>>>();
45 56
46 private static AssetStatsCollector assetStats; 57 private static AssetStatsCollector assetStats;
47 private static UserStatsCollector userStats; 58 private static UserStatsCollector userStats;
@@ -51,6 +62,76 @@ namespace OpenSim.Framework.Monitoring
51 public static UserStatsCollector UserStats { get { return userStats; } } 62 public static UserStatsCollector UserStats { get { return userStats; } }
52 public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } } 63 public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
53 64
65 public static void RegisterConsoleCommands(CommandConsole console)
66 {
67 console.Commands.AddCommand(
68 "General",
69 false,
70 "show stats",
71 "show stats [list|all|<category>]",
72 "Show statistical information for this server",
73 "If no final argument is specified then legacy statistics information is currently shown.\n"
74 + "If list is specified then statistic categories are shown.\n"
75 + "If all is specified then all registered statistics are shown.\n"
76 + "If a category name is specified then only statistics from that category are shown.\n"
77 + "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
78 HandleShowStatsCommand);
79 }
80
81 public static void HandleShowStatsCommand(string module, string[] cmd)
82 {
83 ICommandConsole con = MainConsole.Instance;
84
85 if (cmd.Length > 2)
86 {
87 var categoryName = cmd[2];
88
89 if (categoryName == AllSubCommand)
90 {
91 foreach (var category in RegisteredStats.Values)
92 {
93 OutputCategoryStatsToConsole(con, category);
94 }
95 }
96 else if (categoryName == ListSubCommand)
97 {
98 con.Output("Statistic categories available are:");
99 foreach (string category in RegisteredStats.Keys)
100 con.OutputFormat(" {0}", category);
101 }
102 else
103 {
104 Dictionary<string, Dictionary<string, Stat>> category;
105 if (!RegisteredStats.TryGetValue(categoryName, out category))
106 {
107 con.OutputFormat("No such category as {0}", categoryName);
108 }
109 else
110 {
111 OutputCategoryStatsToConsole(con, category);
112 }
113 }
114 }
115 else
116 {
117 // Legacy
118 con.Output(SimExtraStats.Report());
119 }
120 }
121
122 private static void OutputCategoryStatsToConsole(
123 ICommandConsole con, Dictionary<string, Dictionary<string, Stat>> category)
124 {
125 foreach (var container in category.Values)
126 {
127 foreach (Stat stat in container.Values)
128 {
129 con.OutputFormat(
130 "{0}.{1}.{2} : {3}{4}", stat.Category, stat.Container, stat.ShortName, stat.Value, stat.UnitName);
131 }
132 }
133 }
134
54 /// <summary> 135 /// <summary>
55 /// Start collecting statistics related to assets. 136 /// Start collecting statistics related to assets.
56 /// Should only be called once. 137 /// Should only be called once.
@@ -73,43 +154,100 @@ namespace OpenSim.Framework.Monitoring
73 return userStats; 154 return userStats;
74 } 155 }
75 156
157 /// <summary>
158 /// Registers a statistic.
159 /// </summary>
160 /// <param name='stat'></param>
161 /// <returns></returns>
76 public static bool RegisterStat(Stat stat) 162 public static bool RegisterStat(Stat stat)
77 { 163 {
164 Dictionary<string, Dictionary<string, Stat>> category = null, newCategory;
165 Dictionary<string, Stat> container = null, newContainer;
166
78 lock (RegisteredStats) 167 lock (RegisteredStats)
79 { 168 {
80 if (RegisteredStats.ContainsKey(stat.UniqueName)) 169 // Stat name is not unique across category/container/shortname key.
81 { 170 // XXX: For now just return false. This is to avoid problems in regression tests where all tests
82 // XXX: For now just return false. This is to avoid problems in regression tests where all tests 171 // in a class are run in the same instance of the VM.
83 // in a class are run in the same instance of the VM. 172 if (TryGetStat(stat, out category, out container))
84 return false; 173 return false;
85 174
86// throw new Exception( 175 // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed.
87// "StatsManager already contains stat with ShortName {0} in Category {1}", stat.ShortName, stat.Category); 176 // This means that we don't need to lock or copy them on iteration, which will be a much more
88 } 177 // common operation after startup.
178 if (container != null)
179 newContainer = new Dictionary<string, Stat>(container);
180 else
181 newContainer = new Dictionary<string, Stat>();
182
183 if (category != null)
184 newCategory = new Dictionary<string, Dictionary<string, Stat>>(category);
185 else
186 newCategory = new Dictionary<string, Dictionary<string, Stat>>();
89 187
90 // We take a replace-on-write approach here so that we don't need to generate a new Dictionary 188 newContainer[stat.ShortName] = stat;
91 Dictionary<string, Stat> newRegisteredStats = new Dictionary<string, Stat>(RegisteredStats); 189 newCategory[stat.Container] = newContainer;
92 newRegisteredStats[stat.UniqueName] = stat; 190 RegisteredStats[stat.Category] = newCategory;
93 RegisteredStats = newRegisteredStats;
94 } 191 }
95 192
96 return true; 193 return true;
97 } 194 }
98 195
196 /// <summary>
197 /// Deregister a statistic
198 /// </summary>>
199 /// <param name='stat'></param>
200 /// <returns></returns
99 public static bool DeregisterStat(Stat stat) 201 public static bool DeregisterStat(Stat stat)
100 { 202 {
203 Dictionary<string, Dictionary<string, Stat>> category = null, newCategory;
204 Dictionary<string, Stat> container = null, newContainer;
205
101 lock (RegisteredStats) 206 lock (RegisteredStats)
102 { 207 {
103 if (!RegisteredStats.ContainsKey(stat.UniqueName)) 208 if (!TryGetStat(stat, out category, out container))
104 return false; 209 return false;
105 210
106 Dictionary<string, Stat> newRegisteredStats = new Dictionary<string, Stat>(RegisteredStats); 211 newContainer = new Dictionary<string, Stat>(container);
107 newRegisteredStats.Remove(stat.UniqueName); 212 newContainer.Remove(stat.UniqueName);
108 RegisteredStats = newRegisteredStats; 213
214 newCategory = new Dictionary<string, Dictionary<string, Stat>>(category);
215 newCategory.Remove(stat.Container);
216
217 newCategory[stat.Container] = newContainer;
218 RegisteredStats[stat.Category] = newCategory;
109 219
110 return true; 220 return true;
111 } 221 }
112 } 222 }
223
224 public static bool TryGetStats(string category, out Dictionary<string, Dictionary<string, Stat>> stats)
225 {
226 return RegisteredStats.TryGetValue(category, out stats);
227 }
228
229 public static bool TryGetStat(
230 Stat stat,
231 out Dictionary<string, Dictionary<string, Stat>> category,
232 out Dictionary<string, Stat> container)
233 {
234 category = null;
235 container = null;
236
237 lock (RegisteredStats)
238 {
239 if (RegisteredStats.TryGetValue(stat.Category, out category))
240 {
241 if (category.TryGetValue(stat.Container, out container))
242 {
243 if (container.ContainsKey(stat.ShortName))
244 return true;
245 }
246 }
247 }
248
249 return false;
250 }
113 } 251 }
114 252
115 /// <summary> 253 /// <summary>
@@ -157,9 +295,26 @@ namespace OpenSim.Framework.Monitoring
157 295
158 public virtual double Value { get; set; } 296 public virtual double Value { get; set; }
159 297
298 /// <summary>
299 /// Constructor
300 /// </summary>
301 /// <param name='shortName'>Short name for the stat. Must not contain spaces. e.g. "LongFrames"</param>
302 /// <param name='name'>Human readable name for the stat. e.g. "Long frames"</param>
303 /// <param name='unitName'>
304 /// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
305 /// e.g. " frames"
306 /// </param>
307 /// <param name='category'>Category under which this stat should appear, e.g. "scene". Do not capitalize.</param>
308 /// <param name='container'>Entity to which this stat relates. e.g. scene name if this is a per scene stat.</param>
309 /// <param name='verbosity'>Verbosity of stat. Controls whether it will appear in short stat display or only full display.</param>
310 /// <param name='description'>Description of stat</param>
160 public Stat( 311 public Stat(
161 string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description) 312 string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description)
162 { 313 {
314 if (StatsManager.SubCommands.Contains(category))
315 throw new Exception(
316 string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category));
317
163 ShortName = shortName; 318 ShortName = shortName;
164 Name = name; 319 Name = name;
165 UnitName = unitName; 320 UnitName = unitName;
@@ -203,7 +358,7 @@ namespace OpenSim.Framework.Monitoring
203 358
204 public PercentageStat( 359 public PercentageStat(
205 string shortName, string name, string category, string container, StatVerbosity verbosity, string description) 360 string shortName, string name, string category, string container, StatVerbosity verbosity, string description)
206 : base(shortName, name, " %", category, container, verbosity, description) 361 : base(shortName, name, "%", category, container, verbosity, description)
207 { 362 {
208 } 363 }
209 } 364 }
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 7a5c16d..aac9c45 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -96,11 +96,6 @@ namespace OpenSim.Framework.Servers
96 get { return m_httpServer; } 96 get { return m_httpServer; }
97 } 97 }
98 98
99 /// <summary>
100 /// Holds the non-viewer statistics collection object for this service/server
101 /// </summary>
102 protected IStatsCollector m_stats;
103
104 public BaseOpenSimServer() 99 public BaseOpenSimServer()
105 { 100 {
106 m_startuptime = DateTime.Now; 101 m_startuptime = DateTime.Now;
@@ -177,10 +172,6 @@ namespace OpenSim.Framework.Servers
177 "show info", 172 "show info",
178 "Show general information about the server", HandleShow); 173 "Show general information about the server", HandleShow);
179 174
180 m_console.Commands.AddCommand("General", false, "show stats",
181 "show stats",
182 "Show statistics", HandleShow);
183
184 m_console.Commands.AddCommand("General", false, "show threads", 175 m_console.Commands.AddCommand("General", false, "show threads",
185 "show threads", 176 "show threads",
186 "Show thread status", HandleShow); 177 "Show thread status", HandleShow);
@@ -226,12 +217,7 @@ namespace OpenSim.Framework.Servers
226 { 217 {
227 StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n"); 218 StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n");
228 sb.Append(GetUptimeReport()); 219 sb.Append(GetUptimeReport());
229 220 sb.Append(StatsManager.SimExtraStats.Report());
230 if (m_stats != null)
231 {
232 sb.Append(m_stats.Report());
233 }
234
235 sb.Append(Environment.NewLine); 221 sb.Append(Environment.NewLine);
236 sb.Append(GetThreadsReport()); 222 sb.Append(GetThreadsReport());
237 223
@@ -382,10 +368,6 @@ namespace OpenSim.Framework.Servers
382 { 368 {
383 Notice("set log level [level] - change the console logging level only. For example, off or debug."); 369 Notice("set log level [level] - change the console logging level only. For example, off or debug.");
384 Notice("show info - show server information (e.g. startup path)."); 370 Notice("show info - show server information (e.g. startup path).");
385
386 if (m_stats != null)
387 Notice("show stats - show statistical information for this server");
388
389 Notice("show threads - list tracked threads"); 371 Notice("show threads - list tracked threads");
390 Notice("show uptime - show server startup time and uptime."); 372 Notice("show uptime - show server startup time and uptime.");
391 Notice("show version - show server version."); 373 Notice("show version - show server version.");
@@ -409,11 +391,6 @@ namespace OpenSim.Framework.Servers
409 ShowInfo(); 391 ShowInfo();
410 break; 392 break;
411 393
412 case "stats":
413 if (m_stats != null)
414 Notice(m_stats.Report());
415 break;
416
417 case "threads": 394 case "threads":
418 Notice(GetThreadsReport()); 395 Notice(GetThreadsReport());
419 break; 396 break;
@@ -604,8 +581,7 @@ namespace OpenSim.Framework.Servers
604 581
605 public string osSecret { 582 public string osSecret {
606 // Secret uuid for the simulator 583 // Secret uuid for the simulator
607 get { return m_osSecret; } 584 get { return m_osSecret; }
608
609 } 585 }
610 586
611 public string StatReport(IOSHttpRequest httpRequest) 587 public string StatReport(IOSHttpRequest httpRequest)
@@ -613,11 +589,11 @@ namespace OpenSim.Framework.Servers
613 // If we catch a request for "callback", wrap the response in the value for jsonp 589 // If we catch a request for "callback", wrap the response in the value for jsonp
614 if (httpRequest.Query.ContainsKey("callback")) 590 if (httpRequest.Query.ContainsKey("callback"))
615 { 591 {
616 return httpRequest.Query["callback"].ToString() + "(" + m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");"; 592 return httpRequest.Query["callback"].ToString() + "(" + StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");";
617 } 593 }
618 else 594 else
619 { 595 {
620 return m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); 596 return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version);
621 } 597 }
622 } 598 }
623 599
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index f784398..4f1b439 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -223,8 +223,6 @@ namespace OpenSim
223 223
224 base.StartupSpecific(); 224 base.StartupSpecific();
225 225
226 m_stats = StatsManager.SimExtraStats;
227
228 // Create a ModuleLoader instance 226 // Create a ModuleLoader instance
229 m_moduleLoader = new ModuleLoader(m_config.Source); 227 m_moduleLoader = new ModuleLoader(m_config.Source);
230 228
@@ -234,51 +232,51 @@ namespace OpenSim
234 plugin.PostInitialise(); 232 plugin.PostInitialise();
235 } 233 }
236 234
237 AddPluginCommands(); 235 if (m_console != null)
236 {
237 StatsManager.RegisterConsoleCommands(m_console);
238 AddPluginCommands(m_console);
239 }
238 } 240 }
239 241
240 protected virtual void AddPluginCommands() 242 protected virtual void AddPluginCommands(CommandConsole console)
241 { 243 {
242 // If console exists add plugin commands. 244 List<string> topics = GetHelpTopics();
243 if (m_console != null)
244 {
245 List<string> topics = GetHelpTopics();
246 245
247 foreach (string topic in topics) 246 foreach (string topic in topics)
248 { 247 {
249 string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1); 248 string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
250 249
251 // This is a hack to allow the user to enter the help command in upper or lowercase. This will go 250 // This is a hack to allow the user to enter the help command in upper or lowercase. This will go
252 // away at some point. 251 // away at some point.
253 m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic, 252 console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
254 "help " + capitalizedTopic, 253 "help " + capitalizedTopic,
255 "Get help on plugin command '" + topic + "'", 254 "Get help on plugin command '" + topic + "'",
256 HandleCommanderHelp); 255 HandleCommanderHelp);
257 m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic, 256 console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
258 "help " + capitalizedTopic, 257 "help " + capitalizedTopic,
259 "Get help on plugin command '" + topic + "'", 258 "Get help on plugin command '" + topic + "'",
260 HandleCommanderHelp); 259 HandleCommanderHelp);
261 260
262 ICommander commander = null; 261 ICommander commander = null;
263 262
264 Scene s = SceneManager.CurrentOrFirstScene; 263 Scene s = SceneManager.CurrentOrFirstScene;
265 264
266 if (s != null && s.GetCommanders() != null) 265 if (s != null && s.GetCommanders() != null)
267 { 266 {
268 if (s.GetCommanders().ContainsKey(topic)) 267 if (s.GetCommanders().ContainsKey(topic))
269 commander = s.GetCommanders()[topic]; 268 commander = s.GetCommanders()[topic];
270 } 269 }
271 270
272 if (commander == null) 271 if (commander == null)
273 continue; 272 continue;
274 273
275 foreach (string command in commander.Commands.Keys) 274 foreach (string command in commander.Commands.Keys)
276 { 275 {
277 m_console.Commands.AddCommand(capitalizedTopic, false, 276 console.Commands.AddCommand(capitalizedTopic, false,
278 topic + " " + command, 277 topic + " " + command,
279 topic + " " + commander.Commands[command].ShortHelp(), 278 topic + " " + commander.Commands[command].ShortHelp(),
280 String.Empty, HandleCommanderCommand); 279 String.Empty, HandleCommanderCommand);
281 }
282 } 280 }
283 } 281 }
284 } 282 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index fc9406b..3d9f94f 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -31,6 +31,7 @@ using System.Reflection;
31using OpenMetaverse; 31using OpenMetaverse;
32using OpenMetaverse.Packets; 32using OpenMetaverse.Packets;
33using log4net; 33using log4net;
34using OpenSim.Framework.Monitoring;
34 35
35namespace OpenSim.Region.ClientStack.LindenUDP 36namespace OpenSim.Region.ClientStack.LindenUDP
36{ 37{
@@ -43,17 +44,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
43 private bool packetPoolEnabled = true; 44 private bool packetPoolEnabled = true;
44 private bool dataBlockPoolEnabled = true; 45 private bool dataBlockPoolEnabled = true;
45 46
47 private PercentageStat m_packetsReusedStat = new PercentageStat(
48 "PacketsReused",
49 "Packets reused",
50 "simulator",
51 "simulator",
52 StatVerbosity.Debug,
53 "Number of packets reused out of all requests to the packet pool");
54
55 private PercentageStat m_blocksReusedStat = new PercentageStat(
56 "BlocksReused",
57 "Blocks reused",
58 "simulator",
59 "simulator",
60 StatVerbosity.Debug,
61 "Number of data blocks reused out of all requests to the packet pool");
62
46 /// <summary> 63 /// <summary>
47 /// Pool of packets available for reuse. 64 /// Pool of packets available for reuse.
48 /// </summary> 65 /// </summary>
49 private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>(); 66 private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>();
50 67
51 private static Dictionary<Type, Stack<Object>> DataBlocks = 68 private static Dictionary<Type, Stack<Object>> DataBlocks = new Dictionary<Type, Stack<Object>>();
52 new Dictionary<Type, Stack<Object>>();
53
54 static PacketPool()
55 {
56 }
57 69
58 public static PacketPool Instance 70 public static PacketPool Instance
59 { 71 {
@@ -72,8 +84,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
72 get { return dataBlockPoolEnabled; } 84 get { return dataBlockPoolEnabled; }
73 } 85 }
74 86
87 private PacketPool()
88 {
89 StatsManager.RegisterStat(m_packetsReusedStat);
90 StatsManager.RegisterStat(m_blocksReusedStat);
91 }
92
75 public Packet GetPacket(PacketType type) 93 public Packet GetPacket(PacketType type)
76 { 94 {
95 m_packetsReusedStat.Consequent++;
96
77 Packet packet; 97 Packet packet;
78 98
79 if (!packetPoolEnabled) 99 if (!packetPoolEnabled)
@@ -89,6 +109,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
89 else 109 else
90 { 110 {
91 // Recycle old packages 111 // Recycle old packages
112 m_packetsReusedStat.Antecedent++;
113
92 packet = (pool[type]).Pop(); 114 packet = (pool[type]).Pop();
93 } 115 }
94 } 116 }
@@ -211,16 +233,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
211 } 233 }
212 } 234 }
213 235
214 public static T GetDataBlock<T>() where T: new() 236 public T GetDataBlock<T>() where T: new()
215 { 237 {
216 lock (DataBlocks) 238 lock (DataBlocks)
217 { 239 {
240 m_blocksReusedStat.Consequent++;
241
218 Stack<Object> s; 242 Stack<Object> s;
219 243
220 if (DataBlocks.TryGetValue(typeof(T), out s)) 244 if (DataBlocks.TryGetValue(typeof(T), out s))
221 { 245 {
222 if (s.Count > 0) 246 if (s.Count > 0)
247 {
248 m_blocksReusedStat.Antecedent++;
223 return (T)s.Pop(); 249 return (T)s.Pop();
250 }
224 } 251 }
225 else 252 else
226 { 253 {
@@ -231,7 +258,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
231 } 258 }
232 } 259 }
233 260
234 public static void ReturnDataBlock<T>(T block) where T: new() 261 public void ReturnDataBlock<T>(T block) where T: new()
235 { 262 {
236 if (block == null) 263 if (block == null)
237 return; 264 return;