aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-x[-rw-r--r--]OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs47
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/Framework/Scenes/Scene.cs108
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/Framework/Scenes/SceneGraph.cs59
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/Framework/Scenes/SimStatsReporter.cs216
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/ScriptEngine/XEngine/XEngine.cs36
5 files changed, 448 insertions, 18 deletions
diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
index f6f458d..98fa65a 100644..100755
--- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics;
30using System.Linq; 31using System.Linq;
31using System.Text; 32using System.Text;
32using OpenMetaverse; 33using OpenMetaverse;
@@ -71,6 +72,10 @@ namespace OpenSim.Framework.Monitoring
71 private volatile float pendingUploads; 72 private volatile float pendingUploads;
72 private volatile float activeScripts; 73 private volatile float activeScripts;
73 private volatile float scriptLinesPerSecond; 74 private volatile float scriptLinesPerSecond;
75 private volatile float m_usersLoggingIn;
76 private volatile float m_totalGeoPrims;
77 private volatile float m_totalMeshes;
78 private volatile float m_inUseThreads;
74 79
75// /// <summary> 80// /// <summary>
76// /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the 81// /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the
@@ -249,6 +254,10 @@ namespace OpenSim.Framework.Monitoring
249 { 254 {
250 // FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original 255 // FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original
251 // SimStatsPacket that was being used). 256 // SimStatsPacket that was being used).
257
258 // For an unknown reason the original designers decided not to
259 // include the spare MS statistic inside of this class, this is
260 // located inside the StatsBlock at location 21 thus it is skipped
252 timeDilation = stats.StatsBlock[0].StatValue; 261 timeDilation = stats.StatsBlock[0].StatValue;
253 simFps = stats.StatsBlock[1].StatValue; 262 simFps = stats.StatsBlock[1].StatValue;
254 physicsFps = stats.StatsBlock[2].StatValue; 263 physicsFps = stats.StatsBlock[2].StatValue;
@@ -270,6 +279,10 @@ namespace OpenSim.Framework.Monitoring
270 pendingUploads = stats.StatsBlock[18].StatValue; 279 pendingUploads = stats.StatsBlock[18].StatValue;
271 activeScripts = stats.StatsBlock[19].StatValue; 280 activeScripts = stats.StatsBlock[19].StatValue;
272 scriptLinesPerSecond = stats.StatsBlock[20].StatValue; 281 scriptLinesPerSecond = stats.StatsBlock[20].StatValue;
282 m_usersLoggingIn = stats.StatsBlock[22].StatValue;
283 m_totalGeoPrims = stats.StatsBlock[23].StatValue;
284 m_totalMeshes = stats.StatsBlock[24].StatValue;
285 m_inUseThreads = stats.StatsBlock[25].StatValue;
273 } 286 }
274 287
275 /// <summary> 288 /// <summary>
@@ -407,6 +420,23 @@ Asset service request failures: {3}" + Environment.NewLine,
407 /// <returns></returns> 420 /// <returns></returns>
408 public override OSDMap OReport(string uptime, string version) 421 public override OSDMap OReport(string uptime, string version)
409 { 422 {
423 // Get the amount of physical memory, allocated with the instance of this program, in kilobytes;
424 // the working set is the set of memory pages currently visible to this program in physical RAM
425 // memory and includes both shared (e.g. system libraries) and private data
426 double memUsage = Process.GetCurrentProcess().WorkingSet64 / 1024.0;
427
428 // Get the number of threads from the system that are currently
429 // running
430 int numberThreadsRunning = 0;
431 foreach (ProcessThread currentThread in
432 Process.GetCurrentProcess().Threads)
433 {
434 if (currentThread.ThreadState == ThreadState.Running)
435 {
436 numberThreadsRunning++;
437 }
438 }
439
410 OSDMap args = new OSDMap(30); 440 OSDMap args = new OSDMap(30);
411// args["AssetsInCache"] = OSD.FromString (String.Format ("{0:0.##}", AssetsInCache)); 441// args["AssetsInCache"] = OSD.FromString (String.Format ("{0:0.##}", AssetsInCache));
412// args["TimeAfterCacheMiss"] = OSD.FromString (String.Format ("{0:0.##}", 442// args["TimeAfterCacheMiss"] = OSD.FromString (String.Format ("{0:0.##}",
@@ -443,6 +473,23 @@ Asset service request failures: {3}" + Environment.NewLine,
443 args["Memory"] = OSD.FromString (base.XReport (uptime, version)); 473 args["Memory"] = OSD.FromString (base.XReport (uptime, version));
444 args["Uptime"] = OSD.FromString (uptime); 474 args["Uptime"] = OSD.FromString (uptime);
445 args["Version"] = OSD.FromString (version); 475 args["Version"] = OSD.FromString (version);
476
477 args["Logging in Users"] = OSD.FromString(String.Format("{0:0.##}",
478 m_usersLoggingIn));
479 args["GeoPrims"] = OSD.FromString(String.Format("{0:0.##}",
480 m_totalGeoPrims));
481 args["Mesh Objects"] = OSD.FromString(String.Format("{0:0.##}",
482 m_totalMeshes));
483 args["Polygon Count"] = OSD.FromString(String.Format("{0:0.##}", 0));
484 args["Texture Count"] = OSD.FromString(String.Format("{0:0.##}", 0));
485 args["XEngine Thread Count"] = OSD.FromString(String.Format("{0:0.##}",
486 m_inUseThreads));
487 args["Util Thread Count"] = OSD.FromString(String.Format("{0:0.##}",
488 Util.GetSmartThreadPoolInfo().InUseThreads));
489 args["System Thread Count"] = OSD.FromString(String.Format(
490 "{0:0.##}", numberThreadsRunning));
491 args["ProcMem"] = OSD.FromString(String.Format("{0:#,###,###.##}",
492 memUsage));
446 493
447 return args; 494 return args;
448 } 495 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 4715558..052567f 100644..100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -526,6 +526,13 @@ namespace OpenSim.Region.Framework.Scenes
526 get { return m_sceneGraph.PhysicsScene.TimeDilation; } 526 get { return m_sceneGraph.PhysicsScene.TimeDilation; }
527 } 527 }
528 528
529 public void setThreadCount(int inUseThreads)
530 {
531 // Just pass the thread count information on its way as the Scene
532 // does not require the value for anything at this time
533 StatsReporter.SetThreadCount(inUseThreads);
534 }
535
529 public SceneCommunicationService SceneGridService 536 public SceneCommunicationService SceneGridService
530 { 537 {
531 get { return m_sceneGridService; } 538 get { return m_sceneGridService; }
@@ -1107,7 +1114,35 @@ namespace OpenSim.Region.Framework.Scenes
1107 1114
1108 #endregion Interest Management 1115 #endregion Interest Management
1109 1116
1110 StatsReporter = new SimStatsReporter(this); 1117 // The timer used by the Stopwatch class depends on the system hardware and operating system; inform
1118 // if the timer is based on a high-resolution performance counter or based on the system timer;
1119 // the performance counter will provide a more precise time than the system timer
1120 if (Stopwatch.IsHighResolution)
1121 m_log.InfoFormat("[SCENE]: Using high-resolution performance counter for statistics.");
1122 else
1123 m_log.InfoFormat("[SCENE]: Using system timer for statistics.");
1124
1125 // Acquire the statistics section of the OpenSim.ini file located
1126 // in the bin directory
1127 IConfig statisticsConfig = m_config.Configs["Statistics"];
1128
1129 // Confirm that the statistics section existed in the configuration
1130 // file
1131 if (statisticsConfig != null)
1132 {
1133 // Create the StatsReporter using the number of frames to store
1134 // for the frame time statistics, or 10 frames if the config
1135 // file doesn't contain a value
1136 StatsReporter = new SimStatsReporter(this,
1137 statisticsConfig.GetInt("NumberOfFrames", 10));
1138 }
1139 else
1140 {
1141 // Create a StatsReporter with the current scene and a default
1142 // 10 frames stored for the frame time statistics
1143 StatsReporter = new SimStatsReporter(this);
1144 }
1145
1111 StatsReporter.OnSendStatsResult += SendSimStatsPackets; 1146 StatsReporter.OnSendStatsResult += SendSimStatsPackets;
1112 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; 1147 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
1113 1148
@@ -1607,6 +1642,21 @@ namespace OpenSim.Region.Framework.Scenes
1607 float physicsFPS = 0f; 1642 float physicsFPS = 0f;
1608 int previousFrameTick, tmpMS; 1643 int previousFrameTick, tmpMS;
1609 1644
1645 // These variables will be used to save the precise frame time using the
1646 // Stopwatch class of Microsoft SDK; the times are recorded at the start
1647 // and end of a parcticular section of code, and then used to calculate
1648 // the frame times, which are the sums of the sections for each given name
1649 double preciseTotalFrameTime = 0.0;
1650 double preciseSimFrameTime = 0.0;
1651 double precisePhysicsFrameTime = 0.0;
1652 Stopwatch totalFrameStopwatch = new Stopwatch();
1653 Stopwatch simFrameStopwatch = new Stopwatch();
1654 Stopwatch physicsFrameStopwatch = new Stopwatch();
1655
1656 // Begin the stopwatch to keep track of the time that the frame
1657 // started running to determine how long the frame took to complete
1658 totalFrameStopwatch.Start();
1659
1610 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame)) 1660 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1611 { 1661 {
1612 ++Frame; 1662 ++Frame;
@@ -1627,20 +1677,47 @@ namespace OpenSim.Region.Framework.Scenes
1627 terrainMS = Util.EnvironmentTickCountSubtract(tmpMS); 1677 terrainMS = Util.EnvironmentTickCountSubtract(tmpMS);
1628 } 1678 }
1629 1679
1680 // At several points inside the code there was a need to
1681 // create a more precise measurement of time elapsed. This
1682 // led to the addition of variables that have a similar
1683 // function and thus remain tightly connected to their
1684 // original counterparts. However, the original code is
1685 // not receiving comments from our group because we don't
1686 // feel right modifying the code to that degree at this
1687 // point in time, the precise values all begin with the
1688 // keyword precise
1689
1630 tmpMS = Util.EnvironmentTickCount(); 1690 tmpMS = Util.EnvironmentTickCount();
1691
1692 // Begin the stopwatch to track the time to prepare physics
1693 physicsFrameStopwatch.Start();
1631 if (PhysicsEnabled && Frame % m_update_physics == 0) 1694 if (PhysicsEnabled && Frame % m_update_physics == 0)
1632 m_sceneGraph.UpdatePreparePhysics(); 1695 m_sceneGraph.UpdatePreparePhysics();
1696
1697 // Get the time it took to prepare the physics, this
1698 // would report the most precise time that physics was
1699 // running on the machine and should the physics not be
1700 // enabled will report the time it took to check if physics
1701 // was enabled
1702 physicsFrameStopwatch.Stop();
1703 precisePhysicsFrameTime = physicsFrameStopwatch.Elapsed.TotalMilliseconds;
1633 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS); 1704 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS);
1634 1705
1635 // Apply any pending avatar force input to the avatar's velocity 1706 // Apply any pending avatar force input to the avatar's velocity
1636 tmpMS = Util.EnvironmentTickCount(); 1707 tmpMS = Util.EnvironmentTickCount();
1708 simFrameStopwatch.Start();
1637 if (Frame % m_update_entitymovement == 0) 1709 if (Frame % m_update_entitymovement == 0)
1638 m_sceneGraph.UpdateScenePresenceMovement(); 1710 m_sceneGraph.UpdateScenePresenceMovement();
1711
1712 // Get the simulation frame time that the avatar force input took
1713 simFrameStopwatch.Stop();
1714 preciseSimFrameTime = simFrameStopwatch.Elapsed.TotalMilliseconds;
1639 agentMS = Util.EnvironmentTickCountSubtract(tmpMS); 1715 agentMS = Util.EnvironmentTickCountSubtract(tmpMS);
1640 1716
1641 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their 1717 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1642 // velocity 1718 // velocity
1643 tmpMS = Util.EnvironmentTickCount(); 1719 tmpMS = Util.EnvironmentTickCount();
1720 physicsFrameStopwatch.Restart();
1644 if (Frame % m_update_physics == 0) 1721 if (Frame % m_update_physics == 0)
1645 { 1722 {
1646 if (PhysicsEnabled) 1723 if (PhysicsEnabled)
@@ -1649,8 +1726,14 @@ namespace OpenSim.Region.Framework.Scenes
1649 if (SynchronizeScene != null) 1726 if (SynchronizeScene != null)
1650 SynchronizeScene(this); 1727 SynchronizeScene(this);
1651 } 1728 }
1729
1730 // Add the main physics update time to the prepare physics time
1731 physicsFrameStopwatch.Stop();
1732 precisePhysicsFrameTime += physicsFrameStopwatch.Elapsed.TotalMilliseconds;
1652 physicsMS = Util.EnvironmentTickCountSubtract(tmpMS); 1733 physicsMS = Util.EnvironmentTickCountSubtract(tmpMS);
1653 1734
1735 // Start the stopwatch for the remainder of the simulation
1736 simFrameStopwatch.Restart();
1654 tmpMS = Util.EnvironmentTickCount(); 1737 tmpMS = Util.EnvironmentTickCount();
1655 1738
1656 // Check if any objects have reached their targets 1739 // Check if any objects have reached their targets
@@ -1754,6 +1837,10 @@ namespace OpenSim.Region.Framework.Scenes
1754 spareMS = Math.Max(0, MinFrameTicks - physicsMS2 - agentMS - physicsMS - otherMS); 1837 spareMS = Math.Max(0, MinFrameTicks - physicsMS2 - agentMS - physicsMS - otherMS);
1755 } 1838 }
1756 1839
1840 // Get the elapsed time for the simulation frame
1841 simFrameStopwatch.Stop();
1842 preciseSimFrameTime += simFrameStopwatch.Elapsed.TotalMilliseconds;
1843
1757 previousFrameTick = m_lastFrameTick; 1844 previousFrameTick = m_lastFrameTick;
1758 frameMS = Util.EnvironmentTickCountSubtract(m_lastFrameTick); 1845 frameMS = Util.EnvironmentTickCountSubtract(m_lastFrameTick);
1759 m_lastFrameTick = Util.EnvironmentTickCount(); 1846 m_lastFrameTick = Util.EnvironmentTickCount();
@@ -1771,6 +1858,15 @@ namespace OpenSim.Region.Framework.Scenes
1771 StatsReporter.AddSpareMS(spareMS); 1858 StatsReporter.AddSpareMS(spareMS);
1772 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); 1859 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1773 1860
1861 // Send the correct time values to the stats reporter for the
1862 // frame times
1863 StatsReporter.addFrameTimeMilliseconds(preciseTotalFrameTime,
1864 preciseSimFrameTime, precisePhysicsFrameTime, 0.0);
1865
1866 // Send the correct number of frames that the physics library
1867 // has processed to the stats reporter
1868 StatsReporter.addPhysicsFrame(1);
1869
1774 // Optionally warn if a frame takes double the amount of time that it should. 1870 // Optionally warn if a frame takes double the amount of time that it should.
1775 if (DebugUpdates 1871 if (DebugUpdates
1776 && Util.EnvironmentTickCountSubtract( 1872 && Util.EnvironmentTickCountSubtract(
@@ -1782,6 +1878,9 @@ namespace OpenSim.Region.Framework.Scenes
1782 RegionInfo.RegionName); 1878 RegionInfo.RegionName);
1783 } 1879 }
1784 1880
1881 // Finished updating scene frame, so stop the total frame's Stopwatch
1882 totalFrameStopwatch.Stop();
1883
1785 return spareMS >= 0; 1884 return spareMS >= 0;
1786 } 1885 }
1787 1886
@@ -2702,6 +2801,9 @@ namespace OpenSim.Region.Framework.Scenes
2702 bool vialogin; 2801 bool vialogin;
2703 bool reallyNew = true; 2802 bool reallyNew = true;
2704 2803
2804 // Update the number of users attempting to login
2805 StatsReporter.UpdateUsersLoggingIn(true);
2806
2705 // Validation occurs in LLUDPServer 2807 // Validation occurs in LLUDPServer
2706 // 2808 //
2707 // XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with 2809 // XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with
@@ -2786,6 +2888,10 @@ namespace OpenSim.Region.Framework.Scenes
2786 EventManager.TriggerOnClientLogin(client); 2888 EventManager.TriggerOnClientLogin(client);
2787 } 2889 }
2788 2890
2891 // User has logged into the scene so update the list of users logging
2892 // in
2893 StatsReporter.UpdateUsersLoggingIn(false);
2894
2789 m_LastLogin = Util.EnvironmentTickCount(); 2895 m_LastLogin = Util.EnvironmentTickCount();
2790 2896
2791 return sp; 2897 return sp;
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 51f50d9..c2e9b61 100644..100755
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -67,7 +67,9 @@ namespace OpenSim.Region.Framework.Scenes
67 protected Scene m_parentScene; 67 protected Scene m_parentScene;
68 protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); 68 protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
69 protected int m_numRootAgents = 0; 69 protected int m_numRootAgents = 0;
70 protected int m_numTotalPrim = 0;
70 protected int m_numPrim = 0; 71 protected int m_numPrim = 0;
72 protected int m_numMesh = 0;
71 protected int m_numChildAgents = 0; 73 protected int m_numChildAgents = 0;
72 protected int m_physicalPrim = 0; 74 protected int m_physicalPrim = 0;
73 75
@@ -368,7 +370,8 @@ namespace OpenSim.Region.Framework.Scenes
368 370
369 SceneObjectPart[] parts = sceneObject.Parts; 371 SceneObjectPart[] parts = sceneObject.Parts;
370 372
371 // Clamp child prim sizes and add child prims to the m_numPrim count 373 // Clamp the sizes (scales) of the child prims and add the child prims to the count of all primitives
374 // (meshes and geometric primitives) in the scene; add child prims to m_numTotalPrim count
372 if (m_parentScene.m_clampPrimSize) 375 if (m_parentScene.m_clampPrimSize)
373 { 376 {
374 foreach (SceneObjectPart part in parts) 377 foreach (SceneObjectPart part in parts)
@@ -382,7 +385,19 @@ namespace OpenSim.Region.Framework.Scenes
382 part.Shape.Scale = scale; 385 part.Shape.Scale = scale;
383 } 386 }
384 } 387 }
385 m_numPrim += parts.Length; 388 m_numTotalPrim += parts.Length;
389
390 // Go through all parts (geometric primitives and meshes) of this Scene Object
391 foreach (SceneObjectPart part in parts)
392 {
393 // Keep track of the total number of meshes or geometric primitives now in the scene;
394 // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
395 // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
396 if (part.GetPrimType() == PrimType.SCULPT)
397 m_numMesh++;
398 else
399 m_numPrim++;
400 }
386 401
387 sceneObject.AttachToScene(m_parentScene); 402 sceneObject.AttachToScene(m_parentScene);
388 403
@@ -437,7 +452,21 @@ namespace OpenSim.Region.Framework.Scenes
437 452
438 if (!resultOfObjectLinked) 453 if (!resultOfObjectLinked)
439 { 454 {
440 m_numPrim -= grp.PrimCount; 455 // Decrement the total number of primitives (meshes and geometric primitives)
456 // that are part of the Scene Object being removed
457 m_numTotalPrim -= grp.PrimCount;
458
459 // Go through all parts (primitives and meshes) of this Scene Object
460 foreach (SceneObjectPart part in grp.Parts)
461 {
462 // Keep track of the total number of meshes or geometric primitives left in the scene;
463 // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
464 // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
465 if (part.GetPrimType() == PrimType.SCULPT)
466 m_numMesh--;
467 else
468 m_numPrim--;
469 }
441 470
442 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 471 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
443 RemovePhysicalPrim(grp.PrimCount); 472 RemovePhysicalPrim(grp.PrimCount);
@@ -687,9 +716,19 @@ namespace OpenSim.Region.Framework.Scenes
687 716
688 public int GetTotalObjectsCount() 717 public int GetTotalObjectsCount()
689 { 718 {
719 return m_numTotalPrim;
720 }
721
722 public int GetTotalPrimObjectsCount()
723 {
690 return m_numPrim; 724 return m_numPrim;
691 } 725 }
692 726
727 public int GetTotalMeshObjectsCount()
728 {
729 return m_numMesh;
730 }
731
693 public int GetActiveObjectsCount() 732 public int GetActiveObjectsCount()
694 { 733 {
695 return m_physicalPrim; 734 return m_physicalPrim;
@@ -1970,7 +2009,19 @@ namespace OpenSim.Region.Framework.Scenes
1970 // think it's selected, so it will never send a deselect... 2009 // think it's selected, so it will never send a deselect...
1971 copy.IsSelected = false; 2010 copy.IsSelected = false;
1972 2011
1973 m_numPrim += copy.Parts.Length; 2012 m_numTotalPrim += copy.Parts.Length;
2013
2014 // Go through all parts (primitives and meshes) of this Scene Object
2015 foreach (SceneObjectPart part in copy.Parts)
2016 {
2017 // Keep track of the total number of meshes or geometric primitives now in the scene;
2018 // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
2019 // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
2020 if (part.GetPrimType() == PrimType.SCULPT)
2021 m_numMesh++;
2022 else
2023 m_numPrim++;
2024 }
1974 2025
1975 if (rot != Quaternion.Identity) 2026 if (rot != Quaternion.Identity)
1976 { 2027 {
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 8f1e345..b6da636 100644..100755
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -61,6 +61,10 @@ namespace OpenSim.Region.Framework.Scenes
61 61
62 private YourStatsAreWrong handlerStatsIncorrect; 62 private YourStatsAreWrong handlerStatsIncorrect;
63 63
64 // Determines the size of the array that is used to collect StatBlocks
65 // for sending to the SimStats and SimExtraStatsCollector
66 private const int m_statisticArraySize = 26;
67
64 /// <summary> 68 /// <summary>
65 /// These are the IDs of stats sent in the StatsPacket to the viewer. 69 /// These are the IDs of stats sent in the StatsPacket to the viewer.
66 /// </summary> 70 /// </summary>
@@ -104,7 +108,11 @@ namespace OpenSim.Region.Framework.Scenes
104 ScriptEps = 31, 108 ScriptEps = 31,
105 SimSpareMs = 32, 109 SimSpareMs = 32,
106 SimSleepMs = 33, 110 SimSleepMs = 33,
107 SimIoPumpTime = 34 111 SimIoPumpTime = 34,
112 UsersLoggingIn = 35,
113 TotalGeoPrim = 36,
114 TotalMesh = 37,
115 ThreadCount = 38
108 } 116 }
109 117
110 /// <summary> 118 /// <summary>
@@ -175,7 +183,7 @@ namespace OpenSim.Region.Framework.Scenes
175 183
176 // saved last reported value so there is something available for llGetRegionFPS 184 // saved last reported value so there is something available for llGetRegionFPS
177 private float lastReportedSimFPS; 185 private float lastReportedSimFPS;
178 private float[] lastReportedSimStats = new float[22]; 186 private float[] lastReportedSimStats = new float[m_statisticArraySize];
179 private float m_pfps; 187 private float m_pfps;
180 188
181 /// <summary> 189 /// <summary>
@@ -202,6 +210,8 @@ namespace OpenSim.Region.Framework.Scenes
202 private int m_rootAgents; 210 private int m_rootAgents;
203 private int m_childAgents; 211 private int m_childAgents;
204 private int m_numPrim; 212 private int m_numPrim;
213 private int m_numGeoPrim;
214 private int m_numMesh;
205 private int m_inPacketsPerSecond; 215 private int m_inPacketsPerSecond;
206 private int m_outPacketsPerSecond; 216 private int m_outPacketsPerSecond;
207 private int m_activePrim; 217 private int m_activePrim;
@@ -213,6 +223,34 @@ namespace OpenSim.Region.Framework.Scenes
213 223
214 private int m_objectCapacity = 45000; 224 private int m_objectCapacity = 45000;
215 225
226 // This is the number of frames that will be stored and then averaged for
227 // the Total, Simulation, Physics, and Network Frame Time; It is set to
228 // 10 by default but can be changed by the OpenSim.ini configuration file
229 // NumberOfFrames parameter
230 private int m_numberFramesStored = 10;
231
232 // The arrays that will hold the time it took to run the past N frames,
233 // where N is the num_frames_to_average given by the configuration file
234 private double[] m_totalFrameTimeMilliseconds;
235 private double[] m_simulationFrameTimeMilliseconds;
236 private double[] m_physicsFrameTimeMilliseconds;
237 private double[] m_networkFrameTimeMilliseconds;
238
239 // The location of the next time in milliseconds that will be
240 // (over)written when the next frame completes
241 private int m_nextLocation = 0;
242
243 // The correct number of frames that have completed since the last stats
244 // update for physics
245 private int m_numberPhysicsFrames;
246
247 // The current number of users attempting to login to the region
248 private int m_usersLoggingIn;
249
250 // The last reported value of threads from the SmartThreadPool inside of
251 // XEngine
252 private int m_inUseThreads;
253
216 private Scene m_scene; 254 private Scene m_scene;
217 255
218 private RegionInfo ReportingRegion; 256 private RegionInfo ReportingRegion;
@@ -223,6 +261,15 @@ namespace OpenSim.Region.Framework.Scenes
223 261
224 public SimStatsReporter(Scene scene) 262 public SimStatsReporter(Scene scene)
225 { 263 {
264 // Initialize the different frame time arrays to the correct sizes
265 m_totalFrameTimeMilliseconds = new double[m_numberFramesStored];
266 m_simulationFrameTimeMilliseconds = new double[m_numberFramesStored];
267 m_physicsFrameTimeMilliseconds = new double[m_numberFramesStored];
268 m_networkFrameTimeMilliseconds = new double[m_numberFramesStored];
269
270 // Initialize the current number of users logging into the region
271 m_usersLoggingIn = 0;
272
226 m_scene = scene; 273 m_scene = scene;
227 m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps; 274 m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps;
228 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000); 275 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
@@ -256,6 +303,14 @@ namespace OpenSim.Region.Framework.Scenes
256 StatsManager.RegisterStat(SlowFramesStat); 303 StatsManager.RegisterStat(SlowFramesStat);
257 } 304 }
258 305
306
307 public SimStatsReporter(Scene scene, int numberOfFrames) : this (scene)
308 {
309 // Store the number of frames from the OpenSim.ini configuration file
310 m_numberFramesStored = numberOfFrames;
311 }
312
313
259 public void Close() 314 public void Close()
260 { 315 {
261 m_report.Elapsed -= TriggerStatsHeartbeat; 316 m_report.Elapsed -= TriggerStatsHeartbeat;
@@ -289,10 +344,21 @@ namespace OpenSim.Region.Framework.Scenes
289 344
290 private void statsHeartBeat(object sender, EventArgs e) 345 private void statsHeartBeat(object sender, EventArgs e)
291 { 346 {
347 double totalSumFrameTime;
348 double simulationSumFrameTime;
349 double physicsSumFrameTime;
350 double networkSumFrameTime;
351 float timeDilation;
352 int currentFrame;
353
292 if (!m_scene.Active) 354 if (!m_scene.Active)
293 return; 355 return;
294 356
295 SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[22]; 357 // Create arrays to hold the statistics for this current scene,
358 // these will be passed to the SimExtraStatsCollector, they are also
359 // sent to the SimStats class
360 SimStatsPacket.StatBlock[] sb = new
361 SimStatsPacket.StatBlock[m_statisticArraySize];
296 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock(); 362 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
297 363
298 // Know what's not thread safe in Mono... modifying timers. 364 // Know what's not thread safe in Mono... modifying timers.
@@ -314,14 +380,21 @@ namespace OpenSim.Region.Framework.Scenes
314 380
315#region various statistic googly moogly 381#region various statistic googly moogly
316 382
383 // ORIGINAL code commented out until we have time to add our own
384 // statistics to the statistics window, this will be done as a
385 // new section given the title of our current project
317 // We're going to lie about the FPS because we've been lying since 2008. The actual FPS is currently 386 // We're going to lie about the FPS because we've been lying since 2008. The actual FPS is currently
318 // locked at a maximum of 11. Maybe at some point this can change so that we're not lying. 387 // locked at a maximum of 11. Maybe at some point this can change so that we're not lying.
319 int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor); 388 //int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor);
389 int reportedFPS = m_fps;
320 390
321 // save the reported value so there is something available for llGetRegionFPS 391 // save the reported value so there is something available for llGetRegionFPS
322 lastReportedSimFPS = reportedFPS / m_statsUpdateFactor; 392 lastReportedSimFPS = reportedFPS / m_statsUpdateFactor;
323 393
324 float physfps = ((m_pfps / 1000)); 394 // ORIGINAL code commented out until we have time to add our own
395 // statistics to the statistics window
396 //float physfps = ((m_pfps / 1000));
397 float physfps = m_numberPhysicsFrames;
325 398
326 //if (physfps > 600) 399 //if (physfps > 600)
327 //physfps = physfps - (physfps - 600); 400 //physfps = physfps - (physfps - 600);
@@ -334,6 +407,8 @@ namespace OpenSim.Region.Framework.Scenes
334 m_rootAgents = m_scene.SceneGraph.GetRootAgentCount(); 407 m_rootAgents = m_scene.SceneGraph.GetRootAgentCount();
335 m_childAgents = m_scene.SceneGraph.GetChildAgentCount(); 408 m_childAgents = m_scene.SceneGraph.GetChildAgentCount();
336 m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount(); 409 m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount();
410 m_numGeoPrim = m_scene.SceneGraph.GetTotalPrimObjectsCount();
411 m_numMesh = m_scene.SceneGraph.GetTotalMeshObjectsCount();
337 m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount(); 412 m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount();
338 m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount(); 413 m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount();
339 414
@@ -359,13 +434,48 @@ namespace OpenSim.Region.Framework.Scenes
359 if (framesUpdated == 0) 434 if (framesUpdated == 0)
360 framesUpdated = 1; 435 framesUpdated = 1;
361 436
362 for (int i = 0; i < 22; i++) 437 for (int i = 0; i < m_statisticArraySize; i++)
363 { 438 {
364 sb[i] = new SimStatsPacket.StatBlock(); 439 sb[i] = new SimStatsPacket.StatBlock();
365 } 440 }
366 441
442 // Resetting the sums of the frame times to prevent any errors
443 // in calculating the moving average for frame time
444 totalSumFrameTime = 0;
445 simulationSumFrameTime = 0;
446 physicsSumFrameTime = 0;
447 networkSumFrameTime = 0;
448
449 // Loop through all the frames that were stored for the current
450 // heartbeat to process the moving average of frame times
451 for (int i = 0; i < m_numberFramesStored; i++)
452 {
453 // Sum up each frame time in order to calculate the moving
454 // average of frame time
455 totalSumFrameTime += m_totalFrameTimeMilliseconds[i];
456 simulationSumFrameTime +=
457 m_simulationFrameTimeMilliseconds[i];
458 physicsSumFrameTime += m_physicsFrameTimeMilliseconds[i];
459 networkSumFrameTime += m_networkFrameTimeMilliseconds[i];
460 }
461
462 // Get the index that represents the current frame based on the next one known; go back
463 // to the last index if next one is stated to restart at 0
464 if (m_nextLocation == 0)
465 currentFrame = m_numberFramesStored - 1;
466 else
467 currentFrame = m_nextLocation - 1;
468
469 // Calculate the time dilation; which is currently based on the ratio between the sum of the
470 // physics and simulation rate, and the set minimum time to run the scene's update; minFrameTime
471 // is given in seconds so multiply by 1000 to convert it to milliseconds
472 timeDilation = (float)(m_simulationFrameTimeMilliseconds[currentFrame] +
473 m_physicsFrameTimeMilliseconds[currentFrame]) / (m_scene.MinFrameTime * 1000);
474
475 // ORIGINAL code commented out until we have time to add our own
367 sb[0].StatID = (uint) Stats.TimeDilation; 476 sb[0].StatID = (uint) Stats.TimeDilation;
368 sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor)); 477 //sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor));
478 sb[0].StatValue = timeDilation;
369 479
370 sb[1].StatID = (uint) Stats.SimFPS; 480 sb[1].StatID = (uint) Stats.SimFPS;
371 sb[1].StatValue = reportedFPS / m_statsUpdateFactor; 481 sb[1].StatValue = reportedFPS / m_statsUpdateFactor;
@@ -388,20 +498,27 @@ namespace OpenSim.Region.Framework.Scenes
388 sb[7].StatID = (uint) Stats.ActivePrim; 498 sb[7].StatID = (uint) Stats.ActivePrim;
389 sb[7].StatValue = m_activePrim; 499 sb[7].StatValue = m_activePrim;
390 500
501 // ORIGINAL code commented out until we have time to add our own
502 // statistics to the statistics window
391 sb[8].StatID = (uint)Stats.FrameMS; 503 sb[8].StatID = (uint)Stats.FrameMS;
392 sb[8].StatValue = m_frameMS / framesUpdated; 504 //sb[8].StatValue = m_frameMS / framesUpdated;
505 sb[8].StatValue = (float) totalSumFrameTime / m_numberFramesStored;
393 506
394 sb[9].StatID = (uint)Stats.NetMS; 507 sb[9].StatID = (uint)Stats.NetMS;
395 sb[9].StatValue = m_netMS / framesUpdated; 508 //sb[9].StatValue = m_netMS / framesUpdated;
509 sb[9].StatValue = (float) networkSumFrameTime / m_numberFramesStored;
396 510
397 sb[10].StatID = (uint)Stats.PhysicsMS; 511 sb[10].StatID = (uint)Stats.PhysicsMS;
398 sb[10].StatValue = m_physicsMS / framesUpdated; 512 //sb[10].StatValue = m_physicsMS / framesUpdated;
513 sb[10].StatValue = (float) physicsSumFrameTime / m_numberFramesStored;
399 514
400 sb[11].StatID = (uint)Stats.ImageMS ; 515 sb[11].StatID = (uint)Stats.ImageMS ;
401 sb[11].StatValue = m_imageMS / framesUpdated; 516 sb[11].StatValue = m_imageMS / framesUpdated;
402 517
403 sb[12].StatID = (uint)Stats.OtherMS; 518 sb[12].StatID = (uint)Stats.OtherMS;
404 sb[12].StatValue = m_otherMS / framesUpdated; 519 //sb[12].StatValue = m_otherMS / framesUpdated;
520 sb[12].StatValue = (float) simulationSumFrameTime /
521 m_numberFramesStored;
405 522
406 sb[13].StatID = (uint)Stats.InPacketsPerSecond; 523 sb[13].StatID = (uint)Stats.InPacketsPerSecond;
407 sb[13].StatValue = (m_inPacketsPerSecond / m_statsUpdateFactor); 524 sb[13].StatValue = (m_inPacketsPerSecond / m_statsUpdateFactor);
@@ -430,7 +547,25 @@ namespace OpenSim.Region.Framework.Scenes
430 sb[21].StatID = (uint)Stats.SimSpareMs; 547 sb[21].StatID = (uint)Stats.SimSpareMs;
431 sb[21].StatValue = m_spareMS / framesUpdated; 548 sb[21].StatValue = m_spareMS / framesUpdated;
432 549
433 for (int i = 0; i < 22; i++) 550 // Added to track the number of users currently attempting to
551 // login to the region
552 sb[22].StatID = (uint)Stats.UsersLoggingIn;
553 sb[22].StatValue = m_usersLoggingIn;
554
555 // Total number of geometric primitives in the scene
556 sb[23].StatID = (uint)Stats.TotalGeoPrim;
557 sb[23].StatValue = m_numGeoPrim;
558
559 // Total number of mesh objects in the scene
560 sb[24].StatID = (uint)Stats.TotalMesh;
561 sb[24].StatValue = m_numMesh;
562
563 // Added to track the current number of threads that XEngine is
564 // using
565 sb[25].StatID = (uint)Stats.ThreadCount;
566 sb[25].StatValue = m_inUseThreads;
567
568 for (int i = 0; i < m_statisticArraySize; i++)
434 { 569 {
435 lastReportedSimStats[i] = sb[i].StatValue; 570 lastReportedSimStats[i] = sb[i].StatValue;
436 } 571 }
@@ -475,6 +610,10 @@ namespace OpenSim.Region.Framework.Scenes
475 610
476 private void ResetValues() 611 private void ResetValues()
477 { 612 {
613 // Reset the number of frames that the physics library has
614 // processed since the last stats report
615 m_numberPhysicsFrames = 0;
616
478 m_timeDilation = 0; 617 m_timeDilation = 0;
479 m_fps = 0; 618 m_fps = 0;
480 m_pfps = 0; 619 m_pfps = 0;
@@ -605,6 +744,32 @@ namespace OpenSim.Region.Framework.Scenes
605 m_otherMS += ms; 744 m_otherMS += ms;
606 } 745 }
607 746
747 public void addPhysicsFrame(int frames)
748 {
749 // Add the number of physics frames to the correct total physics
750 // frames
751 m_numberPhysicsFrames += frames;
752 }
753
754 public void addFrameTimeMilliseconds(double total, double simulation,
755 double physics, double network)
756 {
757 // Save the frame times from the current frame into the appropriate
758 // arrays
759 m_totalFrameTimeMilliseconds[m_nextLocation] = total;
760 m_simulationFrameTimeMilliseconds[m_nextLocation] = simulation;
761 m_physicsFrameTimeMilliseconds[m_nextLocation] = physics;
762 m_networkFrameTimeMilliseconds[m_nextLocation] = network;
763
764 // Update to the next location in the list
765 m_nextLocation++;
766
767 // Since the list will begin to overwrite the oldest frame values
768 // first, the next location needs to loop back to the beginning of the
769 // list whenever it reaches the end
770 m_nextLocation = m_nextLocation % m_numberFramesStored;
771 }
772
608 public void AddPendingDownloads(int count) 773 public void AddPendingDownloads(int count)
609 { 774 {
610 m_pendingDownloads += count; 775 m_pendingDownloads += count;
@@ -627,6 +792,31 @@ namespace OpenSim.Region.Framework.Scenes
627 AddunAckedBytes(unAckedBytes); 792 AddunAckedBytes(unAckedBytes);
628 } 793 }
629 794
795 public void UpdateUsersLoggingIn(bool isLoggingIn)
796 {
797 // Determine whether the user has started logging in or has completed
798 // logging into the region
799 if (isLoggingIn)
800 {
801 // The user is starting to login to the region so increment the
802 // number of users attempting to login to the region
803 m_usersLoggingIn++;
804 }
805 else
806 {
807 // The user has finished logging into the region so decrement the
808 // number of users logging into the region
809 m_usersLoggingIn--;
810 }
811 }
812
813 public void SetThreadCount(int inUseThreads)
814 {
815 // Save the new number of threads to our member variable to send to
816 // the extra stats collector
817 m_inUseThreads = inUseThreads;
818 }
819
630 #endregion 820 #endregion
631 821
632 public Dictionary<string, float> GetExtraSimStats() 822 public Dictionary<string, float> GetExtraSimStats()
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 54620d1..4e383f8 100644..100755
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -1872,6 +1872,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1872 IScriptInstance instance = GetInstance(itemID); 1872 IScriptInstance instance = GetInstance(itemID);
1873 if (instance != null) 1873 if (instance != null)
1874 instance.ApiResetScript(); 1874 instance.ApiResetScript();
1875
1876 // Send the new number of threads that are in use by the thread
1877 // pool, I believe that by adding them to the locations where the
1878 // script is changing states that I will catch all changes to the
1879 // thread pool
1880 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
1875 } 1881 }
1876 1882
1877 public void ResetScript(UUID itemID) 1883 public void ResetScript(UUID itemID)
@@ -1879,6 +1885,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1879 IScriptInstance instance = GetInstance(itemID); 1885 IScriptInstance instance = GetInstance(itemID);
1880 if (instance != null) 1886 if (instance != null)
1881 instance.ResetScript(m_WaitForEventCompletionOnScriptStop); 1887 instance.ResetScript(m_WaitForEventCompletionOnScriptStop);
1888
1889 // Send the new number of threads that are in use by the thread
1890 // pool, I believe that by adding them to the locations where the
1891 // script is changing states that I will catch all changes to the
1892 // thread pool
1893 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
1882 } 1894 }
1883 1895
1884 public void StartScript(UUID itemID) 1896 public void StartScript(UUID itemID)
@@ -1888,6 +1900,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1888 instance.Start(); 1900 instance.Start();
1889 else 1901 else
1890 m_runFlags.AddOrUpdate(itemID, true, 240); 1902 m_runFlags.AddOrUpdate(itemID, true, 240);
1903
1904 // Send the new number of threads that are in use by the thread
1905 // pool, I believe that by adding them to the locations where the
1906 // script is changing states that I will catch all changes to the
1907 // thread pool
1908 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
1891 } 1909 }
1892 1910
1893 public void StopScript(UUID itemID) 1911 public void StopScript(UUID itemID)
@@ -1903,6 +1921,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1903// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name); 1921// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name);
1904 m_runFlags.AddOrUpdate(itemID, false, 240); 1922 m_runFlags.AddOrUpdate(itemID, false, 240);
1905 } 1923 }
1924
1925 // Send the new number of threads that are in use by the thread
1926 // pool, I believe that by adding them to the locations where the
1927 // script is changing states that I will catch all changes to the
1928 // thread pool
1929 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
1906 } 1930 }
1907 1931
1908 public DetectParams GetDetectParams(UUID itemID, int idx) 1932 public DetectParams GetDetectParams(UUID itemID, int idx)
@@ -2393,6 +2417,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
2393 instance.Suspend(); 2417 instance.Suspend();
2394// else 2418// else
2395// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); 2419// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
2420
2421 // Send the new number of threads that are in use by the thread
2422 // pool, I believe that by adding them to the locations where the
2423 // script is changing states that I will catch all changes to the
2424 // thread pool
2425 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
2396 } 2426 }
2397 2427
2398 public void ResumeScript(UUID itemID) 2428 public void ResumeScript(UUID itemID)
@@ -2404,6 +2434,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
2404 instance.Resume(); 2434 instance.Resume();
2405// else 2435// else
2406// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); 2436// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
2437
2438 // Send the new number of threads that are in use by the thread
2439 // pool, I believe that by adding them to the locations where the
2440 // script is changing states that I will catch all changes to the
2441 // thread pool
2442 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
2407 } 2443 }
2408 2444
2409 public bool HasScript(UUID itemID, out bool running) 2445 public bool HasScript(UUID itemID, out bool running)