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