diff options
author | Teravus Ovares | 2008-10-11 11:43:42 +0000 |
---|---|---|
committer | Teravus Ovares | 2008-10-11 11:43:42 +0000 |
commit | abc6424c51324fecd393057b3c95b1f93c74d573 (patch) | |
tree | 1a25ef7ca80d267b5c92373104ea466046e02c17 /OpenSim/Region/Environment | |
parent | Add the 4 missing events (diff) | |
download | opensim-SC_OLD-abc6424c51324fecd393057b3c95b1f93c74d573.zip opensim-SC_OLD-abc6424c51324fecd393057b3c95b1f93c74d573.tar.gz opensim-SC_OLD-abc6424c51324fecd393057b3c95b1f93c74d573.tar.bz2 opensim-SC_OLD-abc6424c51324fecd393057b3c95b1f93c74d573.tar.xz |
* 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.
Diffstat (limited to 'OpenSim/Region/Environment')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Scene.cs | 275 |
1 files changed, 148 insertions, 127 deletions
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 | |||
60 | public delegate void SynchronizeSceneHandler(Scene scene); | 60 | public delegate void SynchronizeSceneHandler(Scene scene); |
61 | public SynchronizeSceneHandler SynchronizeScene = null; | 61 | public SynchronizeSceneHandler SynchronizeScene = null; |
62 | public int splitID = 0; | 62 | public int splitID = 0; |
63 | |||
63 | 64 | ||
64 | #region Fields | 65 | #region Fields |
65 | 66 | ||
66 | protected Timer m_heartbeatTimer = new Timer(); | 67 | |
67 | protected Timer m_restartWaitTimer = new Timer(); | 68 | protected Timer m_restartWaitTimer = new Timer(); |
68 | 69 | ||
69 | protected SimStatsReporter m_statsReporter; | 70 | protected SimStatsReporter m_statsReporter; |
@@ -83,7 +84,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
83 | 84 | ||
84 | private int m_timePhase = 24; | 85 | private int m_timePhase = 24; |
85 | 86 | ||
86 | private readonly Mutex updateLock; | 87 | |
87 | 88 | ||
88 | /// <summary> | 89 | /// <summary> |
89 | /// Are we applying physics to any of the prims in this scene? | 90 | /// Are we applying physics to any of the prims in this scene? |
@@ -169,6 +170,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
169 | private bool m_scripts_enabled = true; | 170 | private bool m_scripts_enabled = true; |
170 | private string m_defaultScriptEngine; | 171 | private string m_defaultScriptEngine; |
171 | private int m_LastLogin = 0; | 172 | private int m_LastLogin = 0; |
173 | private Thread HeartbeatThread; | ||
174 | private volatile bool shuttingdown = false; | ||
172 | 175 | ||
173 | #endregion | 176 | #endregion |
174 | 177 | ||
@@ -259,7 +262,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
259 | bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion) | 262 | bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion) |
260 | { | 263 | { |
261 | m_config = config; | 264 | m_config = config; |
262 | updateLock = new Mutex(false); | 265 | |
263 | m_moduleLoader = moduleLoader; | 266 | m_moduleLoader = moduleLoader; |
264 | m_authenticateHandler = authen; | 267 | m_authenticateHandler = authen; |
265 | CommsManager = commsMan; | 268 | CommsManager = commsMan; |
@@ -631,7 +634,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
631 | // Stop all client threads. | 634 | // Stop all client threads. |
632 | ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(true); }); | 635 | ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(true); }); |
633 | // Stop updating the scene objects and agents. | 636 | // Stop updating the scene objects and agents. |
634 | m_heartbeatTimer.Close(); | 637 | //m_heartbeatTimer.Close(); |
638 | shuttingdown = true; | ||
635 | // close the inner scene | 639 | // close the inner scene |
636 | m_innerScene.Close(); | 640 | m_innerScene.Close(); |
637 | // De-register with region communications (events cleanup) | 641 | // De-register with region communications (events cleanup) |
@@ -656,10 +660,16 @@ namespace OpenSim.Region.Environment.Scenes | |||
656 | /// </summary> | 660 | /// </summary> |
657 | public void StartTimer() | 661 | public void StartTimer() |
658 | { | 662 | { |
659 | m_log.Debug("[SCENE]: Starting timer"); | 663 | //m_log.Debug("[SCENE]: Starting timer"); |
660 | m_heartbeatTimer.Enabled = true; | 664 | //m_heartbeatTimer.Enabled = true; |
661 | m_heartbeatTimer.Interval = (int)(m_timespan * 1000); | 665 | //m_heartbeatTimer.Interval = (int)(m_timespan * 1000); |
662 | m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); | 666 | //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); |
667 | HeartbeatThread = new Thread(new ParameterizedThreadStart(Heartbeat)); | ||
668 | HeartbeatThread.SetApartmentState(ApartmentState.MTA); | ||
669 | HeartbeatThread.Name = "Heartbeat"; | ||
670 | HeartbeatThread.Priority = ThreadPriority.AboveNormal; | ||
671 | ThreadTracker.Add(HeartbeatThread); | ||
672 | HeartbeatThread.Start(); | ||
663 | } | 673 | } |
664 | 674 | ||
665 | /// <summary> | 675 | /// <summary> |
@@ -685,7 +695,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
685 | /// </summary> | 695 | /// </summary> |
686 | /// <param name="sender"></param> | 696 | /// <param name="sender"></param> |
687 | /// <param name="e"></param> | 697 | /// <param name="e"></param> |
688 | private void Heartbeat(object sender, EventArgs e) | 698 | private void Heartbeat(object sender) |
689 | { | 699 | { |
690 | Update(); | 700 | Update(); |
691 | } | 701 | } |
@@ -695,146 +705,157 @@ namespace OpenSim.Region.Environment.Scenes | |||
695 | /// </summary> | 705 | /// </summary> |
696 | public override void Update() | 706 | public override void Update() |
697 | { | 707 | { |
698 | TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate; | 708 | int maintc = 0; |
699 | // Aquire a lock so only one update call happens at once | 709 | while (!shuttingdown) |
700 | updateLock.WaitOne(); | ||
701 | float physicsFPS = 0; | ||
702 | //m_log.Info("sadfadf" + m_neighbours.Count.ToString()); | ||
703 | int agentsInScene = m_innerScene.GetRootAgentCount() + m_innerScene.GetChildAgentCount(); | ||
704 | |||
705 | if (agentsInScene > 21) | ||
706 | { | 710 | { |
707 | if (m_update_entities == 1) | 711 | maintc = System.Environment.TickCount; |
712 | |||
713 | TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate; | ||
714 | // Aquire a lock so only one update call happens at once | ||
715 | //updateLock.WaitOne(); | ||
716 | float physicsFPS = 0; | ||
717 | //m_log.Info("sadfadf" + m_neighbours.Count.ToString()); | ||
718 | int agentsInScene = m_innerScene.GetRootAgentCount() + m_innerScene.GetChildAgentCount(); | ||
719 | |||
720 | if (agentsInScene > 21) | ||
708 | { | 721 | { |
709 | m_update_entities = 5; | 722 | if (m_update_entities == 1) |
710 | m_statsReporter.SetUpdateMS(6000); | 723 | { |
724 | m_update_entities = 5; | ||
725 | m_statsReporter.SetUpdateMS(6000); | ||
726 | } | ||
711 | } | 727 | } |
712 | } | 728 | else |
713 | else | ||
714 | { | ||
715 | if (m_update_entities == 5) | ||
716 | { | 729 | { |
717 | m_update_entities = 1; | 730 | if (m_update_entities == 5) |
718 | m_statsReporter.SetUpdateMS(3000); | 731 | { |
732 | m_update_entities = 1; | ||
733 | m_statsReporter.SetUpdateMS(3000); | ||
734 | } | ||
719 | } | 735 | } |
720 | } | ||
721 | 736 | ||
722 | frameMS = System.Environment.TickCount; | 737 | frameMS = System.Environment.TickCount; |
723 | try | 738 | try |
724 | { | 739 | { |
725 | // Increment the frame counter | 740 | // Increment the frame counter |
726 | m_frame++; | 741 | m_frame++; |
727 | |||
728 | // Loop it | ||
729 | if (m_frame == Int32.MaxValue) | ||
730 | m_frame = 0; | ||
731 | |||
732 | physicsMS2 = System.Environment.TickCount; | ||
733 | if ((m_frame % m_update_physics == 0) && m_physics_enabled) | ||
734 | m_innerScene.UpdatePreparePhysics(); | ||
735 | physicsMS2 = System.Environment.TickCount - physicsMS2; | ||
736 | 742 | ||
737 | if (m_frame % m_update_entitymovement == 0) | 743 | // Loop it |
738 | m_innerScene.UpdateEntityMovement(); | 744 | if (m_frame == Int32.MaxValue) |
745 | m_frame = 0; | ||
739 | 746 | ||
740 | physicsMS = System.Environment.TickCount; | 747 | physicsMS2 = System.Environment.TickCount; |
741 | if ((m_frame % m_update_physics == 0) && m_physics_enabled) | 748 | if ((m_frame % m_update_physics == 0) && m_physics_enabled) |
742 | physicsFPS = m_innerScene.UpdatePhysics( | 749 | m_innerScene.UpdatePreparePhysics(); |
743 | Math.Max(SinceLastFrame.TotalSeconds, m_timespan) | 750 | physicsMS2 = System.Environment.TickCount - physicsMS2; |
744 | ); | ||
745 | if (m_frame % m_update_physics == 0 && SynchronizeScene != null) | ||
746 | SynchronizeScene(this); | ||
747 | 751 | ||
748 | physicsMS = System.Environment.TickCount - physicsMS; | 752 | if (m_frame % m_update_entitymovement == 0) |
749 | physicsMS += physicsMS2; | 753 | m_innerScene.UpdateEntityMovement(); |
750 | 754 | ||
751 | otherMS = System.Environment.TickCount; | 755 | physicsMS = System.Environment.TickCount; |
752 | // run through all entities looking for updates (slow) | 756 | if ((m_frame % m_update_physics == 0) && m_physics_enabled) |
753 | if (m_frame % m_update_entities == 0) | 757 | physicsFPS = m_innerScene.UpdatePhysics( |
754 | m_innerScene.UpdateEntities(); | 758 | Math.Max(SinceLastFrame.TotalSeconds, m_timespan) |
759 | ); | ||
760 | if (m_frame % m_update_physics == 0 && SynchronizeScene != null) | ||
761 | SynchronizeScene(this); | ||
755 | 762 | ||
756 | // run through entities that have scheduled themselves for | 763 | physicsMS = System.Environment.TickCount - physicsMS; |
757 | // updates looking for updates(faster) | 764 | physicsMS += physicsMS2; |
758 | if (m_frame % m_update_entitiesquick == 0) | ||
759 | m_innerScene.ProcessUpdates(); | ||
760 | 765 | ||
761 | // Run through scenepresences looking for updates | 766 | otherMS = System.Environment.TickCount; |
762 | if (m_frame % m_update_presences == 0) | 767 | // run through all entities looking for updates (slow) |
763 | m_innerScene.UpdatePresences(); | 768 | if (m_frame % m_update_entities == 0) |
769 | m_innerScene.UpdateEntities(); | ||
764 | 770 | ||
765 | // Delete temp-on-rez stuff | 771 | // run through entities that have scheduled themselves for |
766 | if (m_frame % m_update_backup == 0) | 772 | // updates looking for updates(faster) |
767 | CleanTempObjects(); | 773 | if (m_frame % m_update_entitiesquick == 0) |
774 | m_innerScene.ProcessUpdates(); | ||
768 | 775 | ||
769 | if (Region_Status != RegionStatus.SlaveScene) | 776 | // Run through scenepresences looking for updates |
770 | { | 777 | if (m_frame % m_update_presences == 0) |
771 | if (m_frame % m_update_events == 0) | 778 | m_innerScene.UpdatePresences(); |
772 | UpdateEvents(); | ||
773 | 779 | ||
780 | // Delete temp-on-rez stuff | ||
774 | if (m_frame % m_update_backup == 0) | 781 | if (m_frame % m_update_backup == 0) |
782 | CleanTempObjects(); | ||
783 | |||
784 | if (Region_Status != RegionStatus.SlaveScene) | ||
775 | { | 785 | { |
776 | UpdateStorageBackup(); | 786 | if (m_frame % m_update_events == 0) |
777 | } | 787 | UpdateEvents(); |
778 | 788 | ||
779 | if (m_frame % m_update_terrain == 0) | 789 | if (m_frame % m_update_backup == 0) |
780 | UpdateTerrain(); | 790 | { |
781 | 791 | UpdateStorageBackup(); | |
782 | if (m_frame % m_update_land == 0) | 792 | } |
783 | UpdateLand(); | ||
784 | otherMS = System.Environment.TickCount - otherMS; | ||
785 | // if (m_frame%m_update_avatars == 0) | ||
786 | // UpdateInWorldTime(); | ||
787 | m_statsReporter.AddPhysicsFPS(physicsFPS); | ||
788 | m_statsReporter.AddTimeDilation(m_timedilation); | ||
789 | m_statsReporter.AddFPS(1); | ||
790 | m_statsReporter.AddInPackets(0); | ||
791 | m_statsReporter.SetRootAgents(m_innerScene.GetRootAgentCount()); | ||
792 | m_statsReporter.SetChildAgents(m_innerScene.GetChildAgentCount()); | ||
793 | m_statsReporter.SetObjects(m_innerScene.GetTotalObjectsCount()); | ||
794 | m_statsReporter.SetActiveObjects(m_innerScene.GetActiveObjectsCount()); | ||
795 | frameMS = System.Environment.TickCount - frameMS; | ||
796 | m_statsReporter.addFrameMS(frameMS); | ||
797 | m_statsReporter.addPhysicsMS(physicsMS); | ||
798 | m_statsReporter.addOtherMS(otherMS); | ||
799 | m_statsReporter.SetActiveScripts(m_innerScene.GetActiveScriptsCount()); | ||
800 | m_statsReporter.addScriptLines(m_innerScene.GetScriptLPS()); | ||
801 | } | ||
802 | } | ||
803 | catch (NotImplementedException) | ||
804 | { | ||
805 | throw; | ||
806 | } | ||
807 | catch (AccessViolationException e) | ||
808 | { | ||
809 | m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); | ||
810 | } | ||
811 | catch (NullReferenceException e) | ||
812 | { | ||
813 | m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); | ||
814 | } | ||
815 | catch (InvalidOperationException e) | ||
816 | { | ||
817 | m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); | ||
818 | } | ||
819 | catch (Exception e) | ||
820 | { | ||
821 | m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); | ||
822 | } | ||
823 | finally | ||
824 | { | ||
825 | updateLock.ReleaseMutex(); | ||
826 | // Get actual time dilation | ||
827 | float tmpval = (m_timespan / (float)SinceLastFrame.TotalSeconds); | ||
828 | 793 | ||
829 | // If actual time dilation is greater then one, we're catching up, so subtract | 794 | if (m_frame % m_update_terrain == 0) |
830 | // the amount that's greater then 1 from the time dilation | 795 | UpdateTerrain(); |
831 | if (tmpval > 1.0) | 796 | |
797 | if (m_frame % m_update_land == 0) | ||
798 | UpdateLand(); | ||
799 | otherMS = System.Environment.TickCount - otherMS; | ||
800 | // if (m_frame%m_update_avatars == 0) | ||
801 | // UpdateInWorldTime(); | ||
802 | m_statsReporter.AddPhysicsFPS(physicsFPS); | ||
803 | m_statsReporter.AddTimeDilation(m_timedilation); | ||
804 | m_statsReporter.AddFPS(1); | ||
805 | m_statsReporter.AddInPackets(0); | ||
806 | m_statsReporter.SetRootAgents(m_innerScene.GetRootAgentCount()); | ||
807 | m_statsReporter.SetChildAgents(m_innerScene.GetChildAgentCount()); | ||
808 | m_statsReporter.SetObjects(m_innerScene.GetTotalObjectsCount()); | ||
809 | m_statsReporter.SetActiveObjects(m_innerScene.GetActiveObjectsCount()); | ||
810 | frameMS = System.Environment.TickCount - frameMS; | ||
811 | m_statsReporter.addFrameMS(frameMS); | ||
812 | m_statsReporter.addPhysicsMS(physicsMS); | ||
813 | m_statsReporter.addOtherMS(otherMS); | ||
814 | m_statsReporter.SetActiveScripts(m_innerScene.GetActiveScriptsCount()); | ||
815 | m_statsReporter.addScriptLines(m_innerScene.GetScriptLPS()); | ||
816 | } | ||
817 | } | ||
818 | catch (NotImplementedException) | ||
832 | { | 819 | { |
833 | tmpval = tmpval - (tmpval - 1.0f); | 820 | throw; |
834 | } | 821 | } |
835 | m_timedilation = tmpval; | 822 | catch (AccessViolationException e) |
823 | { | ||
824 | m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); | ||
825 | } | ||
826 | catch (NullReferenceException e) | ||
827 | { | ||
828 | m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); | ||
829 | } | ||
830 | catch (InvalidOperationException e) | ||
831 | { | ||
832 | m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); | ||
833 | } | ||
834 | catch (Exception e) | ||
835 | { | ||
836 | m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); | ||
837 | } | ||
838 | finally | ||
839 | { | ||
840 | //updateLock.ReleaseMutex(); | ||
841 | // Get actual time dilation | ||
842 | float tmpval = (m_timespan / (float)SinceLastFrame.TotalSeconds); | ||
836 | 843 | ||
837 | m_lastupdate = DateTime.Now; | 844 | // If actual time dilation is greater then one, we're catching up, so subtract |
845 | // the amount that's greater then 1 from the time dilation | ||
846 | if (tmpval > 1.0) | ||
847 | { | ||
848 | tmpval = tmpval - (tmpval - 1.0f); | ||
849 | } | ||
850 | m_timedilation = tmpval; | ||
851 | |||
852 | m_lastupdate = DateTime.Now; | ||
853 | } | ||
854 | maintc = System.Environment.TickCount - maintc; | ||
855 | maintc = (int)(m_timespan * 1000) - maintc; | ||
856 | |||
857 | if ((maintc < (m_timespan * 1000)) && maintc > 0) | ||
858 | Thread.Sleep(maintc); | ||
838 | } | 859 | } |
839 | } | 860 | } |
840 | 861 | ||