aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2014-09-26 20:05:22 +0100
committerJustin Clark-Casey (justincc)2014-11-25 23:18:38 +0000
commit7bababaab64ccac7153f68c19a3988764d537b1e (patch)
tree3ed7b2db238fd605a2673aef2bdad57376705888 /OpenSim/Region/Framework/Scenes
parentMake BulletSim thread be ThreadPriority.Highest if running (diff)
downloadopensim-SC_OLD-7bababaab64ccac7153f68c19a3988764d537b1e.zip
opensim-SC_OLD-7bababaab64ccac7153f68c19a3988764d537b1e.tar.gz
opensim-SC_OLD-7bababaab64ccac7153f68c19a3988764d537b1e.tar.bz2
opensim-SC_OLD-7bababaab64ccac7153f68c19a3988764d537b1e.tar.xz
Improve frame time stability by taking a few unnecessary repeated calculations out of the main scene loop.
Also uses a wait event to sleep rather than a Thread.Sleep to allow the loop to be interrupted in a more controlled manner when necessary.
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs59
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs4
2 files changed, 42 insertions, 21 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index ce048ef..2da254b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -360,14 +360,31 @@ namespace OpenSim.Region.Framework.Scenes
360 public uint MaintenanceRun { get; private set; } 360 public uint MaintenanceRun { get; private set; }
361 361
362 /// <summary> 362 /// <summary>
363 /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we 363 /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we
364 /// will sleep for the remaining period. 364 /// will sleep for the remaining period.
365 /// </summary> 365 /// </summary>
366 /// <remarks> 366 /// <remarks>
367 /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations 367 /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations
368 /// occur too quickly (viewer 1) or with even more slide (viewer 2). 368 /// occur too quickly (viewer 1) or with even more slide (viewer 2).
369 /// </remarks> 369 /// </remarks>
370 public float MinFrameTime { get; private set; } 370 public int MinFrameTicks
371 {
372 get { return m_minFrameTicks; }
373 private set
374 {
375 m_minFrameTicks = value;
376 MinFrameSeconds = (float)m_minFrameTicks / 1000;
377 }
378 }
379 private int m_minFrameTicks;
380
381 /// <summary>
382 /// The minimum length of time in seconds that will be taken for a scene frame.
383 /// </summary>
384 /// <remarks>
385 /// Always derived from MinFrameTicks.
386 /// </remarks>
387 public float MinFrameSeconds { get; private set; }
371 388
372 /// <summary> 389 /// <summary>
373 /// The minimum length of time in seconds that will be taken for a maintenance run. 390 /// The minimum length of time in seconds that will be taken for a maintenance run.
@@ -412,8 +429,11 @@ namespace OpenSim.Region.Framework.Scenes
412 /// asynchronously from the update loop. 429 /// asynchronously from the update loop.
413 /// </summary> 430 /// </summary>
414 private bool m_cleaningTemps = false; 431 private bool m_cleaningTemps = false;
415 432
416// private Object m_heartbeatLock = new Object(); 433 /// <summary>
434 /// Used to control main scene thread looping time when not updating via timer.
435 /// </summary>
436 private ManualResetEvent m_updateWaitEvent = new ManualResetEvent(false);
417 437
418 // TODO: Possibly stop other classes being able to manipulate this directly. 438 // TODO: Possibly stop other classes being able to manipulate this directly.
419 private SceneGraph m_sceneGraph; 439 private SceneGraph m_sceneGraph;
@@ -782,7 +802,6 @@ namespace OpenSim.Region.Framework.Scenes
782 : this(regInfo, physicsScene) 802 : this(regInfo, physicsScene)
783 { 803 {
784 m_config = config; 804 m_config = config;
785 MinFrameTime = 0.089f;
786 MinMaintenanceTime = 1; 805 MinMaintenanceTime = 1;
787 SeeIntoRegion = true; 806 SeeIntoRegion = true;
788 807
@@ -1005,7 +1024,11 @@ namespace OpenSim.Region.Framework.Scenes
1005 } 1024 }
1006 } 1025 }
1007 1026
1008 MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime); 1027 if (startupConfig.Contains("MinFrameTime"))
1028 MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000);
1029 else
1030 MinFrameTicks = 89;
1031
1009 m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup); 1032 m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup);
1010 m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); 1033 m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations);
1011 m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement); 1034 m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement);
@@ -1445,7 +1468,7 @@ namespace OpenSim.Region.Framework.Scenes
1445 1468
1446 if (UpdateOnTimer) 1469 if (UpdateOnTimer)
1447 { 1470 {
1448 m_sceneUpdateTimer = new Timer(MinFrameTime * 1000); 1471 m_sceneUpdateTimer = new Timer(MinFrameTicks);
1449 m_sceneUpdateTimer.AutoReset = true; 1472 m_sceneUpdateTimer.AutoReset = true;
1450 m_sceneUpdateTimer.Elapsed += Update; 1473 m_sceneUpdateTimer.Elapsed += Update;
1451 m_sceneUpdateTimer.Start(); 1474 m_sceneUpdateTimer.Start();
@@ -1552,7 +1575,7 @@ namespace OpenSim.Region.Framework.Scenes
1552 runtc = (int)(MinMaintenanceTime * 1000) - runtc; 1575 runtc = (int)(MinMaintenanceTime * 1000) - runtc;
1553 1576
1554 if (runtc > 0) 1577 if (runtc > 0)
1555 Thread.Sleep(runtc); 1578 Thread.Sleep(runtc);
1556 1579
1557 // Optionally warn if a frame takes double the amount of time that it should. 1580 // Optionally warn if a frame takes double the amount of time that it should.
1558 if (DebugUpdates 1581 if (DebugUpdates
@@ -1613,7 +1636,7 @@ namespace OpenSim.Region.Framework.Scenes
1613 if (Frame % m_update_physics == 0) 1636 if (Frame % m_update_physics == 0)
1614 { 1637 {
1615 if (PhysicsEnabled) 1638 if (PhysicsEnabled)
1616 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime); 1639 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds);
1617 1640
1618 if (SynchronizeScene != null) 1641 if (SynchronizeScene != null)
1619 SynchronizeScene(this); 1642 SynchronizeScene(this);
@@ -1711,18 +1734,16 @@ namespace OpenSim.Region.Framework.Scenes
1711 { 1734 {
1712 Watchdog.UpdateThread(); 1735 Watchdog.UpdateThread();
1713 1736
1714 tmpMS = Util.EnvironmentTickCountSubtract(Util.EnvironmentTickCount(), m_lastFrameTick); 1737 spareMS = MinFrameTicks - Util.EnvironmentTickCountSubtract(m_lastFrameTick);
1715 tmpMS = (int)(MinFrameTime * 1000) - tmpMS;
1716 1738
1717 if (tmpMS > 0) 1739 if (spareMS > 0)
1718 { 1740 m_updateWaitEvent.WaitOne(spareMS);
1719 spareMS = tmpMS; 1741 else
1720 Thread.Sleep(tmpMS); 1742 spareMS = 0;
1721 }
1722 } 1743 }
1723 else 1744 else
1724 { 1745 {
1725 spareMS = Math.Max(0, (int)(MinFrameTime * 1000) - physicsMS2 - agentMS - physicsMS -otherMS); 1746 spareMS = Math.Max(0, MinFrameTicks - physicsMS2 - agentMS - physicsMS - otherMS);
1726 } 1747 }
1727 1748
1728 previousFrameTick = m_lastFrameTick; 1749 previousFrameTick = m_lastFrameTick;
@@ -1745,11 +1766,11 @@ namespace OpenSim.Region.Framework.Scenes
1745 // Optionally warn if a frame takes double the amount of time that it should. 1766 // Optionally warn if a frame takes double the amount of time that it should.
1746 if (DebugUpdates 1767 if (DebugUpdates
1747 && Util.EnvironmentTickCountSubtract( 1768 && Util.EnvironmentTickCountSubtract(
1748 m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2)) 1769 m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2)
1749 m_log.WarnFormat( 1770 m_log.WarnFormat(
1750 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", 1771 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1751 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), 1772 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
1752 MinFrameTime * 1000, 1773 MinFrameTicks,
1753 RegionInfo.RegionName); 1774 RegionInfo.RegionName);
1754 } 1775 }
1755 1776
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 95f9caf..8f1e345 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -224,7 +224,7 @@ namespace OpenSim.Region.Framework.Scenes
224 public SimStatsReporter(Scene scene) 224 public SimStatsReporter(Scene scene)
225 { 225 {
226 m_scene = scene; 226 m_scene = scene;
227 m_reportedFpsCorrectionFactor = scene.MinFrameTime * m_nominalReportedFps; 227 m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps;
228 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000); 228 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
229 ReportingRegion = scene.RegionInfo; 229 ReportingRegion = scene.RegionInfo;
230 230
@@ -239,7 +239,7 @@ namespace OpenSim.Region.Framework.Scenes
239 239
240 /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit 240 /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
241 /// longer than ideal (which in itself is a concern). 241 /// longer than ideal (which in itself is a concern).
242 SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.MinFrameTime * 1000 * 1.2); 242 SlowFramesStatReportThreshold = (int)Math.Ceiling(scene.MinFrameTicks * 1.2);
243 243
244 SlowFramesStat 244 SlowFramesStat
245 = new Stat( 245 = new Stat(