diff options
-rw-r--r-- | OpenSim/Framework/Monitoring/StatsManager.cs | 75 | ||||
-rw-r--r-- | OpenSim/Framework/Pool.cs | 15 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 14 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | 17 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 40 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SimStatsReporter.cs | 6 |
6 files changed, 153 insertions, 14 deletions
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index 31989e5..116b2c0 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs | |||
@@ -249,6 +249,19 @@ namespace OpenSim.Framework.Monitoring | |||
249 | } | 249 | } |
250 | 250 | ||
251 | /// <summary> | 251 | /// <summary> |
252 | /// Stat type. | ||
253 | /// </summary> | ||
254 | /// <remarks> | ||
255 | /// A push stat is one which is continually updated and so it's value can simply by read. | ||
256 | /// A pull stat is one where reading the value triggers a collection method - the stat is not continually updated. | ||
257 | /// </remarks> | ||
258 | public enum StatType | ||
259 | { | ||
260 | Push, | ||
261 | Pull | ||
262 | } | ||
263 | |||
264 | /// <summary> | ||
252 | /// Verbosity of stat. | 265 | /// Verbosity of stat. |
253 | /// </summary> | 266 | /// </summary> |
254 | /// <remarks> | 267 | /// <remarks> |
@@ -285,29 +298,65 @@ namespace OpenSim.Framework.Monitoring | |||
285 | /// </value> | 298 | /// </value> |
286 | public string Container { get; private set; } | 299 | public string Container { get; private set; } |
287 | 300 | ||
301 | public StatType StatType { get; private set; } | ||
302 | |||
303 | /// <summary> | ||
304 | /// Action used to update this stat when the value is requested if it's a pull type. | ||
305 | /// </summary> | ||
306 | public Action<Stat> PullAction { get; private set; } | ||
307 | |||
288 | public StatVerbosity Verbosity { get; private set; } | 308 | public StatVerbosity Verbosity { get; private set; } |
289 | public string ShortName { get; private set; } | 309 | public string ShortName { get; private set; } |
290 | public string Name { get; private set; } | 310 | public string Name { get; private set; } |
291 | public string Description { get; private set; } | 311 | public string Description { get; private set; } |
292 | public virtual string UnitName { get; private set; } | 312 | public virtual string UnitName { get; private set; } |
293 | 313 | ||
294 | public virtual double Value { get; set; } | 314 | public virtual double Value |
315 | { | ||
316 | get | ||
317 | { | ||
318 | // Asking for an update here means that the updater cannot access this value without infinite recursion. | ||
319 | // XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being | ||
320 | // called by the pull action and just return the value. | ||
321 | if (StatType == StatType.Pull) | ||
322 | PullAction(this); | ||
323 | |||
324 | return m_value; | ||
325 | } | ||
326 | |||
327 | set | ||
328 | { | ||
329 | m_value = value; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | private double m_value; | ||
295 | 334 | ||
296 | /// <summary> | 335 | /// <summary> |
297 | /// Constructor | 336 | /// Constructor |
298 | /// </summary> | 337 | /// </summary> |
299 | /// <param name='shortName'>Short name for the stat. Must not contain spaces. e.g. "LongFrames"</param> | 338 | /// <param name='shortName'>Short name for the stat. Must not contain spaces. e.g. "LongFrames"</param> |
300 | /// <param name='name'>Human readable name for the stat. e.g. "Long frames"</param> | 339 | /// <param name='name'>Human readable name for the stat. e.g. "Long frames"</param> |
340 | /// <param name='description'>Description of stat</param> | ||
301 | /// <param name='unitName'> | 341 | /// <param name='unitName'> |
302 | /// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value. | 342 | /// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value. |
303 | /// e.g. " frames" | 343 | /// e.g. " frames" |
304 | /// </param> | 344 | /// </param> |
305 | /// <param name='category'>Category under which this stat should appear, e.g. "scene". Do not capitalize.</param> | 345 | /// <param name='category'>Category under which this stat should appear, e.g. "scene". Do not capitalize.</param> |
306 | /// <param name='container'>Entity to which this stat relates. e.g. scene name if this is a per scene stat.</param> | 346 | /// <param name='container'>Entity to which this stat relates. e.g. scene name if this is a per scene stat.</param> |
347 | /// <param name='type'>Push or pull</param> | ||
348 | /// <param name='pullAction'>Pull stats need an action to update the stat on request. Push stats should set null here.</param> | ||
307 | /// <param name='verbosity'>Verbosity of stat. Controls whether it will appear in short stat display or only full display.</param> | 349 | /// <param name='verbosity'>Verbosity of stat. Controls whether it will appear in short stat display or only full display.</param> |
308 | /// <param name='description'>Description of stat</param> | ||
309 | public Stat( | 350 | public Stat( |
310 | string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description) | 351 | string shortName, |
352 | string name, | ||
353 | string description, | ||
354 | string unitName, | ||
355 | string category, | ||
356 | string container, | ||
357 | StatType type, | ||
358 | Action<Stat> pullAction, | ||
359 | StatVerbosity verbosity) | ||
311 | { | 360 | { |
312 | if (StatsManager.SubCommands.Contains(category)) | 361 | if (StatsManager.SubCommands.Contains(category)) |
313 | throw new Exception( | 362 | throw new Exception( |
@@ -315,11 +364,18 @@ namespace OpenSim.Framework.Monitoring | |||
315 | 364 | ||
316 | ShortName = shortName; | 365 | ShortName = shortName; |
317 | Name = name; | 366 | Name = name; |
367 | Description = description; | ||
318 | UnitName = unitName; | 368 | UnitName = unitName; |
319 | Category = category; | 369 | Category = category; |
320 | Container = container; | 370 | Container = container; |
371 | StatType = type; | ||
372 | |||
373 | if (StatType == StatType.Push && pullAction != null) | ||
374 | throw new Exception("A push stat cannot have a pull action"); | ||
375 | else | ||
376 | PullAction = pullAction; | ||
377 | |||
321 | Verbosity = verbosity; | 378 | Verbosity = verbosity; |
322 | Description = description; | ||
323 | 379 | ||
324 | UniqueName = GenUniqueName(Container, Category, ShortName); | 380 | UniqueName = GenUniqueName(Container, Category, ShortName); |
325 | } | 381 | } |
@@ -361,8 +417,15 @@ namespace OpenSim.Framework.Monitoring | |||
361 | } | 417 | } |
362 | 418 | ||
363 | public PercentageStat( | 419 | public PercentageStat( |
364 | string shortName, string name, string category, string container, StatVerbosity verbosity, string description) | 420 | string shortName, |
365 | : base(shortName, name, "%", category, container, verbosity, description) {} | 421 | string name, |
422 | string description, | ||
423 | string category, | ||
424 | string container, | ||
425 | StatType type, | ||
426 | Action<Stat> pullAction, | ||
427 | StatVerbosity verbosity) | ||
428 | : base(shortName, name, description, "%", category, container, type, pullAction, verbosity) {} | ||
366 | 429 | ||
367 | public override string ToConsoleString() | 430 | public override string ToConsoleString() |
368 | { | 431 | { |
diff --git a/OpenSim/Framework/Pool.cs b/OpenSim/Framework/Pool.cs index 1ca06c3..5484f5c 100644 --- a/OpenSim/Framework/Pool.cs +++ b/OpenSim/Framework/Pool.cs | |||
@@ -38,8 +38,23 @@ namespace OpenSim.Framework | |||
38 | /// </remarks> | 38 | /// </remarks> |
39 | public class Pool<T> | 39 | public class Pool<T> |
40 | { | 40 | { |
41 | /// <summary> | ||
42 | /// Number of objects in the pool. | ||
43 | /// </summary> | ||
44 | public int Count | ||
45 | { | ||
46 | get | ||
47 | { | ||
48 | lock (m_pool) | ||
49 | return m_pool.Count; | ||
50 | } | ||
51 | } | ||
52 | |||
41 | private Stack<T> m_pool; | 53 | private Stack<T> m_pool; |
42 | 54 | ||
55 | /// <summary> | ||
56 | /// Maximum pool size. Beyond this, any returned objects are not pooled. | ||
57 | /// </summary> | ||
43 | private int m_maxPoolSize; | 58 | private int m_maxPoolSize; |
44 | 59 | ||
45 | private Func<T> m_createFunction; | 60 | private Func<T> m_createFunction; |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 419de66..bcfd392 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -278,7 +278,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
278 | ThrottleRates = new ThrottleRates(configSource); | 278 | ThrottleRates = new ThrottleRates(configSource); |
279 | 279 | ||
280 | if (UsePools) | 280 | if (UsePools) |
281 | { | ||
281 | m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500); | 282 | m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500); |
283 | |||
284 | StatsManager.RegisterStat( | ||
285 | new Stat( | ||
286 | "IncomingPacketPoolCount", | ||
287 | "Objects within incoming packet pool", | ||
288 | "The number of objects currently stored within the incoming packet pool", | ||
289 | "", | ||
290 | "clientstack", | ||
291 | "packetpool", | ||
292 | StatType.Pull, | ||
293 | stat => stat.Value = m_incomingPacketPool.Count, | ||
294 | StatVerbosity.Debug)); | ||
295 | } | ||
282 | } | 296 | } |
283 | 297 | ||
284 | public void Start() | 298 | public void Start() |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 6e6b3ef..18abfd6 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -31,6 +31,7 @@ using System.Net.Sockets; | |||
31 | using System.Threading; | 31 | using System.Threading; |
32 | using log4net; | 32 | using log4net; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Monitoring; | ||
34 | 35 | ||
35 | namespace OpenMetaverse | 36 | namespace OpenMetaverse |
36 | { | 37 | { |
@@ -107,9 +108,25 @@ namespace OpenMetaverse | |||
107 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) | 108 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) |
108 | { | 109 | { |
109 | if (UsePools) | 110 | if (UsePools) |
111 | { | ||
110 | m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); | 112 | m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); |
113 | |||
114 | StatsManager.RegisterStat( | ||
115 | new Stat( | ||
116 | "UDPPacketBufferPoolCount", | ||
117 | "Objects within the UDPPacketBuffer pool", | ||
118 | "The number of objects currently stored within the UDPPacketBuffer pool", | ||
119 | "", | ||
120 | "clientstack", | ||
121 | "packetpool", | ||
122 | StatType.Pull, | ||
123 | stat => stat.Value = m_pool.Count, | ||
124 | StatVerbosity.Debug)); | ||
125 | } | ||
111 | else | 126 | else |
127 | { | ||
112 | m_pool = null; | 128 | m_pool = null; |
129 | } | ||
113 | 130 | ||
114 | m_asyncPacketHandling = asyncPacketHandling; | 131 | m_asyncPacketHandling = asyncPacketHandling; |
115 | 132 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index 2a3d14f..9f22fb4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | |||
@@ -47,18 +47,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
47 | private PercentageStat m_packetsReusedStat = new PercentageStat( | 47 | private PercentageStat m_packetsReusedStat = new PercentageStat( |
48 | "PacketsReused", | 48 | "PacketsReused", |
49 | "Packets reused", | 49 | "Packets reused", |
50 | "Number of packets reused out of all requests to the packet pool", | ||
50 | "clientstack", | 51 | "clientstack", |
51 | "packetpool", | 52 | "packetpool", |
52 | StatVerbosity.Debug, | 53 | StatType.Push, |
53 | "Number of packets reused out of all requests to the packet pool"); | 54 | null, |
55 | StatVerbosity.Debug); | ||
54 | 56 | ||
55 | private PercentageStat m_blocksReusedStat = new PercentageStat( | 57 | private PercentageStat m_blocksReusedStat = new PercentageStat( |
56 | "BlocksReused", | 58 | "PacketDataBlocksReused", |
57 | "Blocks reused", | 59 | "Packet data blocks reused", |
60 | "Number of data blocks reused out of all requests to the packet pool", | ||
58 | "clientstack", | 61 | "clientstack", |
59 | "packetpool", | 62 | "packetpool", |
60 | StatVerbosity.Debug, | 63 | StatType.Push, |
61 | "Number of data blocks reused out of all requests to the packet pool"); | 64 | null, |
65 | StatVerbosity.Debug); | ||
62 | 66 | ||
63 | /// <summary> | 67 | /// <summary> |
64 | /// Pool of packets available for reuse. | 68 | /// Pool of packets available for reuse. |
@@ -88,6 +92,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
88 | { | 92 | { |
89 | StatsManager.RegisterStat(m_packetsReusedStat); | 93 | StatsManager.RegisterStat(m_packetsReusedStat); |
90 | StatsManager.RegisterStat(m_blocksReusedStat); | 94 | StatsManager.RegisterStat(m_blocksReusedStat); |
95 | |||
96 | StatsManager.RegisterStat( | ||
97 | new Stat( | ||
98 | "PacketsPoolCount", | ||
99 | "Objects within the packet pool", | ||
100 | "The number of objects currently stored within the packet pool", | ||
101 | "", | ||
102 | "clientstack", | ||
103 | "packetpool", | ||
104 | StatType.Pull, | ||
105 | stat => { lock (pool) { stat.Value = pool.Count; } }, | ||
106 | StatVerbosity.Debug)); | ||
107 | |||
108 | StatsManager.RegisterStat( | ||
109 | new Stat( | ||
110 | "PacketDataBlocksPoolCount", | ||
111 | "Objects within the packet data block pool", | ||
112 | "The number of objects currently stored within the packet data block pool", | ||
113 | "", | ||
114 | "clientstack", | ||
115 | "packetpool", | ||
116 | StatType.Pull, | ||
117 | stat => { lock (DataBlocks) { stat.Value = DataBlocks.Count; } }, | ||
118 | StatVerbosity.Debug)); | ||
91 | } | 119 | } |
92 | 120 | ||
93 | /// <summary> | 121 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 2addb5b..b9d615e 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs | |||
@@ -245,11 +245,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
245 | = new Stat( | 245 | = new Stat( |
246 | "SlowFrames", | 246 | "SlowFrames", |
247 | "Slow Frames", | 247 | "Slow Frames", |
248 | "Number of frames where frame time has been significantly longer than the desired frame time.", | ||
248 | " frames", | 249 | " frames", |
249 | "scene", | 250 | "scene", |
250 | m_scene.Name, | 251 | m_scene.Name, |
251 | StatVerbosity.Info, | 252 | StatType.Push, |
252 | "Number of frames where frame time has been significantly longer than the desired frame time."); | 253 | null, |
254 | StatVerbosity.Info); | ||
253 | 255 | ||
254 | StatsManager.RegisterStat(SlowFramesStat); | 256 | StatsManager.RegisterStat(SlowFramesStat); |
255 | } | 257 | } |