aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SimStatsReporter.cs')
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/Framework/Scenes/SimStatsReporter.cs629
1 files changed, 309 insertions, 320 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 3effee7..bc440fc 100644..100755
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Timers; 30using System.Timers;
31using System.Threading;
31using OpenMetaverse.Packets; 32using OpenMetaverse.Packets;
32using OpenSim.Framework; 33using OpenSim.Framework;
33using OpenSim.Framework.Monitoring; 34using OpenSim.Framework.Monitoring;
@@ -62,8 +63,10 @@ namespace OpenSim.Region.Framework.Scenes
62 private YourStatsAreWrong handlerStatsIncorrect; 63 private YourStatsAreWrong handlerStatsIncorrect;
63 64
64 // Determines the size of the array that is used to collect StatBlocks 65 // Determines the size of the array that is used to collect StatBlocks
65 // for sending to the SimStats and SimExtraStatsCollector 66 // for sending viewer compatible stats must be conform with sb array filling below
66 private const int m_statisticArraySize = 28; 67 private const int m_statisticViewerArraySize = 38;
68 // size of LastReportedSimFPS with extra stats.
69 private const int m_statisticExtraArraySize = (int)(Stats.SimExtraCountEnd - Stats.SimExtraCountStart);
67 70
68 /// <summary> 71 /// <summary>
69 /// These are the IDs of stats sent in the StatsPacket to the viewer. 72 /// These are the IDs of stats sent in the StatsPacket to the viewer.
@@ -74,6 +77,7 @@ namespace OpenSim.Region.Framework.Scenes
74 /// </remarks> 77 /// </remarks>
75 public enum Stats : uint 78 public enum Stats : uint
76 { 79 {
80// viewers defined IDs
77 TimeDilation = 0, 81 TimeDilation = 0,
78 SimFPS = 1, 82 SimFPS = 1,
79 PhysicsFPS = 2, 83 PhysicsFPS = 2,
@@ -90,7 +94,7 @@ namespace OpenSim.Region.Framework.Scenes
90 Agents = 13, 94 Agents = 13,
91 ChildAgents = 14, 95 ChildAgents = 14,
92 ActiveScripts = 15, 96 ActiveScripts = 15,
93 ScriptLinesPerSecond = 16, 97 LSLScriptLinesPerSecond = 16, // viewers don't like this anymore
94 InPacketsPerSecond = 17, 98 InPacketsPerSecond = 17,
95 OutPacketsPerSecond = 18, 99 OutPacketsPerSecond = 18,
96 PendingDownloads = 19, 100 PendingDownloads = 19,
@@ -109,11 +113,24 @@ namespace OpenSim.Region.Framework.Scenes
109 SimSpareMs = 32, 113 SimSpareMs = 32,
110 SimSleepMs = 33, 114 SimSleepMs = 33,
111 SimIoPumpTime = 34, 115 SimIoPumpTime = 34,
112 FrameDilation = 35, 116 SimPCTSscriptsRun = 35,
113 UsersLoggingIn = 36, 117 SimRegionIdle = 36, // dataserver only
114 TotalGeoPrim = 37, 118 SimRegionIdlePossible = 37, // dataserver only
115 TotalMesh = 38, 119 SimAIStepTimeMS = 38,
116 ThreadCount = 39 120 SimSkippedSillouet_PS = 39,
121 SimSkippedCharsPerC = 40,
122
123// extra stats IDs irrelevant, just far from viewer defined ones
124 SimExtraCountStart = 1000,
125
126 internalLSLScriptLinesPerSecond = 1000,
127 FrameDilation2 = 1001,
128 UsersLoggingIn = 1002,
129 TotalGeoPrim = 1003,
130 TotalMesh = 1004,
131 ThreadCount = 1005,
132
133 SimExtraCountEnd = 1006
117 } 134 }
118 135
119 /// <summary> 136 /// <summary>
@@ -158,19 +175,14 @@ namespace OpenSim.Region.Framework.Scenes
158 175
159 // Sending a stats update every 3 seconds- 176 // Sending a stats update every 3 seconds-
160 private int m_statsUpdatesEveryMS = 3000; 177 private int m_statsUpdatesEveryMS = 3000;
161 private float m_statsUpdateFactor; 178 private double m_lastUpdateTS;
179 private double m_prevFrameStatsTS;
180 private double m_FrameStatsTS;
162 private float m_timeDilation; 181 private float m_timeDilation;
163 private int m_fps; 182 private int m_fps;
164 183
165 /// <summary> 184 private object m_statsLock = new object();
166 /// Number of the last frame on which we processed a stats udpate. 185 private object m_statsFrameLock = new object();
167 /// </summary>
168 private uint m_lastUpdateFrame;
169
170 /// <summary>
171 /// Our nominal fps target, as expected in fps stats when a sim is running normally.
172 /// </summary>
173 private float m_nominalReportedFps = 55;
174 186
175 /// <summary> 187 /// <summary>
176 /// Parameter to adjust reported scene fps 188 /// Parameter to adjust reported scene fps
@@ -186,10 +198,10 @@ namespace OpenSim.Region.Framework.Scenes
186 /// corresponding, with default heartbeat rate, to a value of 5. 198 /// corresponding, with default heartbeat rate, to a value of 5.
187 /// </remarks> 199 /// </remarks>
188 private float m_statisticsFPSfactor = 5.0f; 200 private float m_statisticsFPSfactor = 5.0f;
189 201 private float m_targetFrameTime = 0.1f;
190 // saved last reported value so there is something available for llGetRegionFPS 202 // saved last reported value so there is something available for llGetRegionFPS
191 private float lastReportedSimFPS; 203 private float lastReportedSimFPS;
192 private float[] lastReportedSimStats = new float[m_statisticArraySize]; 204 private float[] lastReportedSimStats = new float[m_statisticExtraArraySize + m_statisticViewerArraySize];
193 private float m_pfps; 205 private float m_pfps;
194 206
195 /// <summary> 207 /// <summary>
@@ -202,14 +214,15 @@ namespace OpenSim.Region.Framework.Scenes
202 /// </summary> 214 /// </summary>
203 private int m_objectUpdates; 215 private int m_objectUpdates;
204 216
205 private int m_frameMS; 217 private float m_frameMS;
206 private int m_spareMS; 218
207 private int m_netMS; 219 private float m_netMS;
208 private int m_agentMS; 220 private float m_agentMS;
209 private int m_physicsMS; 221 private float m_physicsMS;
210 private int m_imageMS; 222 private float m_imageMS;
211 private int m_otherMS; 223 private float m_otherMS;
212 private int m_scriptMS; 224 private float m_sleeptimeMS;
225 private float m_scriptTimeMS;
213 226
214 private int m_rootAgents; 227 private int m_rootAgents;
215 private int m_childAgents; 228 private int m_childAgents;
@@ -224,31 +237,11 @@ namespace OpenSim.Region.Framework.Scenes
224 private int m_pendingUploads = 0; // FIXME: Not currently filled in 237 private int m_pendingUploads = 0; // FIXME: Not currently filled in
225 private int m_activeScripts; 238 private int m_activeScripts;
226 private int m_scriptLinesPerSecond; 239 private int m_scriptLinesPerSecond;
240 private int m_scriptEventsPerSecond;
227 241
228 private int m_objectCapacity = 45000; 242 private int m_objectCapacity = 45000;
229 243
230 // This is the number of frames that will be stored and then averaged for 244 // The current number of users attempting to login to the region
231 // the Total, Simulation, Physics, and Network Frame Time; It is set to
232 // 10 by default but can be changed by the OpenSim.ini configuration file
233 // NumberOfFrames parameter
234 private int m_numberFramesStored;
235
236 // The arrays that will hold the time it took to run the past N frames,
237 // where N is the num_frames_to_average given by the configuration file
238 private double[] m_totalFrameTimeMilliseconds;
239 private double[] m_simulationFrameTimeMilliseconds;
240 private double[] m_physicsFrameTimeMilliseconds;
241 private double[] m_networkFrameTimeMilliseconds;
242
243 // The location of the next time in milliseconds that will be
244 // (over)written when the next frame completes
245 private int m_nextLocation = 0;
246
247 // The correct number of frames that have completed since the last stats
248 // update for physics
249 private int m_numberPhysicsFrames;
250
251 // The current number of users attempting to login to the region
252 private int m_usersLoggingIn; 245 private int m_usersLoggingIn;
253 246
254 // The last reported value of threads from the SmartThreadPool inside of 247 // The last reported value of threads from the SmartThreadPool inside of
@@ -259,51 +252,39 @@ namespace OpenSim.Region.Framework.Scenes
259 252
260 private RegionInfo ReportingRegion; 253 private RegionInfo ReportingRegion;
261 254
262 private Timer m_report = new Timer(); 255 private System.Timers.Timer m_report = new System.Timers.Timer();
263 256
264 private IEstateModule estateModule; 257 private IEstateModule estateModule;
265 258
266 public SimStatsReporter(Scene scene) 259 public SimStatsReporter(Scene scene)
267 : this(scene, Scene.m_defaultNumberFramesStored)
268 { 260 {
269 }
270
271 public SimStatsReporter(Scene scene, int numberOfFrames)
272 {
273 // Store the number of frames from the OpenSim.ini configuration file
274 m_numberFramesStored = numberOfFrames;
275
276 // Initialize the different frame time arrays to the correct sizes
277 m_totalFrameTimeMilliseconds = new double[m_numberFramesStored];
278 m_simulationFrameTimeMilliseconds = new double[m_numberFramesStored];
279 m_physicsFrameTimeMilliseconds = new double[m_numberFramesStored];
280 m_networkFrameTimeMilliseconds = new double[m_numberFramesStored];
281
282 // Initialize the current number of users logging into the region
283 m_usersLoggingIn = 0;
284
285 m_scene = scene; 261 m_scene = scene;
286 262
287 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
288 ReportingRegion = scene.RegionInfo; 263 ReportingRegion = scene.RegionInfo;
289 264
290 if(scene.Normalized55FPS) 265 if(scene.Normalized55FPS)
291 m_statisticsFPSfactor = 55.0f * m_scene.MinFrameTicks / 1000.0f; 266 m_statisticsFPSfactor = 55.0f * m_scene.FrameTime;
292 else 267 else
293 m_statisticsFPSfactor = 1.0f; 268 m_statisticsFPSfactor = 1.0f;
294 269
270 m_targetFrameTime = 1000.0f * m_scene.FrameTime / m_statisticsFPSfactor;
271
295 m_objectCapacity = scene.RegionInfo.ObjectCapacity; 272 m_objectCapacity = scene.RegionInfo.ObjectCapacity;
296 m_report.AutoReset = true; 273 m_report.AutoReset = true;
297 m_report.Interval = m_statsUpdatesEveryMS; 274 m_report.Interval = m_statsUpdatesEveryMS;
298 m_report.Elapsed += TriggerStatsHeartbeat; 275 m_report.Elapsed += TriggerStatsHeartbeat;
299 m_report.Enabled = true; 276 m_report.Enabled = true;
300 277
278 m_lastUpdateTS = Util.GetTimeStampMS();
279 m_FrameStatsTS = m_lastUpdateTS;
280 m_prevFrameStatsTS = m_lastUpdateTS;
281
301 if (StatsManager.SimExtraStats != null) 282 if (StatsManager.SimExtraStats != null)
302 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket; 283 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket;
303 284
304 /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit 285 /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
305 /// longer than ideal (which in itself is a concern). 286 /// longer than ideal (which in itself is a concern).
306 SlowFramesStatReportThreshold = (int)Math.Ceiling(scene.MinFrameTicks * 1.2); 287 SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.FrameTime * 1000 * 1.2);
307 288
308 SlowFramesStat 289 SlowFramesStat
309 = new Stat( 290 = new Stat(
@@ -318,7 +299,6 @@ namespace OpenSim.Region.Framework.Scenes
318 StatVerbosity.Info); 299 StatVerbosity.Info);
319 300
320 StatsManager.RegisterStat(SlowFramesStat); 301 StatsManager.RegisterStat(SlowFramesStat);
321
322 } 302 }
323 303
324 304
@@ -335,7 +315,6 @@ namespace OpenSim.Region.Framework.Scenes
335 public void SetUpdateMS(int ms) 315 public void SetUpdateMS(int ms)
336 { 316 {
337 m_statsUpdatesEveryMS = ms; 317 m_statsUpdatesEveryMS = ms;
338 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
339 m_report.Interval = m_statsUpdatesEveryMS; 318 m_report.Interval = m_statsUpdatesEveryMS;
340 } 319 }
341 320
@@ -355,29 +334,20 @@ namespace OpenSim.Region.Framework.Scenes
355 334
356 private void statsHeartBeat(object sender, EventArgs e) 335 private void statsHeartBeat(object sender, EventArgs e)
357 { 336 {
358 double totalSumFrameTime; 337 if (!m_scene.Active)
359 double simulationSumFrameTime;
360 double physicsSumFrameTime;
361 double networkSumFrameTime;
362 float frameDilation;
363 int currentFrame;
364
365 if (!m_scene.Active)
366 return; 338 return;
367 339
368 // Create arrays to hold the statistics for this current scene, 340 // dont do it if if still been done
369 // these will be passed to the SimExtraStatsCollector, they are also 341
370 // sent to the SimStats class 342 if(Monitor.TryEnter(m_statsLock))
371 SimStatsPacket.StatBlock[] sb = new
372 SimStatsPacket.StatBlock[m_statisticArraySize];
373 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
374
375 // Know what's not thread safe in Mono... modifying timers.
376 // m_log.Debug("Firing Stats Heart Beat");
377 lock (m_report)
378 { 343 {
344 // m_log.Debug("Firing Stats Heart Beat");
345
346 SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[m_statisticViewerArraySize];
347 SimStatsPacket.StatBlock[] sbex = new SimStatsPacket.StatBlock[m_statisticExtraArraySize];
348 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
379 uint regionFlags = 0; 349 uint regionFlags = 0;
380 350
381 try 351 try
382 { 352 {
383 if (estateModule == null) 353 if (estateModule == null)
@@ -390,22 +360,93 @@ namespace OpenSim.Region.Framework.Scenes
390 } 360 }
391 361
392#region various statistic googly moogly 362#region various statistic googly moogly
363 double timeTmp = m_lastUpdateTS;
364 m_lastUpdateTS = Util.GetTimeStampMS();
365 float updateElapsed = (float)((m_lastUpdateTS - timeTmp)/1000.0);
393 366
394 int reportedFPS = (int)(m_fps * m_statisticsFPSfactor); 367 // factor to consider updates integration time
368 float updateTimeFactor = 1.0f / updateElapsed;
395 369
396 // save the reported value so there is something available for llGetRegionFPS
397 lastReportedSimFPS = reportedFPS / m_statsUpdateFactor;
398 370
399 // ORIGINAL code commented out until we have time to add our own 371 // scene frame stats
400 // statistics to the statistics window 372 float reportedFPS;
401 //float physfps = ((m_pfps / 1000)); 373 float physfps;
402 float physfps = m_numberPhysicsFrames * m_statisticsFPSfactor; 374 float timeDilation;
375 float agentMS;
376 float physicsMS;
377 float otherMS;
378 float sleeptime;
379 float scriptTimeMS;
380 float totalFrameTime;
403 381
404 //if (physfps > 600) 382 float invFrameElapsed;
405 //physfps = physfps - (physfps - 600);
406 383
407 if (physfps < 0) 384 // get a copy under lock and reset
408 physfps = 0; 385 lock(m_statsFrameLock)
386 {
387 timeDilation = m_timeDilation;
388 reportedFPS = m_fps;
389 physfps = m_pfps;
390 agentMS = m_agentMS;
391 physicsMS = m_physicsMS;
392 otherMS = m_otherMS;
393 sleeptime = m_sleeptimeMS;
394 scriptTimeMS = m_scriptTimeMS;
395 totalFrameTime = m_frameMS;
396 // still not inv
397 invFrameElapsed = (float)((m_FrameStatsTS - m_prevFrameStatsTS) / 1000.0);
398
399 ResetFrameStats();
400 }
401
402 if (invFrameElapsed / updateElapsed < 0.8)
403 // scene is in trouble, its account of time is most likely wrong
404 // can even be in stall
405 invFrameElapsed = updateTimeFactor;
406 else
407 invFrameElapsed = 1.0f / invFrameElapsed;
408
409 float perframefactor;
410 if (reportedFPS <= 0)
411 {
412 reportedFPS = 0.0f;
413 physfps = 0.0f;
414 perframefactor = 1.0f;
415 timeDilation = 0.0f;
416 }
417 else
418 {
419 timeDilation /= reportedFPS;
420 reportedFPS *= m_statisticsFPSfactor;
421 perframefactor = 1.0f / (float)reportedFPS;
422 reportedFPS *= invFrameElapsed;
423 physfps *= invFrameElapsed * m_statisticsFPSfactor;
424 }
425
426 // some engines track frame time with error related to the simulation step size
427 if(physfps > reportedFPS)
428 physfps = reportedFPS;
429
430 // save the reported value so there is something available for llGetRegionFPS
431 lastReportedSimFPS = reportedFPS;
432
433 // scale frame stats
434
435 totalFrameTime *= perframefactor;
436 sleeptime *= perframefactor;
437 otherMS *= perframefactor;
438 physicsMS *= perframefactor;
439 agentMS *= perframefactor;
440 scriptTimeMS *= perframefactor;
441
442 // estimate spare time
443 float sparetime;
444 sparetime = m_targetFrameTime - (physicsMS + agentMS + otherMS);
445
446 if (sparetime < 0)
447 sparetime = 0;
448 else if (sparetime > totalFrameTime)
449 sparetime = totalFrameTime;
409 450
410#endregion 451#endregion
411 452
@@ -416,79 +457,28 @@ namespace OpenSim.Region.Framework.Scenes
416 m_numMesh = m_scene.SceneGraph.GetTotalMeshObjectsCount(); 457 m_numMesh = m_scene.SceneGraph.GetTotalMeshObjectsCount();
417 m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount(); 458 m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount();
418 m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount(); 459 m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount();
460 m_scriptLinesPerSecond = m_scene.SceneGraph.GetScriptLPS();
419 461
420 // FIXME: Checking for stat sanity is a complex approach. What we really need to do is fix the code 462 // FIXME: Checking for stat sanity is a complex approach. What we really need to do is fix the code
421 // so that stat numbers are always consistent. 463 // so that stat numbers are always consistent.
422 CheckStatSanity(); 464 CheckStatSanity();
423
424 //Our time dilation is 0.91 when we're running a full speed,
425 // therefore to make sure we get an appropriate range,
426 // we have to factor in our error. (0.10f * statsUpdateFactor)
427 // multiplies the fix for the error times the amount of times it'll occur a second
428 // / 10 divides the value by the number of times the sim heartbeat runs (10fps)
429 // Then we divide the whole amount by the amount of seconds pass in between stats updates.
430
431 // 'statsUpdateFactor' is how often stats packets are sent in seconds. Used below to change
432 // values to X-per-second values.
433
434 uint thisFrame = m_scene.Frame;
435 uint numFrames = thisFrame - m_lastUpdateFrame;
436 float framesUpdated = (float)numFrames * m_statisticsFPSfactor;
437 m_lastUpdateFrame = thisFrame;
438
439 // Avoid div-by-zero if somehow we've not updated any frames.
440 if (framesUpdated == 0)
441 framesUpdated = 1;
442
443 for (int i = 0; i < m_statisticArraySize; i++)
444 {
445 sb[i] = new SimStatsPacket.StatBlock();
446 }
447 465
448 // Resetting the sums of the frame times to prevent any errors 466 for (int i = 0; i < m_statisticViewerArraySize; i++)
449 // in calculating the moving average for frame time
450 totalSumFrameTime = 0;
451 simulationSumFrameTime = 0;
452 physicsSumFrameTime = 0;
453 networkSumFrameTime = 0;
454
455 // Loop through all the frames that were stored for the current
456 // heartbeat to process the moving average of frame times
457 for (int i = 0; i < m_numberFramesStored; i++)
458 { 467 {
459 // Sum up each frame time in order to calculate the moving 468 sb[i] = new SimStatsPacket.StatBlock();
460 // average of frame time
461 totalSumFrameTime += m_totalFrameTimeMilliseconds[i];
462 simulationSumFrameTime +=
463 m_simulationFrameTimeMilliseconds[i];
464 physicsSumFrameTime += m_physicsFrameTimeMilliseconds[i];
465 networkSumFrameTime += m_networkFrameTimeMilliseconds[i];
466 } 469 }
467 470
468 // Get the index that represents the current frame based on the next one known; go back
469 // to the last index if next one is stated to restart at 0
470 if (m_nextLocation == 0)
471 currentFrame = m_numberFramesStored - 1;
472 else
473 currentFrame = m_nextLocation - 1;
474
475 // Calculate the frame dilation; which is currently based on the ratio between the sum of the
476 // physics and simulation rate, and the set minimum time to run a scene's frame
477 frameDilation = (float)(m_simulationFrameTimeMilliseconds[currentFrame] +
478 m_physicsFrameTimeMilliseconds[currentFrame]) / m_scene.MinFrameTicks;
479
480 // ORIGINAL code commented out until we have time to add our own
481 sb[0].StatID = (uint) Stats.TimeDilation; 471 sb[0].StatID = (uint) Stats.TimeDilation;
482 sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor)); 472 sb[0].StatValue = (Single.IsNaN(timeDilation)) ? 0.0f : (float)Math.Round(timeDilation,3);
483 473
484 sb[1].StatID = (uint) Stats.SimFPS; 474 sb[1].StatID = (uint) Stats.SimFPS;
485 sb[1].StatValue = reportedFPS / m_statsUpdateFactor; 475 sb[1].StatValue = (float)Math.Round(reportedFPS,1);;
486 476
487 sb[2].StatID = (uint) Stats.PhysicsFPS; 477 sb[2].StatID = (uint) Stats.PhysicsFPS;
488 sb[2].StatValue = physfps / m_statsUpdateFactor; 478 sb[2].StatValue = (float)Math.Round(physfps,1);
489 479
490 sb[3].StatID = (uint) Stats.AgentUpdates; 480 sb[3].StatID = (uint) Stats.AgentUpdates;
491 sb[3].StatValue = (m_agentUpdates / m_statsUpdateFactor); 481 sb[3].StatValue = m_agentUpdates * updateTimeFactor;
492 482
493 sb[4].StatID = (uint) Stats.Agents; 483 sb[4].StatID = (uint) Stats.Agents;
494 sb[4].StatValue = m_rootAgents; 484 sb[4].StatValue = m_rootAgents;
@@ -502,38 +492,32 @@ namespace OpenSim.Region.Framework.Scenes
502 sb[7].StatID = (uint) Stats.ActivePrim; 492 sb[7].StatID = (uint) Stats.ActivePrim;
503 sb[7].StatValue = m_activePrim; 493 sb[7].StatValue = m_activePrim;
504 494
505 // ORIGINAL code commented out until we have time to add our own
506 // statistics to the statistics window
507 sb[8].StatID = (uint)Stats.FrameMS; 495 sb[8].StatID = (uint)Stats.FrameMS;
508 //sb[8].StatValue = m_frameMS / framesUpdated; 496 sb[8].StatValue = totalFrameTime;
509 sb[8].StatValue = (float) totalSumFrameTime / m_numberFramesStored / m_statisticsFPSfactor;
510 497
511 sb[9].StatID = (uint)Stats.NetMS; 498 sb[9].StatID = (uint)Stats.NetMS;
512 //sb[9].StatValue = m_netMS / framesUpdated; 499 sb[9].StatValue = m_netMS * perframefactor;
513 sb[9].StatValue = (float) networkSumFrameTime / m_numberFramesStored / m_statisticsFPSfactor;
514 500
515 sb[10].StatID = (uint)Stats.PhysicsMS; 501 sb[10].StatID = (uint)Stats.PhysicsMS;
516 //sb[10].StatValue = m_physicsMS / framesUpdated; 502 sb[10].StatValue = physicsMS;
517 sb[10].StatValue = (float) physicsSumFrameTime / m_numberFramesStored / m_statisticsFPSfactor;
518 503
519 sb[11].StatID = (uint)Stats.ImageMS ; 504 sb[11].StatID = (uint)Stats.ImageMS ;
520 sb[11].StatValue = m_imageMS / framesUpdated; 505 sb[11].StatValue = m_imageMS * perframefactor;
521 506
522 sb[12].StatID = (uint)Stats.OtherMS; 507 sb[12].StatID = (uint)Stats.OtherMS;
523 //sb[12].StatValue = m_otherMS / framesUpdated; 508 sb[12].StatValue = otherMS;
524 sb[12].StatValue = (float) simulationSumFrameTime / m_numberFramesStored / m_statisticsFPSfactor;
525 509
526 sb[13].StatID = (uint)Stats.InPacketsPerSecond; 510 sb[13].StatID = (uint)Stats.InPacketsPerSecond;
527 sb[13].StatValue = (m_inPacketsPerSecond / m_statsUpdateFactor); 511 sb[13].StatValue = (float)Math.Round(m_inPacketsPerSecond * updateTimeFactor);
528 512
529 sb[14].StatID = (uint)Stats.OutPacketsPerSecond; 513 sb[14].StatID = (uint)Stats.OutPacketsPerSecond;
530 sb[14].StatValue = (m_outPacketsPerSecond / m_statsUpdateFactor); 514 sb[14].StatValue = (float)Math.Round(m_outPacketsPerSecond * updateTimeFactor);
531 515
532 sb[15].StatID = (uint)Stats.UnAckedBytes; 516 sb[15].StatID = (uint)Stats.UnAckedBytes;
533 sb[15].StatValue = m_unAckedBytes; 517 sb[15].StatValue = m_unAckedBytes;
534 518
535 sb[16].StatID = (uint)Stats.AgentMS; 519 sb[16].StatID = (uint)Stats.AgentMS;
536 sb[16].StatValue = m_agentMS / framesUpdated; 520 sb[16].StatValue = agentMS;
537 521
538 sb[17].StatID = (uint)Stats.PendingDownloads; 522 sb[17].StatID = (uint)Stats.PendingDownloads;
539 sb[17].StatValue = m_pendingDownloads; 523 sb[17].StatValue = m_pendingDownloads;
@@ -544,120 +528,155 @@ namespace OpenSim.Region.Framework.Scenes
544 sb[19].StatID = (uint)Stats.ActiveScripts; 528 sb[19].StatID = (uint)Stats.ActiveScripts;
545 sb[19].StatValue = m_activeScripts; 529 sb[19].StatValue = m_activeScripts;
546 530
547 sb[20].StatID = (uint)Stats.ScriptLinesPerSecond; 531 sb[20].StatID = (uint)Stats.SimSleepMs;
548 sb[20].StatValue = m_scriptLinesPerSecond / m_statsUpdateFactor; 532 sb[20].StatValue = sleeptime;
549 533
550 sb[21].StatID = (uint)Stats.SimSpareMs; 534 sb[21].StatID = (uint)Stats.SimSpareMs;
551 sb[21].StatValue = m_spareMS / framesUpdated; 535 sb[21].StatValue = sparetime;
536
537 // this should came from phys engine
538 sb[22].StatID = (uint)Stats.SimPhysicsStepMs;
539 sb[22].StatValue = 20;
540
541 // send the ones we dont have as zeros, to clean viewers state
542 // specially arriving from regions with wrond IDs in use
543
544 sb[23].StatID = (uint)Stats.VirtualSizeKb;
545 sb[23].StatValue = 0;
546
547 sb[24].StatID = (uint)Stats.ResidentSizeKb;
548 sb[24].StatValue = 0;
549
550 sb[25].StatID = (uint)Stats.PendingLocalUploads;
551 sb[25].StatValue = 0;
552 552
553 // Current ratio between the sum of physics and sim rate, and the 553 sb[26].StatID = (uint)Stats.PhysicsPinnedTasks;
554 // minimum time to run a scene's frame 554 sb[26].StatValue = 0;
555 sb[22].StatID = (uint)Stats.FrameDilation;
556 sb[22].StatValue = frameDilation;
557 555
558 // Current number of users currently attemptint to login to region 556 sb[27].StatID = (uint)Stats.PhysicsLodTasks;
559 sb[23].StatID = (uint)Stats.UsersLoggingIn; 557 sb[27].StatValue = 0;
560 sb[23].StatValue = m_usersLoggingIn;
561 558
562 // Total number of geometric primitives in the scene 559 sb[28].StatID = (uint)Stats.ScriptEps; // we actuall have this, but not messing array order AGAIN
563 sb[24].StatID = (uint)Stats.TotalGeoPrim; 560 sb[28].StatValue = (float)Math.Round(m_scriptEventsPerSecond * updateTimeFactor);
564 sb[24].StatValue = m_numGeoPrim;
565 561
566 // Total number of mesh objects in the scene 562 sb[29].StatID = (uint)Stats.SimAIStepTimeMS;
567 sb[25].StatID = (uint)Stats.TotalMesh; 563 sb[29].StatValue = 0;
568 sb[25].StatValue = m_numMesh;
569 564
570 // Current number of threads that XEngine is using 565 sb[30].StatID = (uint)Stats.SimIoPumpTime;
571 sb[26].StatID = (uint)Stats.ThreadCount; 566 sb[30].StatValue = 0;
572 sb[26].StatValue = m_inUseThreads;
573 567
574 sb[27].StatID = (uint)Stats.ScriptMS; 568 sb[31].StatID = (uint)Stats.SimPCTSscriptsRun;
575 sb[27].StatValue = (numFrames <= 0) ? 0 : ((float)m_scriptMS / numFrames); 569 sb[31].StatValue = 0;
576 570
577 for (int i = 0; i < m_statisticArraySize; i++) 571 sb[32].StatID = (uint)Stats.SimRegionIdle;
572 sb[32].StatValue = 0;
573
574 sb[33].StatID = (uint)Stats.SimRegionIdlePossible;
575 sb[33].StatValue = 0;
576
577 sb[34].StatID = (uint)Stats.SimSkippedSillouet_PS;
578 sb[34].StatValue = 0;
579
580 sb[35].StatID = (uint)Stats.SimSkippedCharsPerC;
581 sb[35].StatValue = 0;
582
583 sb[36].StatID = (uint)Stats.SimPhysicsMemory;
584 sb[36].StatValue = 0;
585
586 sb[37].StatID = (uint)Stats.ScriptMS;
587 sb[37].StatValue = scriptTimeMS;
588
589 for (int i = 0; i < m_statisticViewerArraySize; i++)
578 { 590 {
579 lastReportedSimStats[i] = sb[i].StatValue; 591 lastReportedSimStats[i] = sb[i].StatValue;
580 } 592 }
581 593
582 SimStats simStats 594
595 // add extra stats for internal use
596
597 for (int i = 0; i < m_statisticExtraArraySize; i++)
598 {
599 sbex[i] = new SimStatsPacket.StatBlock();
600 }
601
602 sbex[0].StatID = (uint)Stats.LSLScriptLinesPerSecond;
603 sbex[0].StatValue = m_scriptLinesPerSecond * updateTimeFactor;
604 lastReportedSimStats[38] = m_scriptLinesPerSecond * updateTimeFactor;
605
606 sbex[1].StatID = (uint)Stats.FrameDilation2;
607 sbex[1].StatValue = (Single.IsNaN(timeDilation)) ? 0.1f : timeDilation;
608 lastReportedSimStats[39] = (Single.IsNaN(timeDilation)) ? 0.1f : timeDilation;
609
610 sbex[2].StatID = (uint)Stats.UsersLoggingIn;
611 sbex[2].StatValue = m_usersLoggingIn;
612 lastReportedSimStats[40] = m_usersLoggingIn;
613
614 sbex[3].StatID = (uint)Stats.TotalGeoPrim;
615 sbex[3].StatValue = m_numGeoPrim;
616 lastReportedSimStats[41] = m_numGeoPrim;
617
618 sbex[4].StatID = (uint)Stats.TotalMesh;
619 sbex[4].StatValue = m_numMesh;
620 lastReportedSimStats[42] = m_numMesh;
621
622 sbex[5].StatID = (uint)Stats.ThreadCount;
623 sbex[5].StatValue = m_inUseThreads;
624 lastReportedSimStats[43] = m_inUseThreads;
625
626 SimStats simStats
583 = new SimStats( 627 = new SimStats(
584 ReportingRegion.RegionLocX, ReportingRegion.RegionLocY, regionFlags, (uint)m_objectCapacity, 628 ReportingRegion.RegionLocX, ReportingRegion.RegionLocY, regionFlags, (uint)m_objectCapacity,
585 rb, sb, m_scene.RegionInfo.originRegionID); 629 rb, sb, sbex, m_scene.RegionInfo.originRegionID);
586 630
587 handlerSendStatResult = OnSendStatsResult; 631 handlerSendStatResult = OnSendStatsResult;
588 if (handlerSendStatResult != null) 632 if (handlerSendStatResult != null)
589 { 633 {
590 handlerSendStatResult(simStats); 634 handlerSendStatResult(simStats);
591 } 635 }
592 636
593 // Extra statistics that aren't currently sent to clients 637 // Extra statistics that aren't currently sent to clients
594 lock (m_lastReportedExtraSimStats) 638 if (m_scene.PhysicsScene != null)
595 { 639 {
596 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor; 640 lock (m_lastReportedExtraSimStats)
597 m_lastReportedExtraSimStats[SlowFramesStat.ShortName] = (float)SlowFramesStat.Value;
598
599 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
600
601 if (physicsStats != null)
602 { 641 {
603 foreach (KeyValuePair<string, float> tuple in physicsStats) 642 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates * updateTimeFactor;
643 m_lastReportedExtraSimStats[SlowFramesStat.ShortName] = (float)SlowFramesStat.Value;
644
645 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
646
647 if (physicsStats != null)
604 { 648 {
605 // FIXME: An extremely dirty hack to divide MS stats per frame rather than per second 649 foreach (KeyValuePair<string, float> tuple in physicsStats)
606 // Need to change things so that stats source can indicate whether they are per second or 650 {
607 // per frame. 651 // FIXME: An extremely dirty hack to divide MS stats per frame rather than per second
608 if (tuple.Key.EndsWith("MS")) 652 // Need to change things so that stats source can indicate whether they are per second or
609 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / framesUpdated; 653 // per frame.
610 else 654 if (tuple.Key.EndsWith("MS"))
611 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / m_statsUpdateFactor; 655 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value * perframefactor;
656 else
657 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value * updateTimeFactor;
658 }
612 } 659 }
613 } 660 }
614 } 661 }
615 662
663// LastReportedObjectUpdates = m_objectUpdates / m_statsUpdateFactor;
616 ResetValues(); 664 ResetValues();
665 Monitor.Exit(m_statsLock);
617 } 666 }
618 } 667 }
619 668
620 private void ResetValues() 669 private void ResetValues()
621 { 670 {
622 // Reset the number of frames that the physics library has
623 // processed since the last stats report
624 m_numberPhysicsFrames = 0;
625
626 m_timeDilation = 0;
627 m_fps = 0;
628 m_pfps = 0;
629 m_agentUpdates = 0; 671 m_agentUpdates = 0;
630 m_objectUpdates = 0; 672 m_objectUpdates = 0;
631 //m_inPacketsPerSecond = 0;
632 //m_outPacketsPerSecond = 0;
633 m_unAckedBytes = 0; 673 m_unAckedBytes = 0;
634 m_scriptLinesPerSecond = 0; 674 m_scriptEventsPerSecond = 0;
635 675
636 m_frameMS = 0;
637 m_agentMS = 0;
638 m_netMS = 0; 676 m_netMS = 0;
639 m_physicsMS = 0;
640 m_imageMS = 0; 677 m_imageMS = 0;
641 m_otherMS = 0;
642 m_scriptMS = 0;
643 m_spareMS = 0;
644 } 678 }
645 679
646 # region methods called from Scene
647 // The majority of these functions are additive
648 // so that you can easily change the amount of
649 // seconds in between sim stats updates
650
651 public void AddTimeDilation(float td)
652 {
653 //float tdsetting = td;
654 //if (tdsetting > 1.0f)
655 //tdsetting = (tdsetting - (tdsetting - 0.91f));
656
657 //if (tdsetting < 0)
658 //tdsetting = 0.0f;
659 m_timeDilation = td;
660 }
661 680
662 internal void CheckStatSanity() 681 internal void CheckStatSanity()
663 { 682 {
@@ -675,14 +694,44 @@ namespace OpenSim.Region.Framework.Scenes
675 } 694 }
676 } 695 }
677 696
678 public void AddFPS(int frames) 697 # region methods called from Scene
698
699 public void AddFrameStats(float _timeDilation, float _physicsFPS, float _agentMS,
700 float _physicsMS, float _otherMS , float _sleepMS,
701 float _frameMS, float _scriptTimeMS)
679 { 702 {
680 m_fps += frames; 703 lock(m_statsFrameLock)
704 {
705 m_fps++;
706 m_timeDilation += _timeDilation;
707 m_pfps += _physicsFPS;
708 m_agentMS += _agentMS;
709 m_physicsMS += _physicsMS;
710 m_otherMS += _otherMS;
711 m_sleeptimeMS += _sleepMS;
712 m_frameMS += _frameMS;
713 m_scriptTimeMS += _scriptTimeMS;
714
715 if (_frameMS > SlowFramesStatReportThreshold)
716 SlowFramesStat.Value++;
717
718 m_FrameStatsTS = Util.GetTimeStampMS();
719 }
681 } 720 }
682 721
683 public void AddPhysicsFPS(float frames) 722 private void ResetFrameStats()
684 { 723 {
685 m_pfps += frames; 724 m_fps = 0;
725 m_timeDilation = 0.0f;
726 m_pfps = 0.0f;
727 m_agentMS = 0.0f;
728 m_physicsMS = 0.0f;
729 m_otherMS = 0.0f;
730 m_sleeptimeMS = 0.0f;
731 m_frameMS = 0.0f;
732 m_scriptTimeMS = 0.0f;
733
734 m_prevFrameStatsTS = m_FrameStatsTS;
686 } 735 }
687 736
688 public void AddObjectUpdates(int numUpdates) 737 public void AddObjectUpdates(int numUpdates)
@@ -711,77 +760,17 @@ namespace OpenSim.Region.Framework.Scenes
711 if (m_unAckedBytes < 0) m_unAckedBytes = 0; 760 if (m_unAckedBytes < 0) m_unAckedBytes = 0;
712 } 761 }
713 762
714 public void addFrameMS(int ms)
715 {
716 m_frameMS += ms;
717
718 // At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
719 // longer than ideal due to the inaccuracy of the Sleep in Scene.Update() (which in itself is a concern).
720 if (ms > SlowFramesStatReportThreshold)
721 SlowFramesStat.Value++;
722 }
723
724 public void AddSpareMS(int ms)
725 {
726 m_spareMS += ms;
727 }
728 763
729 public void addNetMS(int ms) 764 public void addNetMS(float ms)
730 { 765 {
731 m_netMS += ms; 766 m_netMS += ms;
732 } 767 }
733 768
734 public void addAgentMS(int ms) 769 public void addImageMS(float ms)
735 {
736 m_agentMS += ms;
737 }
738
739 public void addPhysicsMS(int ms)
740 {
741 m_physicsMS += ms;
742 }
743
744 public void addImageMS(int ms)
745 { 770 {
746 m_imageMS += ms; 771 m_imageMS += ms;
747 } 772 }
748 773
749 public void addOtherMS(int ms)
750 {
751 m_otherMS += ms;
752 }
753
754 public void AddScriptMS(int ms)
755 {
756 m_scriptMS += ms;
757 }
758
759 public void addPhysicsFrame(int frames)
760 {
761 // Add the number of physics frames to the correct total physics
762 // frames
763 m_numberPhysicsFrames += frames;
764 }
765
766 public void addFrameTimeMilliseconds(double total, double simulation,
767 double physics, double network)
768 {
769 // Save the frame times from the current frame into the appropriate
770 // arrays
771 m_totalFrameTimeMilliseconds[m_nextLocation] = total;
772 m_simulationFrameTimeMilliseconds[m_nextLocation] = simulation;
773 m_physicsFrameTimeMilliseconds[m_nextLocation] = physics;
774 m_networkFrameTimeMilliseconds[m_nextLocation] = network;
775
776 // Update to the next location in the list
777 m_nextLocation++;
778
779 // Since the list will begin to overwrite the oldest frame values
780 // first, the next location needs to loop back to the beginning of the
781 // list whenever it reaches the end
782 m_nextLocation = m_nextLocation % m_numberFramesStored;
783 }
784
785 public void AddPendingDownloads(int count) 774 public void AddPendingDownloads(int count)
786 { 775 {
787 m_pendingDownloads += count; 776 m_pendingDownloads += count;
@@ -792,9 +781,9 @@ namespace OpenSim.Region.Framework.Scenes
792 //m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads); 781 //m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads);
793 } 782 }
794 783
795 public void addScriptLines(int count) 784 public void addScriptEvents(int count)
796 { 785 {
797 m_scriptLinesPerSecond += count; 786 m_scriptEventsPerSecond += count;
798 } 787 }
799 788
800 public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes) 789 public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes)