From abc6424c51324fecd393057b3c95b1f93c74d573 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Sat, 11 Oct 2008 11:43:42 +0000 Subject: * Removed Heartbeat timer * Implemented a proper update thread * Removed the UpdateLock Mutex as it's no longer needed because updates can only happen one at a time now. * This should actually improve performance significantly.. But, see the warning on the next line! * Warning: If there are deadlocks that the threadpool timer method was hiding, this will expose them for all the nastiness they are. --- OpenSim/Region/Environment/Scenes/Scene.cs | 275 ++++++++++++++++------------- 1 file changed, 148 insertions(+), 127 deletions(-) (limited to 'OpenSim/Region/Environment') diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 8bd3642..965ccdf 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -60,10 +60,11 @@ namespace OpenSim.Region.Environment.Scenes public delegate void SynchronizeSceneHandler(Scene scene); public SynchronizeSceneHandler SynchronizeScene = null; public int splitID = 0; + #region Fields - protected Timer m_heartbeatTimer = new Timer(); + protected Timer m_restartWaitTimer = new Timer(); protected SimStatsReporter m_statsReporter; @@ -83,7 +84,7 @@ namespace OpenSim.Region.Environment.Scenes private int m_timePhase = 24; - private readonly Mutex updateLock; + /// /// Are we applying physics to any of the prims in this scene? @@ -169,6 +170,8 @@ namespace OpenSim.Region.Environment.Scenes private bool m_scripts_enabled = true; private string m_defaultScriptEngine; private int m_LastLogin = 0; + private Thread HeartbeatThread; + private volatile bool shuttingdown = false; #endregion @@ -259,7 +262,7 @@ namespace OpenSim.Region.Environment.Scenes bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion) { m_config = config; - updateLock = new Mutex(false); + m_moduleLoader = moduleLoader; m_authenticateHandler = authen; CommsManager = commsMan; @@ -631,7 +634,8 @@ namespace OpenSim.Region.Environment.Scenes // Stop all client threads. ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(true); }); // Stop updating the scene objects and agents. - m_heartbeatTimer.Close(); + //m_heartbeatTimer.Close(); + shuttingdown = true; // close the inner scene m_innerScene.Close(); // De-register with region communications (events cleanup) @@ -656,10 +660,16 @@ namespace OpenSim.Region.Environment.Scenes /// public void StartTimer() { - m_log.Debug("[SCENE]: Starting timer"); - m_heartbeatTimer.Enabled = true; - m_heartbeatTimer.Interval = (int)(m_timespan * 1000); - m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); + //m_log.Debug("[SCENE]: Starting timer"); + //m_heartbeatTimer.Enabled = true; + //m_heartbeatTimer.Interval = (int)(m_timespan * 1000); + //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); + HeartbeatThread = new Thread(new ParameterizedThreadStart(Heartbeat)); + HeartbeatThread.SetApartmentState(ApartmentState.MTA); + HeartbeatThread.Name = "Heartbeat"; + HeartbeatThread.Priority = ThreadPriority.AboveNormal; + ThreadTracker.Add(HeartbeatThread); + HeartbeatThread.Start(); } /// @@ -685,7 +695,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// /// - private void Heartbeat(object sender, EventArgs e) + private void Heartbeat(object sender) { Update(); } @@ -695,146 +705,157 @@ namespace OpenSim.Region.Environment.Scenes /// public override void Update() { - TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate; - // Aquire a lock so only one update call happens at once - updateLock.WaitOne(); - float physicsFPS = 0; - //m_log.Info("sadfadf" + m_neighbours.Count.ToString()); - int agentsInScene = m_innerScene.GetRootAgentCount() + m_innerScene.GetChildAgentCount(); - - if (agentsInScene > 21) + int maintc = 0; + while (!shuttingdown) { - if (m_update_entities == 1) + maintc = System.Environment.TickCount; + + TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate; + // Aquire a lock so only one update call happens at once + //updateLock.WaitOne(); + float physicsFPS = 0; + //m_log.Info("sadfadf" + m_neighbours.Count.ToString()); + int agentsInScene = m_innerScene.GetRootAgentCount() + m_innerScene.GetChildAgentCount(); + + if (agentsInScene > 21) { - m_update_entities = 5; - m_statsReporter.SetUpdateMS(6000); + if (m_update_entities == 1) + { + m_update_entities = 5; + m_statsReporter.SetUpdateMS(6000); + } } - } - else - { - if (m_update_entities == 5) + else { - m_update_entities = 1; - m_statsReporter.SetUpdateMS(3000); + if (m_update_entities == 5) + { + m_update_entities = 1; + m_statsReporter.SetUpdateMS(3000); + } } - } - frameMS = System.Environment.TickCount; - try - { - // Increment the frame counter - m_frame++; - - // Loop it - if (m_frame == Int32.MaxValue) - m_frame = 0; - - physicsMS2 = System.Environment.TickCount; - if ((m_frame % m_update_physics == 0) && m_physics_enabled) - m_innerScene.UpdatePreparePhysics(); - physicsMS2 = System.Environment.TickCount - physicsMS2; + frameMS = System.Environment.TickCount; + try + { + // Increment the frame counter + m_frame++; - if (m_frame % m_update_entitymovement == 0) - m_innerScene.UpdateEntityMovement(); + // Loop it + if (m_frame == Int32.MaxValue) + m_frame = 0; - physicsMS = System.Environment.TickCount; - if ((m_frame % m_update_physics == 0) && m_physics_enabled) - physicsFPS = m_innerScene.UpdatePhysics( - Math.Max(SinceLastFrame.TotalSeconds, m_timespan) - ); - if (m_frame % m_update_physics == 0 && SynchronizeScene != null) - SynchronizeScene(this); + physicsMS2 = System.Environment.TickCount; + if ((m_frame % m_update_physics == 0) && m_physics_enabled) + m_innerScene.UpdatePreparePhysics(); + physicsMS2 = System.Environment.TickCount - physicsMS2; - physicsMS = System.Environment.TickCount - physicsMS; - physicsMS += physicsMS2; + if (m_frame % m_update_entitymovement == 0) + m_innerScene.UpdateEntityMovement(); - otherMS = System.Environment.TickCount; - // run through all entities looking for updates (slow) - if (m_frame % m_update_entities == 0) - m_innerScene.UpdateEntities(); + physicsMS = System.Environment.TickCount; + if ((m_frame % m_update_physics == 0) && m_physics_enabled) + physicsFPS = m_innerScene.UpdatePhysics( + Math.Max(SinceLastFrame.TotalSeconds, m_timespan) + ); + if (m_frame % m_update_physics == 0 && SynchronizeScene != null) + SynchronizeScene(this); - // run through entities that have scheduled themselves for - // updates looking for updates(faster) - if (m_frame % m_update_entitiesquick == 0) - m_innerScene.ProcessUpdates(); + physicsMS = System.Environment.TickCount - physicsMS; + physicsMS += physicsMS2; - // Run through scenepresences looking for updates - if (m_frame % m_update_presences == 0) - m_innerScene.UpdatePresences(); + otherMS = System.Environment.TickCount; + // run through all entities looking for updates (slow) + if (m_frame % m_update_entities == 0) + m_innerScene.UpdateEntities(); - // Delete temp-on-rez stuff - if (m_frame % m_update_backup == 0) - CleanTempObjects(); + // run through entities that have scheduled themselves for + // updates looking for updates(faster) + if (m_frame % m_update_entitiesquick == 0) + m_innerScene.ProcessUpdates(); - if (Region_Status != RegionStatus.SlaveScene) - { - if (m_frame % m_update_events == 0) - UpdateEvents(); + // Run through scenepresences looking for updates + if (m_frame % m_update_presences == 0) + m_innerScene.UpdatePresences(); + // Delete temp-on-rez stuff if (m_frame % m_update_backup == 0) + CleanTempObjects(); + + if (Region_Status != RegionStatus.SlaveScene) { - UpdateStorageBackup(); - } + if (m_frame % m_update_events == 0) + UpdateEvents(); - if (m_frame % m_update_terrain == 0) - UpdateTerrain(); - - if (m_frame % m_update_land == 0) - UpdateLand(); - otherMS = System.Environment.TickCount - otherMS; - // if (m_frame%m_update_avatars == 0) - // UpdateInWorldTime(); - m_statsReporter.AddPhysicsFPS(physicsFPS); - m_statsReporter.AddTimeDilation(m_timedilation); - m_statsReporter.AddFPS(1); - m_statsReporter.AddInPackets(0); - m_statsReporter.SetRootAgents(m_innerScene.GetRootAgentCount()); - m_statsReporter.SetChildAgents(m_innerScene.GetChildAgentCount()); - m_statsReporter.SetObjects(m_innerScene.GetTotalObjectsCount()); - m_statsReporter.SetActiveObjects(m_innerScene.GetActiveObjectsCount()); - frameMS = System.Environment.TickCount - frameMS; - m_statsReporter.addFrameMS(frameMS); - m_statsReporter.addPhysicsMS(physicsMS); - m_statsReporter.addOtherMS(otherMS); - m_statsReporter.SetActiveScripts(m_innerScene.GetActiveScriptsCount()); - m_statsReporter.addScriptLines(m_innerScene.GetScriptLPS()); - } - } - catch (NotImplementedException) - { - throw; - } - catch (AccessViolationException e) - { - m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); - } - catch (NullReferenceException e) - { - m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); - } - catch (InvalidOperationException e) - { - m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); - } - catch (Exception e) - { - m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); - } - finally - { - updateLock.ReleaseMutex(); - // Get actual time dilation - float tmpval = (m_timespan / (float)SinceLastFrame.TotalSeconds); + if (m_frame % m_update_backup == 0) + { + UpdateStorageBackup(); + } - // If actual time dilation is greater then one, we're catching up, so subtract - // the amount that's greater then 1 from the time dilation - if (tmpval > 1.0) + if (m_frame % m_update_terrain == 0) + UpdateTerrain(); + + if (m_frame % m_update_land == 0) + UpdateLand(); + otherMS = System.Environment.TickCount - otherMS; + // if (m_frame%m_update_avatars == 0) + // UpdateInWorldTime(); + m_statsReporter.AddPhysicsFPS(physicsFPS); + m_statsReporter.AddTimeDilation(m_timedilation); + m_statsReporter.AddFPS(1); + m_statsReporter.AddInPackets(0); + m_statsReporter.SetRootAgents(m_innerScene.GetRootAgentCount()); + m_statsReporter.SetChildAgents(m_innerScene.GetChildAgentCount()); + m_statsReporter.SetObjects(m_innerScene.GetTotalObjectsCount()); + m_statsReporter.SetActiveObjects(m_innerScene.GetActiveObjectsCount()); + frameMS = System.Environment.TickCount - frameMS; + m_statsReporter.addFrameMS(frameMS); + m_statsReporter.addPhysicsMS(physicsMS); + m_statsReporter.addOtherMS(otherMS); + m_statsReporter.SetActiveScripts(m_innerScene.GetActiveScriptsCount()); + m_statsReporter.addScriptLines(m_innerScene.GetScriptLPS()); + } + } + catch (NotImplementedException) { - tmpval = tmpval - (tmpval - 1.0f); + throw; } - m_timedilation = tmpval; + catch (AccessViolationException e) + { + m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); + } + catch (NullReferenceException e) + { + m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); + } + catch (InvalidOperationException e) + { + m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); + } + catch (Exception e) + { + m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); + } + finally + { + //updateLock.ReleaseMutex(); + // Get actual time dilation + float tmpval = (m_timespan / (float)SinceLastFrame.TotalSeconds); - m_lastupdate = DateTime.Now; + // If actual time dilation is greater then one, we're catching up, so subtract + // the amount that's greater then 1 from the time dilation + if (tmpval > 1.0) + { + tmpval = tmpval - (tmpval - 1.0f); + } + m_timedilation = tmpval; + + m_lastupdate = DateTime.Now; + } + maintc = System.Environment.TickCount - maintc; + maintc = (int)(m_timespan * 1000) - maintc; + + if ((maintc < (m_timespan * 1000)) && maintc > 0) + Thread.Sleep(maintc); } } -- cgit v1.1