* 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.
afrisby
Teravus Ovares 2007-12-12 06:58:55 +00:00
parent 83f727bb7c
commit 081f4403ea
10 changed files with 335 additions and 34 deletions

View File

@ -57,6 +57,9 @@ namespace OpenSim.Region.Environment.Scenes
protected RegionInfo m_regInfo; protected RegionInfo m_regInfo;
protected Scene m_parentScene; protected Scene m_parentScene;
protected PermissionManager PermissionsMngr; protected PermissionManager PermissionsMngr;
protected int m_numRootAgents = 0;
protected int m_numPrim = 0;
protected int m_numChildAgents = 0;
internal object m_syncRoot = new object(); 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) lock (m_syncRoot)
{ {
_PhyScene.Simulate((float)elapsed); return _PhyScene.Simulate((float)elapsed);
} }
} }
@ -171,6 +174,7 @@ namespace OpenSim.Region.Environment.Scenes
{ {
// QuadTree.AddObject(sceneObject); // QuadTree.AddObject(sceneObject);
Entities.Add(sceneObject.UUID, sceneObject); Entities.Add(sceneObject.UUID, sceneObject);
m_numPrim++;
} }
} }
@ -183,6 +187,7 @@ namespace OpenSim.Region.Environment.Scenes
if (((SceneObjectGroup)obj).LocalId == localID) if (((SceneObjectGroup)obj).LocalId == localID)
{ {
m_parentScene.RemoveEntity((SceneObjectGroup)obj); m_parentScene.RemoveEntity((SceneObjectGroup)obj);
m_numPrim--;
return; return;
} }
} }
@ -198,10 +203,12 @@ namespace OpenSim.Region.Environment.Scenes
if (child) if (child)
{ {
m_numChildAgents++;
MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Creating new child agent."); MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Creating new child agent.");
} }
else else
{ {
m_numRootAgents++;
MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Creating new root agent."); MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Creating new root agent.");
MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Adding Physical agent."); MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Adding Physical agent.");
@ -233,6 +240,47 @@ namespace OpenSim.Region.Environment.Scenes
return newAvatar; 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 #endregion
#region Get Methods #region Get Methods

View File

@ -59,6 +59,8 @@ namespace OpenSim.Region.Environment.Scenes
protected Timer m_heartbeatTimer = new Timer(); protected Timer m_heartbeatTimer = new Timer();
protected Timer m_restartWaitTimer = new Timer(); protected Timer m_restartWaitTimer = new Timer();
protected SimStatsReporter m_statsReporter;
protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
@ -256,6 +258,9 @@ namespace OpenSim.Region.Environment.Scenes
httpListener = httpServer; httpListener = httpServer;
m_dumpAssetsToFile = dumpAssetsToFile; m_dumpAssetsToFile = dumpAssetsToFile;
m_statsReporter = new SimStatsReporter(regInfo);
m_statsReporter.OnSendStatsResult += SendSimStatsPackets;
} }
#endregion #endregion
@ -531,7 +536,7 @@ namespace OpenSim.Region.Environment.Scenes
TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate; TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate;
// Aquire a lock so only one update call happens at once // Aquire a lock so only one update call happens at once
updateLock.WaitOne(); updateLock.WaitOne();
float physicsFPS = 0;
try try
{ {
// Increment the frame counter // Increment the frame counter
@ -548,7 +553,7 @@ namespace OpenSim.Region.Environment.Scenes
m_innerScene.UpdateEntityMovement(); m_innerScene.UpdateEntityMovement();
if (m_frame % m_update_physics == 0) if (m_frame % m_update_physics == 0)
m_innerScene.UpdatePhysics( physicsFPS = m_innerScene.UpdatePhysics(
Math.Max(SinceLastFrame.TotalSeconds, m_timespan) Math.Max(SinceLastFrame.TotalSeconds, m_timespan)
); );
@ -569,6 +574,14 @@ namespace OpenSim.Region.Environment.Scenes
// if (m_frame%m_update_avatars == 0) // if (m_frame%m_update_avatars == 0)
// UpdateInWorldTime(); // 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) catch (NotImplementedException)
{ {
@ -607,6 +620,19 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
private void SendSimStatsPackets(libsecondlife.Packets.SimStatsPacket pack)
{
List<ScenePresence> StatSendAgents = GetScenePresences();
foreach (ScenePresence agent in StatSendAgents)
{
if (!agent.IsChildAgent)
{
agent.ControllingClient.OutPacket(pack, ThrottleOutPacketType.Task);
}
}
}
private void UpdateLand() private void UpdateLand()
{ {
if (m_LandManager.landPrimCountTainted) if (m_LandManager.landPrimCountTainted)
@ -939,6 +965,7 @@ namespace OpenSim.Region.Environment.Scenes
// subscribe to physics events. // subscribe to physics events.
rootPart.DoPhysicsPropertyUpdate(UsePhysics, true); rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
} }
m_innerScene.AddAPrimCount();
} }
} }
@ -967,6 +994,7 @@ namespace OpenSim.Region.Environment.Scenes
public void AddEntity(SceneObjectGroup sceneObject) public void AddEntity(SceneObjectGroup sceneObject)
{ {
m_innerScene.AddEntity(sceneObject); m_innerScene.AddEntity(sceneObject);
} }
public void RemoveEntity(SceneObjectGroup sceneObject) public void RemoveEntity(SceneObjectGroup sceneObject)
@ -976,6 +1004,7 @@ namespace OpenSim.Region.Environment.Scenes
m_LandManager.removePrimFromLandPrimCounts(sceneObject); m_LandManager.removePrimFromLandPrimCounts(sceneObject);
Entities.Remove(sceneObject.UUID); Entities.Remove(sceneObject.UUID);
m_LandManager.setPrimsTainted(); m_LandManager.setPrimsTainted();
m_innerScene.RemoveAPrimCount();
} }
} }
@ -1135,7 +1164,16 @@ namespace OpenSim.Region.Environment.Scenes
m_eventManager.TriggerOnRemovePresence(agentID); m_eventManager.TriggerOnRemovePresence(agentID);
ScenePresence avatar = GetScenePresence(agentID); ScenePresence avatar = GetScenePresence(agentID);
if (avatar.IsChildAgent)
{
m_innerScene.removeUserCount(false);
}
else
{
m_innerScene.removeUserCount(true);
}
Broadcast(delegate(IClientAPI client) Broadcast(delegate(IClientAPI client)
{ {
try try
@ -1196,6 +1234,7 @@ namespace OpenSim.Region.Environment.Scenes
{ {
Entities.Remove(entID); Entities.Remove(entID);
m_storageManager.DataStore.RemoveObject(entID, m_regInfo.RegionID); m_storageManager.DataStore.RemoveObject(entID, m_regInfo.RegionID);
m_innerScene.RemoveAPrimCount();
return true; return true;
} }
return false; return false;
@ -1287,6 +1326,7 @@ namespace OpenSim.Region.Environment.Scenes
if (m_scenePresences.ContainsKey(agentID)) if (m_scenePresences.ContainsKey(agentID))
{ {
m_scenePresences[agentID].MakeRootAgent(position, isFlying); 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); ScenePresence presence = m_innerScene.GetScenePresence(agentID);
if (presence != null) if (presence != null)
{ {
if (presence.IsChildAgent)
{
m_innerScene.removeUserCount(false);
}
else
{
m_innerScene.removeUserCount(true);
}
// Tell a single agent to disconnect from the region. // Tell a single agent to disconnect from the region.
libsecondlife.Packets.DisableSimulatorPacket disable = new libsecondlife.Packets.DisableSimulatorPacket(); libsecondlife.Packets.DisableSimulatorPacket disable = new libsecondlife.Packets.DisableSimulatorPacket();
presence.ControllingClient.OutPacket(disable, ThrottleOutPacketType.Task); 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? if (controller.AgentId != godID && !childagent) // Do we really want to kick the initiator of this madness?
{ {
controller.Kick(Helpers.FieldToUTF8String(reason)); 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 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.Kick(Helpers.FieldToUTF8String(reason));
m_scenePresences[agentID].ControllingClient.Close(); m_scenePresences[agentID].ControllingClient.Close();
} }
@ -1848,7 +1915,10 @@ namespace OpenSim.Region.Environment.Scenes
{ {
return m_innerScene.ConvertLocalIDToFullID(localID); return m_innerScene.ConvertLocalIDToFullID(localID);
} }
public void SwapRootAgentCount(bool rootChildChildRootTF)
{
m_innerScene.SwapRootChildAgent(rootChildChildRootTF);
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

View File

@ -465,6 +465,7 @@ namespace OpenSim.Region.Environment.Scenes
AddToPhysicalScene(); AddToPhysicalScene();
m_physicsActor.Flying = isFlying; m_physicsActor.Flying = isFlying;
m_scene.SwapRootAgentCount(false);
m_scene.CommsManager.UserProfileCacheService.UpdateUserInventory(m_uuid); m_scene.CommsManager.UserProfileCacheService.UpdateUserInventory(m_uuid);
//if (!m_gotAllObjectsInScene) //if (!m_gotAllObjectsInScene)
//{ //{
@ -484,7 +485,7 @@ namespace OpenSim.Region.Environment.Scenes
{ {
Velocity = new LLVector3(0, 0, 0); Velocity = new LLVector3(0, 0, 0);
m_isChildAgent = true; m_isChildAgent = true;
m_scene.SwapRootAgentCount(true);
RemoveFromPhysicalScene(); RemoveFromPhysicalScene();
//this.Pos = new LLVector3(128, 128, 70); //this.Pos = new LLVector3(128, 128, 70);

View File

@ -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;
}
}
}

View File

@ -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) for (int i = 0; i < _actors.Count; ++i)
{ {
BasicActor actor = _actors[i]; BasicActor actor = _actors[i];
@ -164,6 +165,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
actor.Velocity.Z = 0; actor.Velocity.Z = 0;
} }
} }
return fps;
} }
public override void GetResults() public override void GetResults()

View File

@ -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) lock (BulletXLock)
{ {
//Try to remove garbage //Try to remove garbage
RemoveForgottenRigidBodies(); RemoveForgottenRigidBodies();
//End of remove //End of remove
MoveAllObjects(timeStep); MoveAllObjects(timeStep);
fps = (timeStep * simulationSubSteps);
ddWorld.StepSimulation(timeStep, simulationSubSteps, timeStep); ddWorld.StepSimulation(timeStep, simulationSubSteps, timeStep);
//Extra Heightmap Validation: BulletX's HeightFieldTerrain somestimes doesn't work so fine. //Extra Heightmap Validation: BulletX's HeightFieldTerrain somestimes doesn't work so fine.
ValidateHeightForAll(); ValidateHeightForAll();
//End heightmap validation. //End heightmap validation.
UpdateKineticsForAll(); UpdateKineticsForAll();
} }
return fps;
} }
private void MoveAllObjects(float timeStep) private void MoveAllObjects(float timeStep)

View File

@ -70,7 +70,7 @@ namespace OpenSim.Region.Physics.Manager
PhysicsVector size, Quaternion rotation, bool isPhysical); PhysicsVector size, Quaternion rotation, bool isPhysical);
public abstract void AddPhysicsActorTaint(PhysicsActor prim); public abstract void AddPhysicsActorTaint(PhysicsActor prim);
public abstract void Simulate(float timeStep); public abstract float Simulate(float timeStep);
public abstract void GetResults(); 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; m_workIndicator = (m_workIndicator + 1)%10;
//MainLog.Instance.SetStatus(m_workIndicator.ToString()); //MainLog.Instance.SetStatus(m_workIndicator.ToString());
return 0f;
} }
public override void GetResults() public override void GetResults()

View File

@ -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; step_time += timeStep;
@ -800,32 +801,40 @@ namespace OpenSim.Region.Physics.OdePlugin
if (step_time >= m_SkipFramesAtms) if (step_time >= m_SkipFramesAtms)
{ {
// Instead of trying to catch up, it'll do one physics frame only // Instead of trying to catch up, it'll do one physics frame only
step_time = ODE_STEPSIZE; step_time = ODE_STEPSIZE;
this.m_physicsiterations = 5; 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; 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) while (step_time > 0.0f)
{ {
foreach (OdeCharacter actor in _characters) foreach (OdeCharacter actor in _characters)
{ {
actor.Move(timeStep); actor.Move(timeStep);
@ -875,6 +884,7 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
} }
return fps;
} }
public override void GetResults() public override void GetResults()

View File

@ -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) for (int i = 0; i < _characters.Count; ++i)
{ {
fps++;
POSCharacter character = _characters[i]; POSCharacter character = _characters[i];
float oldposX = character.Position.X; float oldposX = character.Position.X;
@ -286,6 +288,7 @@ namespace OpenSim.Region.Physics.POSPlugin
character._velocity.Z = (character.Position.Z - oldposZ) / timeStep; character._velocity.Z = (character.Position.Z - oldposZ) / timeStep;
} }
} }
return fps;
} }
public override void GetResults() public override void GetResults()

View File

@ -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 try
{ {
foreach (PhysXCharacter actor in _characters) foreach (PhysXCharacter actor in _characters)
@ -160,6 +161,7 @@ namespace OpenSim.Region.Physics.PhysXPlugin
{ {
Console.WriteLine(e.Message); Console.WriteLine(e.Message);
} }
return fps;
} }
public override void GetResults() public override void GetResults()