private bool Update() { IMonitorModule monitorModule = RequestModuleInterface <IMonitorModule>(); ISimFrameMonitor simFrameMonitor = monitorModule.GetMonitor <ISimFrameMonitor>(this); ITotalFrameTimeMonitor totalFrameMonitor = monitorModule.GetMonitor <ITotalFrameTimeMonitor>(this); ILastFrameTimeMonitor lastFrameMonitor = monitorModule.GetMonitor <ILastFrameTimeMonitor>(this); IOtherFrameMonitor otherFrameMonitor = monitorModule.GetMonitor <IOtherFrameMonitor>(this); ISleepFrameMonitor sleepFrameMonitor = monitorModule.GetMonitor <ISleepFrameMonitor>(this); while (true) { if (!ShouldRunHeartbeat) //If we arn't supposed to be running, kill ourselves { return(false); } int maintc = Util.EnvironmentTickCount(); int BeginningFrameTime = maintc; // Increment the frame counter ++m_frame; try { int OtherFrameTime = Util.EnvironmentTickCount(); if (m_frame % m_update_coarse_locations == 0) { List <Vector3> coarseLocations; List <UUID> avatarUUIDs; if (SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60)) { // Send coarse locations to clients foreach (IScenePresence presence in GetScenePresences()) { presence.SendCoarseLocations(coarseLocations, avatarUUIDs); } } } if (m_frame % m_update_entities == 0) { m_sceneGraph.UpdateEntities(); } Action[] events; lock (m_events) { events = new Action[m_events.Count]; m_events.CopyTo(events); m_events.Clear(); } foreach (Action h in events) { try { h(); } catch { } } if (m_frame % m_update_events == 0) { m_sceneGraph.PhysicsScene.UpdatesLoop(); } if (m_frame % m_update_events == 0) { m_eventManager.TriggerOnFrame(); } //Now fix the sim stats int MonitorOtherFrameTime = Util.EnvironmentTickCountSubtract(OtherFrameTime); int MonitorLastCompletedFrame = Util.EnvironmentTickCount(); simFrameMonitor.AddFPS(1); lastFrameMonitor.SetValue(MonitorLastCompletedFrame); otherFrameMonitor.AddTime(MonitorOtherFrameTime); } catch (Exception e) { MainConsole.Instance.Error("[REGION]: Failed with exception " + e + " in region: " + RegionInfo.RegionName); return(true); } //Get the time between beginning and end maintc = Util.EnvironmentTickCountSubtract(BeginningFrameTime); //Beginning + (time between beginning and end) = end int MonitorEndFrameTime = BeginningFrameTime + maintc; int getSleepTime = GetHeartbeatSleepTime(maintc, false); if (getSleepTime > 0) { Thread.Sleep(getSleepTime); } if (sleepFrameMonitor != null) { sleepFrameMonitor.AddTime(maintc); totalFrameMonitor.AddFrameTime(MonitorEndFrameTime); } } }
void Heartbeat() { IMonitorModule monitorModule = RequestModuleInterface <IMonitorModule>(); ISimFrameMonitor simFrameMonitor = monitorModule.GetMonitor <ISimFrameMonitor>(this); ITotalFrameTimeMonitor totalFrameMonitor = monitorModule.GetMonitor <ITotalFrameTimeMonitor>(this); ILastFrameTimeMonitor lastFrameMonitor = monitorModule.GetMonitor <ILastFrameTimeMonitor>(this); IOtherFrameMonitor otherFrameMonitor = monitorModule.GetMonitor <IOtherFrameMonitor>(this); ISleepFrameMonitor sleepFrameMonitor = monitorModule.GetMonitor <ISleepFrameMonitor>(this); IPhysicsFrameMonitor physicsFrameMonitor = monitorModule.GetMonitor <IPhysicsFrameMonitor>(this); IPhysicsUpdateFrameMonitor physicsFrameTimeMonitor = monitorModule.GetMonitor <IPhysicsUpdateFrameMonitor>(this); IPhysicsMonitor physicsMonitor = RequestModuleInterface <IPhysicsMonitor>(); ILLClientInventory inventoryModule = RequestModuleInterface <ILLClientInventory>(); while (true) { if (!ShouldRunHeartbeat) //If we aren't supposed to be running, kill ourselves { return; } int maintc = Util.EnvironmentTickCount(); int BeginningFrameTime = maintc; // Increment the frame counter ++Frame; try { int OtherFrameTime = Util.EnvironmentTickCount(); ISceneEntity[] entities = null; lock (PhysicsReturns) { if (PhysicsReturns.Count != 0) { entities = PhysicsReturns.ToArray(); PhysicsReturns.Clear(); } } if (entities != null && inventoryModule != null) { inventoryModule.ReturnObjects(entities, UUID.Zero); } if (Frame % m_update_entities == 0) { m_sceneGraph.UpdateEntities(); } if (Frame % m_update_events == 0) { m_sceneGraph.PhysicsScene.UpdatesLoop(); } if (Frame % m_update_events == 0) { m_eventManager.TriggerOnFrame(); } if (Frame % m_update_coarse_locations == 0) { List <Vector3> coarseLocations; List <UUID> avatarUUIDs; if (SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60)) { // Send coarse locations to clients foreach (IScenePresence presence in GetScenePresences()) { presence.SendCoarseLocations(coarseLocations, avatarUUIDs); } } } int PhysicsUpdateTime = Util.EnvironmentTickCount(); if (Frame % m_update_physics == 0) { TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastphysupdate; if (!RegionInfo.RegionSettings.DisablePhysics && ApproxEquals((float)SinceLastFrame.TotalMilliseconds, m_updatetimespan, 3)) { m_sceneGraph.UpdatePreparePhysics(); m_sceneGraph.UpdatePhysics((float)SinceLastFrame.TotalSeconds); m_lastphysupdate = DateTime.UtcNow; int MonitorPhysicsUpdateTime = Util.EnvironmentTickCountSubtract(PhysicsUpdateTime); if (MonitorPhysicsUpdateTime != 0) { if (physicsFrameTimeMonitor != null) { physicsFrameTimeMonitor.AddTime(MonitorPhysicsUpdateTime); } if (physicsMonitor != null) { physicsMonitor.AddPhysicsStats(RegionInfo.RegionID, PhysicsScene); } if (m_lastPhysicsChange != RegionInfo.RegionSettings.DisablePhysics) { StartPhysicsScene(); } } if (physicsFrameMonitor != null) { physicsFrameMonitor.AddFPS(1); } } else if (m_lastPhysicsChange != RegionInfo.RegionSettings.DisablePhysics) { StopPhysicsScene(); } m_lastPhysicsChange = RegionInfo.RegionSettings.DisablePhysics; } //Now fix the sim stats int MonitorOtherFrameTime = Util.EnvironmentTickCountSubtract(OtherFrameTime); int MonitorLastCompletedFrame = Util.EnvironmentTickCount(); simFrameMonitor.AddFPS(1); lastFrameMonitor.SetValue(MonitorLastCompletedFrame); otherFrameMonitor.AddTime(MonitorOtherFrameTime); } catch (Exception e) { MainConsole.Instance.Error("[Scene]: Failed with exception " + e + " in region: " + RegionInfo.RegionName); return; } //Get the time between beginning and end maintc = Util.EnvironmentTickCountSubtract(BeginningFrameTime); //Beginning + (time between beginning and end) = end int MonitorEndFrameTime = BeginningFrameTime + maintc; int getSleepTime = GetHeartbeatSleepTime(maintc); if (getSleepTime > 0) { Thread.Sleep(getSleepTime); } if (sleepFrameMonitor != null) { sleepFrameMonitor.AddTime(getSleepTime); totalFrameMonitor.AddFrameTime(MonitorEndFrameTime); } } }
/// <summary> /// This is called by a timer and makes a SimStats class of the current stats that we have in this simulator. /// It then sends the packet to the client and triggers the events to tell followers about the updated stats /// and updates the LastSet* values for monitors. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void statsHeartBeat(object sender, EventArgs e) { if (m_currentScene.PhysicsScene == null) { return; } m_report.Stop(); if (rb == null) { buildInitialRegionBlock(); } // Know what's not thread safe in Mono... modifying timers. lock (m_report) { ISimFrameMonitor simFrameMonitor = GetMonitor <ISimFrameMonitor>(); ITimeDilationMonitor timeDilationMonitor = GetMonitor <ITimeDilationMonitor>(); ITotalFrameTimeMonitor totalFrameMonitor = GetMonitor <ITotalFrameTimeMonitor>(); ISleepFrameMonitor sleepFrameMonitor = GetMonitor <ISleepFrameMonitor>(); IOtherFrameMonitor otherFrameMonitor = GetMonitor <IOtherFrameMonitor>(); IPhysicsFrameMonitor physicsFrameMonitor = GetMonitor <IPhysicsFrameMonitor>(); IPhysicsSyncFrameMonitor physicsSyncFrameMonitor = GetMonitor <IPhysicsSyncFrameMonitor>(); IPhysicsUpdateFrameMonitor physicsTimeFrameMonitor = GetMonitor <IPhysicsUpdateFrameMonitor>(); IAgentUpdateMonitor agentUpdateFrameMonitor = GetMonitor <IAgentUpdateMonitor>(); INetworkMonitor networkMonitor = GetMonitor <INetworkMonitor>(); IImageFrameTimeMonitor imagesMonitor = GetMonitor <IImageFrameTimeMonitor>(); IScriptFrameTimeMonitor scriptMonitor = GetMonitor <IScriptFrameTimeMonitor>(); IScriptCountMonitor totalScriptMonitor = GetMonitor <IScriptCountMonitor>(); #region various statistic googly moogly float simfps = simFrameMonitor.SimFPS / statsUpdateFactor; // save the reported value so there is something available for llGetRegionFPS simFrameMonitor.LastReportedSimFPS = simfps; float physfps = physicsFrameMonitor.PhysicsFPS / statsUpdateFactor; physicsFrameMonitor.LastReportedPhysicsFPS = physfps; //Update the time dilation with the newest physicsFPS timeDilationMonitor.SetPhysicsFPS(physfps); #endregion #region Add the stats packets //Some info on this packet http://wiki.secondlife.com/wiki/Statistics_Bar_Guide sb[0].StatID = (uint)Stats.TimeDilation; sb[0].StatValue = (float)timeDilationMonitor.GetValue(); sb[1].StatID = (uint)Stats.FPS; sb[1].StatValue = simfps; float realsimfps = simfps * 2; sb[2].StatID = (uint)Stats.PhysFPS; sb[2].StatValue = physfps; sb[3].StatID = (uint)Stats.AgentUpdates; sb[3].StatValue = (agentUpdateFrameMonitor.AgentUpdates / realsimfps); sb[4].StatID = (uint)Stats.FrameMS; float TotalFrames = (float)(totalFrameMonitor.GetValue() / realsimfps); sb[4].StatValue = TotalFrames; sb[5].StatID = (uint)Stats.NetMS; sb[5].StatValue = 0; //TODO: Implement this sb[6].StatID = (uint)Stats.SimOtherMS; float otherMS = (float)(otherFrameMonitor.GetValue() / realsimfps); sb[6].StatValue = otherMS; sb[7].StatID = (uint)Stats.SimPhysicsMS; float PhysicsMS = (float)(physicsTimeFrameMonitor.GetValue() / realsimfps); sb[7].StatValue = PhysicsMS; sb[8].StatID = (uint)Stats.AgentMS; sb[8].StatValue = (agentUpdateFrameMonitor.AgentFrameTime / realsimfps); sb[9].StatID = (uint)Stats.ImagesMS; float imageMS = (float)(imagesMonitor.GetValue() / realsimfps); sb[9].StatValue = imageMS; sb[10].StatID = (uint)Stats.ScriptMS; float ScriptMS = (float)(scriptMonitor.GetValue() / realsimfps); sb[10].StatValue = ScriptMS; sb[11].StatID = (uint)Stats.TotalObjects; sb[12].StatID = (uint)Stats.ActiveObjects; sb[13].StatID = (uint)Stats.NumAgentMain; sb[14].StatID = (uint)Stats.NumAgentChild; IEntityCountModule entityCountModule = m_currentScene.RequestModuleInterface <IEntityCountModule>(); if (entityCountModule != null) { sb[11].StatValue = entityCountModule.Objects; sb[12].StatValue = entityCountModule.ActiveObjects; sb[13].StatValue = entityCountModule.RootAgents; sb[14].StatValue = entityCountModule.ChildAgents; } sb[15].StatID = (uint)Stats.NumScriptActive; sb[15].StatValue = totalScriptMonitor.ActiveScripts; sb[16].StatID = (uint)Stats.LSLIPS; sb[16].StatValue = 0; //This isn't used anymore, and has been superseeded by LSLEPS sb[17].StatID = (uint)Stats.InPPS; sb[17].StatValue = (networkMonitor.InPacketsPerSecond / statsUpdateFactor); sb[18].StatID = (uint)Stats.OutPPS; sb[18].StatValue = (networkMonitor.OutPacketsPerSecond / statsUpdateFactor); sb[19].StatID = (uint)Stats.PendingDownloads; sb[19].StatValue = (networkMonitor.PendingDownloads); sb[20].StatID = (uint)Stats.PendingUploads; sb[20].StatValue = (networkMonitor.PendingUploads); //21 and 22 are forced to the GC memory as they WILL make memory usage go up rapidly otherwise! sb[21].StatID = (uint)Stats.VirtualSizeKB; sb[21].StatValue = GC.GetTotalMemory(false) / 1024; // System.Diagnostics.Process.GetCurrentProcess().WorkingSet64 / (1024); sb[22].StatID = (uint)Stats.ResidentSizeKB; sb[22].StatValue = GC.GetTotalMemory(false) / 1024; //(float)System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64 / (1024); sb[23].StatID = (uint)Stats.PendingLocalUploads; sb[23].StatValue = (networkMonitor.PendingUploads / statsUpdateFactor); sb[24].StatID = (uint)Stats.TotalUnackedBytes; sb[24].StatValue = (networkMonitor.UnackedBytes); sb[25].StatID = (uint)Stats.PhysicsPinnedTasks; sb[25].StatValue = 0; sb[26].StatID = (uint)Stats.PhysicsLODTasks; sb[26].StatValue = 0; sb[27].StatID = (uint)Stats.SimPhysicsStepMS; sb[27].StatValue = m_currentScene.PhysicsScene.StepTime; sb[28].StatID = (uint)Stats.SimPhysicsShape; sb[28].StatValue = 0; sb[29].StatID = (uint)Stats.SimPhysicsOtherMS; sb[29].StatValue = (float)(physicsSyncFrameMonitor.GetValue() / realsimfps); sb[30].StatID = (uint)Stats.SimPhysicsMemory; sb[30].StatValue = 0; sb[31].StatID = (uint)Stats.ScriptEPS; sb[31].StatValue = totalScriptMonitor.ScriptEPS / statsUpdateFactor; sb[32].StatID = (uint)Stats.SimSpareTime; //Spare time is the total time minus the stats that are in the same category in the client // It is the sleep time, physics step, update physics shape, physics other, and pumpI0. // Note: take out agent Update and script time for now, as they are not a part of the heartbeat right now and will mess this calc up float SpareTime = TotalFrames - ( /*NetMS + */ PhysicsMS + otherMS + imageMS); // + /*(agentUpdateFrameMonitor.AgentFrameTime / statsUpdateFactor) +*/ // (imagesMonitor.GetValue() / statsUpdateFactor) /* + ScriptMS*/)); sb[32].StatValue = SpareTime; sb[33].StatID = (uint)Stats.SimSleepTime; sb[33].StatValue = (float)(sleepFrameMonitor.GetValue() / realsimfps); sb[34].StatID = (uint)Stats.IOPumpTime; sb[34].StatValue = 0; //TODO: implement this #endregion for (int i = 0; i < sb.Length; i++) { if (float.IsInfinity(sb[i].StatValue) || float.IsNaN(sb[i].StatValue)) { sb[i].StatValue = 0; //Don't send huge values } lastReportedSimStats[i] = sb[i].StatValue; } SimStats simStats = new SimStats(rb, sb, m_currentScene.RegionInfo.RegionID); //Fire the event and tell followers about the new stats m_module.SendStatsResults(simStats); //Tell all the scene presences about the new stats foreach (IScenePresence agent in m_currentScene.GetScenePresences().Where(agent => !agent.IsChildAgent)) { agent.ControllingClient.SendSimStats(simStats); } //Now fix any values that require reseting ResetValues(); } m_report.Start(); }
private bool PhysUpdate() { IMonitorModule monitorModule = RequestModuleInterface <IMonitorModule>(); ISimFrameMonitor simFrameMonitor = monitorModule.GetMonitor <ISimFrameMonitor>(); ITotalFrameTimeMonitor totalFrameMonitor = monitorModule.GetMonitor <ITotalFrameTimeMonitor>(); ILastFrameTimeMonitor lastFrameMonitor = monitorModule.GetMonitor <ILastFrameTimeMonitor>(); IOtherFrameMonitor otherFrameMonitor = monitorModule.GetMonitor <IOtherFrameMonitor>(); ISleepFrameMonitor sleepFrameMonitor = monitorModule.GetMonitor <ISleepFrameMonitor>(); IPhysicsFrameMonitor physicsFrameMonitor = monitorModule.GetMonitor <IPhysicsFrameMonitor>(); IPhysicsUpdateFrameMonitor physicsFrameTimeMonitor = monitorModule.GetMonitor <IPhysicsUpdateFrameMonitor>(); IPhysicsMonitor monitor2 = RequestModuleInterface <IPhysicsMonitor>(); ILLClientInventory inventoryModule = RequestModuleInterface <ILLClientInventory>(); while (true) { if (!ShouldRunHeartbeat) //If we arn't supposed to be running, kill ourselves { return(false); } int maintc = Util.EnvironmentTickCount(); int BeginningFrameTime = maintc; ISceneEntity[] entities = null; lock (PhysicsReturns) { if (PhysicsReturns.Count != 0) { entities = PhysicsReturns.ToArray(); PhysicsReturns.Clear(); } } if (entities != null && inventoryModule != null) { inventoryModule.ReturnObjects(entities, UUID.Zero); } int PhysicsUpdateTime = Util.EnvironmentTickCount(); if (m_frame % m_update_physics == 0) { TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastphysupdate; if (!RegionInfo.RegionSettings.DisablePhysics && ApproxEquals((float)SinceLastFrame.TotalMilliseconds, m_updatetimespan, 3)) { m_sceneGraph.UpdatePreparePhysics(); m_sceneGraph.UpdatePhysics((float)SinceLastFrame.TotalSeconds); m_lastphysupdate = DateTime.UtcNow; int MonitorPhysicsUpdateTime = Util.EnvironmentTickCountSubtract(PhysicsUpdateTime); if (MonitorPhysicsUpdateTime != 0) { if (physicsFrameTimeMonitor != null) { physicsFrameTimeMonitor.AddTime(MonitorPhysicsUpdateTime); } if (monitor2 != null) { monitor2.AddPhysicsStats(RegionInfo.RegionID, PhysicsScene); } if (m_lastPhysicsChange != RegionInfo.RegionSettings.DisablePhysics) { StartPhysicsScene(); } } if (physicsFrameMonitor != null) { physicsFrameMonitor.AddFPS(1); } } else if (m_lastPhysicsChange != RegionInfo.RegionSettings.DisablePhysics) { StopPhysicsScene(); } m_lastPhysicsChange = RegionInfo.RegionSettings.DisablePhysics; } //Get the time between beginning and end maintc = Util.EnvironmentTickCountSubtract(BeginningFrameTime); if (maintc == 0) { continue; } int getSleepTime = GetHeartbeatSleepTime(maintc, true); if (getSleepTime > 0) { Thread.Sleep(getSleepTime); } } }