From 081f4403ea2a2f8352d480910052bf5032e2e4a5 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Wed, 12 Dec 2007 06:58:55 +0000 Subject: [PATCH] * Added some simstats to fill the simulator pane of the Statistics monitor. * I stress, this is an initial implementation and the Agents(Child and Root) are definately obviously incorrect. --- .../Region/Environment/Scenes/InnerScene.cs | 52 +++++- OpenSim/Region/Environment/Scenes/Scene.cs | 78 ++++++++- .../Environment/Scenes/ScenePresence.cs | 3 +- .../Environment/Scenes/SimStatsReporter.cs | 158 ++++++++++++++++++ .../BasicPhysicsPlugin/BasicPhysicsPlugin.cs | 4 +- .../Physics/BulletXPlugin/BulletXPlugin.cs | 8 +- .../Region/Physics/Manager/PhysicsScene.cs | 5 +- OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 52 +++--- OpenSim/Region/Physics/POSPlugin/POSPlugin.cs | 5 +- .../Region/Physics/PhysXPlugin/PhysXPlugin.cs | 4 +- 10 files changed, 335 insertions(+), 34 deletions(-) create mode 100644 OpenSim/Region/Environment/Scenes/SimStatsReporter.cs diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index c0e07cb339..b274d47a02 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs @@ -57,6 +57,9 @@ namespace OpenSim.Region.Environment.Scenes protected RegionInfo m_regInfo; protected Scene m_parentScene; protected PermissionManager PermissionsMngr; + protected int m_numRootAgents = 0; + protected int m_numPrim = 0; + protected int m_numChildAgents = 0; internal object m_syncRoot = new object(); @@ -133,11 +136,11 @@ namespace OpenSim.Region.Environment.Scenes } } - internal void UpdatePhysics(double elapsed) + internal float UpdatePhysics(double elapsed) { lock (m_syncRoot) { - _PhyScene.Simulate((float)elapsed); + return _PhyScene.Simulate((float)elapsed); } } @@ -171,6 +174,7 @@ namespace OpenSim.Region.Environment.Scenes { // QuadTree.AddObject(sceneObject); Entities.Add(sceneObject.UUID, sceneObject); + m_numPrim++; } } @@ -183,6 +187,7 @@ namespace OpenSim.Region.Environment.Scenes if (((SceneObjectGroup)obj).LocalId == localID) { m_parentScene.RemoveEntity((SceneObjectGroup)obj); + m_numPrim--; return; } } @@ -198,10 +203,12 @@ namespace OpenSim.Region.Environment.Scenes if (child) { + m_numChildAgents++; MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Creating new child agent."); } else { + m_numRootAgents++; MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Creating new root agent."); MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Adding Physical agent."); @@ -233,6 +240,47 @@ namespace OpenSim.Region.Environment.Scenes return newAvatar; } + public void SwapRootChildAgent(bool direction_RC_CR_T_F) + { + if (direction_RC_CR_T_F) + { + m_numRootAgents--; + m_numChildAgents++; + } + else + { + m_numChildAgents--; + m_numRootAgents++; + } + } + public void removeUserCount(bool TypeRCTF) + { + if (TypeRCTF) + { + m_numRootAgents--; + } + else + { + m_numChildAgents--; + } + } + public void RemoveAPrimCount() + { + m_numPrim--; + } + public void AddAPrimCount() + { + m_numPrim++; + } + public int GetChildAgentCount() + { + return m_numChildAgents; + } + + public int GetRootAgentCount() + { + return m_numRootAgents; + } #endregion #region Get Methods diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index f2b5643225..5462e77954 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -59,6 +59,8 @@ namespace OpenSim.Region.Environment.Scenes protected Timer m_heartbeatTimer = new Timer(); protected Timer m_restartWaitTimer = new Timer(); + protected SimStatsReporter m_statsReporter; + protected List m_regionRestartNotifyList = new List(); protected List m_neighbours = new List(); @@ -256,6 +258,9 @@ namespace OpenSim.Region.Environment.Scenes httpListener = httpServer; m_dumpAssetsToFile = dumpAssetsToFile; + + m_statsReporter = new SimStatsReporter(regInfo); + m_statsReporter.OnSendStatsResult += SendSimStatsPackets; } #endregion @@ -531,7 +536,7 @@ namespace OpenSim.Region.Environment.Scenes TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate; // Aquire a lock so only one update call happens at once updateLock.WaitOne(); - + float physicsFPS = 0; try { // Increment the frame counter @@ -548,7 +553,7 @@ namespace OpenSim.Region.Environment.Scenes m_innerScene.UpdateEntityMovement(); if (m_frame % m_update_physics == 0) - m_innerScene.UpdatePhysics( + physicsFPS = m_innerScene.UpdatePhysics( Math.Max(SinceLastFrame.TotalSeconds, m_timespan) ); @@ -569,6 +574,14 @@ namespace OpenSim.Region.Environment.Scenes // if (m_frame%m_update_avatars == 0) // UpdateInWorldTime(); + m_statsReporter.AddPhysicsFPS(physicsFPS); + m_statsReporter.SetTimeDilation(m_timedilation); + m_statsReporter.AddFPS(1); + m_statsReporter.AddAgentUpdates(1); + m_statsReporter.AddInPackets(0); + m_statsReporter.SetRootAgents(m_innerScene.GetRootAgentCount()); + m_statsReporter.SetChildAgents(m_innerScene.GetChildAgentCount()); + } catch (NotImplementedException) { @@ -607,6 +620,19 @@ namespace OpenSim.Region.Environment.Scenes } } + private void SendSimStatsPackets(libsecondlife.Packets.SimStatsPacket pack) + { + List StatSendAgents = GetScenePresences(); + foreach (ScenePresence agent in StatSendAgents) + { + if (!agent.IsChildAgent) + { + agent.ControllingClient.OutPacket(pack, ThrottleOutPacketType.Task); + + } + } + + } private void UpdateLand() { if (m_LandManager.landPrimCountTainted) @@ -939,6 +965,7 @@ namespace OpenSim.Region.Environment.Scenes // subscribe to physics events. rootPart.DoPhysicsPropertyUpdate(UsePhysics, true); } + m_innerScene.AddAPrimCount(); } } @@ -967,6 +994,7 @@ namespace OpenSim.Region.Environment.Scenes public void AddEntity(SceneObjectGroup sceneObject) { m_innerScene.AddEntity(sceneObject); + } public void RemoveEntity(SceneObjectGroup sceneObject) @@ -976,6 +1004,7 @@ namespace OpenSim.Region.Environment.Scenes m_LandManager.removePrimFromLandPrimCounts(sceneObject); Entities.Remove(sceneObject.UUID); m_LandManager.setPrimsTainted(); + m_innerScene.RemoveAPrimCount(); } } @@ -1135,7 +1164,16 @@ namespace OpenSim.Region.Environment.Scenes m_eventManager.TriggerOnRemovePresence(agentID); ScenePresence avatar = GetScenePresence(agentID); - + + if (avatar.IsChildAgent) + { + m_innerScene.removeUserCount(false); + } + else + { + m_innerScene.removeUserCount(true); + } + Broadcast(delegate(IClientAPI client) { try @@ -1196,6 +1234,7 @@ namespace OpenSim.Region.Environment.Scenes { Entities.Remove(entID); m_storageManager.DataStore.RemoveObject(entID, m_regInfo.RegionID); + m_innerScene.RemoveAPrimCount(); return true; } return false; @@ -1287,6 +1326,7 @@ namespace OpenSim.Region.Environment.Scenes if (m_scenePresences.ContainsKey(agentID)) { m_scenePresences[agentID].MakeRootAgent(position, isFlying); + m_innerScene.SwapRootChildAgent(false); } } } @@ -1321,6 +1361,14 @@ namespace OpenSim.Region.Environment.Scenes ScenePresence presence = m_innerScene.GetScenePresence(agentID); if (presence != null) { + if (presence.IsChildAgent) + { + m_innerScene.removeUserCount(false); + } + else + { + m_innerScene.removeUserCount(true); + } // Tell a single agent to disconnect from the region. libsecondlife.Packets.DisableSimulatorPacket disable = new libsecondlife.Packets.DisableSimulatorPacket(); presence.ControllingClient.OutPacket(disable, ThrottleOutPacketType.Task); @@ -1617,6 +1665,16 @@ namespace OpenSim.Region.Environment.Scenes if (controller.AgentId != godID && !childagent) // Do we really want to kick the initiator of this madness? { controller.Kick(Helpers.FieldToUTF8String(reason)); + + if (childagent) + { + m_innerScene.removeUserCount(false); + } + else + { + m_innerScene.removeUserCount(true); + } + } } ); @@ -1636,6 +1694,15 @@ namespace OpenSim.Region.Environment.Scenes } else { + if (m_scenePresences[agentID].IsChildAgent) + { + m_innerScene.removeUserCount(false); + } + else + { + m_innerScene.removeUserCount(true); + } + m_scenePresences[agentID].ControllingClient.Kick(Helpers.FieldToUTF8String(reason)); m_scenePresences[agentID].ControllingClient.Close(); } @@ -1848,7 +1915,10 @@ namespace OpenSim.Region.Environment.Scenes { return m_innerScene.ConvertLocalIDToFullID(localID); } - + public void SwapRootAgentCount(bool rootChildChildRootTF) + { + m_innerScene.SwapRootChildAgent(rootChildChildRootTF); + } /// /// /// diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index c82d066047..06400670df 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -465,6 +465,7 @@ namespace OpenSim.Region.Environment.Scenes AddToPhysicalScene(); m_physicsActor.Flying = isFlying; + m_scene.SwapRootAgentCount(false); m_scene.CommsManager.UserProfileCacheService.UpdateUserInventory(m_uuid); //if (!m_gotAllObjectsInScene) //{ @@ -484,7 +485,7 @@ namespace OpenSim.Region.Environment.Scenes { Velocity = new LLVector3(0, 0, 0); m_isChildAgent = true; - + m_scene.SwapRootAgentCount(true); RemoveFromPhysicalScene(); //this.Pos = new LLVector3(128, 128, 70); diff --git a/OpenSim/Region/Environment/Scenes/SimStatsReporter.cs b/OpenSim/Region/Environment/Scenes/SimStatsReporter.cs new file mode 100644 index 0000000000..55bd6a7fa5 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/SimStatsReporter.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Timers; +using libsecondlife.Packets; +using OpenSim.Framework; +using Timer = System.Timers.Timer; + +namespace OpenSim.Region.Environment.Scenes +{ + public class SimStatsReporter + { + public delegate void SendStatResult(SimStatsPacket pack); + + public event SendStatResult OnSendStatsResult; + + private enum Stats : uint + { + TimeDilation = 0, + SimFPS = 1, + PhysicsFPS = 2, + AgentUpdates = 3, + Agents = 13, + ChildAgents = 14, + InPacketsPerSecond = 17, + OutPacketsPerSecond = 18, + UnAckedBytes = 24 + } + + private int statsUpdatesEveryMS = 1000; + private float m_timeDilation = 0; + private int m_fps = 0; + private float m_pfps = 0; + private float m_agentUpdates = 0; + private int m_rootAgents = 0; + private int m_childAgents = 0; + private int m_inPacketsPerSecond = 0; + private int m_outPacketsPerSecond = 0; + private int m_unAckedBytes = 0; + private RegionInfo ReportingRegion; + + private Timer m_report = new Timer(); + + + public SimStatsReporter(RegionInfo regionData) + { + ReportingRegion = regionData; + m_report.AutoReset = true; + m_report.Interval = statsUpdatesEveryMS; + m_report.Elapsed += new ElapsedEventHandler(statsHeartBeat); + m_report.Enabled = true; + } + + private void statsHeartBeat(object sender, EventArgs e) + { + m_report.Enabled = false; + SimStatsPacket statpack = new SimStatsPacket(); + SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[9]; + statpack.Region = new SimStatsPacket.RegionBlock(); + statpack.Region.RegionX = ReportingRegion.RegionLocX; + statpack.Region.RegionY = ReportingRegion.RegionLocY; + statpack.Region.RegionFlags = (uint)21; + statpack.Region.ObjectCapacity = (uint)15000; + + sb[0] = new SimStatsPacket.StatBlock(); + sb[0].StatID = (uint)Stats.TimeDilation; + sb[0].StatValue = (m_timeDilation); + + sb[1] = new SimStatsPacket.StatBlock(); + sb[1].StatID = (uint)Stats.SimFPS; + sb[1].StatValue = (int)(m_fps); + + sb[2] = new SimStatsPacket.StatBlock(); + sb[2].StatID = (uint)Stats.PhysicsFPS; + sb[2].StatValue = (m_pfps / statsUpdatesEveryMS); + + sb[3] = new SimStatsPacket.StatBlock(); + sb[3].StatID = (uint)Stats.AgentUpdates; + sb[3].StatValue = (m_agentUpdates / statsUpdatesEveryMS); + + sb[4] = new SimStatsPacket.StatBlock(); + sb[4].StatID = (uint)Stats.Agents; + sb[4].StatValue = m_rootAgents; + + sb[5] = new SimStatsPacket.StatBlock(); + sb[5].StatID = (uint)Stats.ChildAgents; + sb[5].StatValue = m_childAgents; + + sb[6] = new SimStatsPacket.StatBlock(); + sb[6].StatID = (uint)Stats.InPacketsPerSecond; + sb[6].StatValue = (int)(m_inPacketsPerSecond / statsUpdatesEveryMS); + + sb[7] = new SimStatsPacket.StatBlock(); + sb[7].StatID = (uint)Stats.OutPacketsPerSecond; + sb[7].StatValue = (int)(m_outPacketsPerSecond / statsUpdatesEveryMS); + + sb[8] = new SimStatsPacket.StatBlock(); + sb[8].StatID = (uint)Stats.UnAckedBytes; + sb[8].StatValue = (int) (m_unAckedBytes / statsUpdatesEveryMS); + + statpack.Stat = sb; + + if (OnSendStatsResult != null) + { + OnSendStatsResult(statpack); + } + resetvalues(); + m_report.Enabled = true; + } + + private void resetvalues() + { + m_fps = 0; + m_pfps = 0; + m_agentUpdates = 0; + m_inPacketsPerSecond = 0; + m_outPacketsPerSecond = 0; + m_unAckedBytes = 0; + + } + public void SetTimeDilation(float td) + { + m_timeDilation = td; + } + public void SetRootAgents(int rootAgents) + { + m_rootAgents = rootAgents; + } + public void SetChildAgents(int childAgents) + { + m_childAgents = childAgents; + } + public void AddFPS(int frames) + { + m_fps += frames; + } + public void AddPhysicsFPS(float frames) + { + m_pfps += frames; + } + public void AddAgentUpdates(float numUpdates) + { + m_agentUpdates += numUpdates; + } + public void AddInPackets(int numPackets) + { + m_inPacketsPerSecond += numPackets; + } + public void AddOutPackets(int numPackets) + { + m_outPacketsPerSecond += numPackets; + } + public void AddunAckedBytes(int numBytes) + { + m_unAckedBytes += numBytes; + } + } +} diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs index 6b647b16a6..df3ebb9649 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs @@ -118,8 +118,9 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin { } - public override void Simulate(float timeStep) + public override float Simulate(float timeStep) { + float fps = 0; for (int i = 0; i < _actors.Count; ++i) { BasicActor actor = _actors[i]; @@ -164,6 +165,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin actor.Velocity.Z = 0; } } + return fps; } public override void GetResults() diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs index 4b1043ab05..1760e5047f 100644 --- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs +++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs @@ -515,20 +515,26 @@ namespace OpenSim.Region.Physics.BulletXPlugin { } - public override void Simulate(float timeStep) + public override float Simulate(float timeStep) { + float fps = 0; lock (BulletXLock) { //Try to remove garbage RemoveForgottenRigidBodies(); //End of remove MoveAllObjects(timeStep); + + + fps = (timeStep * simulationSubSteps); + ddWorld.StepSimulation(timeStep, simulationSubSteps, timeStep); //Extra Heightmap Validation: BulletX's HeightFieldTerrain somestimes doesn't work so fine. ValidateHeightForAll(); //End heightmap validation. UpdateKineticsForAll(); } + return fps; } private void MoveAllObjects(float timeStep) diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 71cba22555..c63a66dfa8 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.Physics.Manager PhysicsVector size, Quaternion rotation, bool isPhysical); public abstract void AddPhysicsActorTaint(PhysicsActor prim); - public abstract void Simulate(float timeStep); + public abstract float Simulate(float timeStep); public abstract void GetResults(); @@ -126,11 +126,12 @@ namespace OpenSim.Region.Physics.Manager { } - public override void Simulate(float timeStep) + public override float Simulate(float timeStep) { m_workIndicator = (m_workIndicator + 1)%10; //MainLog.Instance.SetStatus(m_workIndicator.ToString()); + return 0f; } public override void GetResults() diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 5234cd3b04..a765878829 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -787,9 +787,10 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public override void Simulate(float timeStep) + public override float Simulate(float timeStep) { - + float fps = 0; + step_time += timeStep; @@ -800,32 +801,40 @@ namespace OpenSim.Region.Physics.OdePlugin - if (step_time >= m_SkipFramesAtms) - { - // Instead of trying to catch up, it'll do one physics frame only - step_time = ODE_STEPSIZE; - this.m_physicsiterations = 5; + if (step_time >= m_SkipFramesAtms) + { + // Instead of trying to catch up, it'll do one physics frame only + step_time = ODE_STEPSIZE; + this.m_physicsiterations = 5; + } + else + { + m_physicsiterations = 10; + } + lock (OdeLock) + { + // Process 10 frames if the sim is running normal.. + // process 5 frames if the sim is running slow + try{ + d.WorldSetQuickStepNumIterations(world, m_physicsiterations); } - else + catch (System.StackOverflowException) { - m_physicsiterations = 10; + MainLog.Instance.Error("PHYSICS", "The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim."); + base.TriggerPhysicsBasedRestart(); } - lock (OdeLock) - { - // Process 10 frames if the sim is running normal.. - // process 5 frames if the sim is running slow - try{ - d.WorldSetQuickStepNumIterations(world, m_physicsiterations); - } - catch (System.StackOverflowException) - { - MainLog.Instance.Error("PHYSICS", "The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim."); - base.TriggerPhysicsBasedRestart(); - } int i = 0; + + + // Figure out the Frames Per Second we're going at. + + fps = (((step_time / ODE_STEPSIZE * m_physicsiterations)*2)* 10); + + while (step_time > 0.0f) { + foreach (OdeCharacter actor in _characters) { actor.Move(timeStep); @@ -875,6 +884,7 @@ namespace OpenSim.Region.Physics.OdePlugin } } } + return fps; } public override void GetResults() diff --git a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs index 4355c5ef0b..efc30fec2c 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs @@ -169,10 +169,12 @@ namespace OpenSim.Region.Physics.POSPlugin } - public override void Simulate(float timeStep) + public override float Simulate(float timeStep) { + float fps = 0; for (int i = 0; i < _characters.Count; ++i) { + fps++; POSCharacter character = _characters[i]; float oldposX = character.Position.X; @@ -286,6 +288,7 @@ namespace OpenSim.Region.Physics.POSPlugin character._velocity.Z = (character.Position.Z - oldposZ) / timeStep; } } + return fps; } public override void GetResults() diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs index 5d22eeb77f..bc28626643 100644 --- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs +++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs @@ -139,8 +139,9 @@ namespace OpenSim.Region.Physics.PhysXPlugin { } - public override void Simulate(float timeStep) + public override float Simulate(float timeStep) { + float fps = 0f; try { foreach (PhysXCharacter actor in _characters) @@ -160,6 +161,7 @@ namespace OpenSim.Region.Physics.PhysXPlugin { Console.WriteLine(e.Message); } + return fps; } public override void GetResults()