aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs77
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModule.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs31
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs53
7 files changed, 145 insertions, 70 deletions
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index c303d6d..d363b15 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -26,8 +26,10 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.IO; 31using System.IO;
32using System.Linq;
31using System.Reflection; 33using System.Reflection;
32using System.Security; 34using System.Security;
33using log4net; 35using log4net;
@@ -876,52 +878,67 @@ namespace OpenSim.Region.CoreModules.World.Estate
876 if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false)) 878 if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false))
877 return; 879 return;
878 880
879 Dictionary<uint, float> SceneData = new Dictionary<uint,float>(); 881 Dictionary<uint, float> sceneData = null;
880 List<UUID> uuidNameLookupList = new List<UUID>(); 882 List<UUID> uuidNameLookupList = new List<UUID>();
881 883
882 if (reportType == 1) 884 if (reportType == 1)
883 { 885 {
884 SceneData = Scene.PhysicsScene.GetTopColliders(); 886 sceneData = Scene.PhysicsScene.GetTopColliders();
885 } 887 }
886 else if (reportType == 0) 888 else if (reportType == 0)
887 { 889 {
888 SceneData = Scene.SceneGraph.GetTopScripts(); 890 IScriptModule scriptModule = Scene.RequestModuleInterface<IScriptModule>();
891
892 if (scriptModule != null)
893 sceneData = scriptModule.GetObjectScriptsExecutionTimes();
889 } 894 }
890 895
891 List<LandStatReportItem> SceneReport = new List<LandStatReportItem>(); 896 List<LandStatReportItem> SceneReport = new List<LandStatReportItem>();
892 lock (SceneData) 897 if (sceneData != null)
893 { 898 {
894 foreach (uint obj in SceneData.Keys) 899 var sortedSceneData
900 = sceneData.Select(
901 item => new { Measurement = item.Value, Part = Scene.GetSceneObjectPart(item.Key) });
902
903 sortedSceneData.OrderBy(item => item.Measurement);
904
905 int items = 0;
906
907 foreach (var entry in sortedSceneData)
895 { 908 {
896 SceneObjectPart prt = Scene.GetSceneObjectPart(obj); 909 if (entry.Part == null)
897 if (prt != null) 910 continue;
911
912 items++;
913 SceneObjectGroup so = entry.Part.ParentGroup;
914
915 LandStatReportItem lsri = new LandStatReportItem();
916 lsri.LocationX = so.AbsolutePosition.X;
917 lsri.LocationY = so.AbsolutePosition.Y;
918 lsri.LocationZ = so.AbsolutePosition.Z;
919 lsri.Score = entry.Measurement;
920 lsri.TaskID = so.UUID;
921 lsri.TaskLocalID = so.LocalId;
922 lsri.TaskName = entry.Part.Name;
923 lsri.OwnerName = "waiting";
924 lock (uuidNameLookupList)
925 uuidNameLookupList.Add(so.OwnerID);
926
927 if (filter.Length != 0)
898 { 928 {
899 SceneObjectGroup sog = prt.ParentGroup; 929 if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
900 LandStatReportItem lsri = new LandStatReportItem();
901 lsri.LocationX = sog.AbsolutePosition.X;
902 lsri.LocationY = sog.AbsolutePosition.Y;
903 lsri.LocationZ = sog.AbsolutePosition.Z;
904 lsri.Score = SceneData[obj];
905 lsri.TaskID = sog.UUID;
906 lsri.TaskLocalID = sog.LocalId;
907 lsri.TaskName = sog.GetPartName(obj);
908 lsri.OwnerName = "waiting";
909 lock (uuidNameLookupList)
910 uuidNameLookupList.Add(sog.OwnerID);
911
912 if (filter.Length != 0)
913 { 930 {
914 if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
915 {
916 }
917 else
918 {
919 continue;
920 }
921 } 931 }
922 932 else
923 SceneReport.Add(lsri); 933 {
934 continue;
935 }
924 } 936 }
937
938 SceneReport.Add(lsri);
939
940 if (items >= 100)
941 break;
925 } 942 }
926 } 943 }
927 944
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
index 18c45dd..9fb4a25 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using OpenMetaverse; 31using OpenMetaverse;
31 32
32namespace OpenSim.Region.Framework.Interfaces 33namespace OpenSim.Region.Framework.Interfaces
@@ -74,5 +75,11 @@ namespace OpenSim.Region.Framework.Interfaces
74 /// Starts the processing threads. 75 /// Starts the processing threads.
75 /// </summary> 76 /// </summary>
76 void StartProcessing(); 77 void StartProcessing();
78
79 /// <summary>
80 /// Get the execution times of all scripts in each object.
81 /// </summary>
82 /// <returns>A dictionary where the key is a local object ID and the value is an execution time in milliseconds.</returns>
83 Dictionary<uint, float> GetObjectScriptsExecutionTimes();
77 } 84 }
78} 85} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index bc3400a..5c542d6 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -733,6 +733,7 @@ namespace OpenSim.Region.Framework.Scenes
733 #endregion 733 #endregion
734 734
735 #region Get Methods 735 #region Get Methods
736
736 /// <summary> 737 /// <summary>
737 /// Get the controlling client for the given avatar, if there is one. 738 /// Get the controlling client for the given avatar, if there is one.
738 /// 739 ///
@@ -1074,36 +1075,6 @@ namespace OpenSim.Region.Framework.Scenes
1074 return Entities.GetEntities(); 1075 return Entities.GetEntities();
1075 } 1076 }
1076 1077
1077 public Dictionary<uint, float> GetTopScripts()
1078 {
1079 Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
1080
1081 EntityBase[] EntityList = GetEntities();
1082 int limit = 0;
1083 foreach (EntityBase ent in EntityList)
1084 {
1085 if (ent is SceneObjectGroup)
1086 {
1087 SceneObjectGroup grp = (SceneObjectGroup)ent;
1088 if ((grp.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
1089 {
1090 if (grp.scriptScore >= 0.01)
1091 {
1092 topScripts.Add(grp.LocalId, grp.scriptScore);
1093 limit++;
1094 if (limit >= 100)
1095 {
1096 break;
1097 }
1098 }
1099 grp.scriptScore = 0;
1100 }
1101 }
1102 }
1103
1104 return topScripts;
1105 }
1106
1107 #endregion 1078 #endregion
1108 1079
1109 #region Other Methods 1080 #region Other Methods
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 878476e..afb5ccf 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -229,8 +229,6 @@ namespace OpenSim.Region.Framework.Scenes
229 get { return RootPart.VolumeDetectActive; } 229 get { return RootPart.VolumeDetectActive; }
230 } 230 }
231 231
232 public float scriptScore;
233
234 private Vector3 lastPhysGroupPos; 232 private Vector3 lastPhysGroupPos;
235 private Quaternion lastPhysGroupRot; 233 private Quaternion lastPhysGroupRot;
236 234
@@ -1184,12 +1182,7 @@ namespace OpenSim.Region.Framework.Scenes
1184 1182
1185 public void AddScriptLPS(int count) 1183 public void AddScriptLPS(int count)
1186 { 1184 {
1187 if (scriptScore + count >= float.MaxValue - count) 1185 m_scene.SceneGraph.AddToScriptLPS(count);
1188 scriptScore = 0;
1189
1190 scriptScore += (float)count;
1191 SceneGraph d = m_scene.SceneGraph;
1192 d.AddToScriptLPS(count);
1193 } 1186 }
1194 1187
1195 public void AddActiveScriptCount(int count) 1188 public void AddActiveScriptCount(int count)
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
index 8762642..11f54a2 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -78,6 +78,21 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
78 /// </summary> 78 /// </summary>
79 string State { get; set; } 79 string State { get; set; }
80 80
81 /// <summary>
82 /// Time the script was last started
83 /// </summary>
84 DateTime TimeStarted { get; }
85
86 /// <summary>
87 /// Tick the last measurement period was started.
88 /// </summary>
89 long MeasurementPeriodTickStart { get; }
90
91 /// <summary>
92 /// Ticks spent executing in the last measurement period.
93 /// </summary>
94 long MeasurementPeriodExecutionTime { get; }
95
81 IScriptEngine Engine { get; } 96 IScriptEngine Engine { get; }
82 UUID AppDomain { get; set; } 97 UUID AppDomain { get; set; }
83 string PrimName { get; } 98 string PrimName { get; }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 968351b..b177287 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -172,6 +172,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
172 172
173 public TaskInventoryItem ScriptTask { get; private set; } 173 public TaskInventoryItem ScriptTask { get; private set; }
174 174
175 public DateTime TimeStarted { get; private set; }
176
177 public long MeasurementPeriodTickStart { get; private set; }
178
179 public long MeasurementPeriodExecutionTime { get; private set; }
180
181 public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute;
182
175 public void ClearQueue() 183 public void ClearQueue()
176 { 184 {
177 m_TimerQueued = false; 185 m_TimerQueued = false;
@@ -458,6 +466,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
458 466
459 Running = true; 467 Running = true;
460 468
469 TimeStarted = DateTime.Now;
470 MeasurementPeriodTickStart = Util.EnvironmentTickCount();
471 MeasurementPeriodExecutionTime = 0;
472
461 if (EventQueue.Count > 0) 473 if (EventQueue.Count > 0)
462 { 474 {
463 if (m_CurrentWorkItem == null) 475 if (m_CurrentWorkItem == null)
@@ -710,8 +722,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
710 m_EventStart = DateTime.Now; 722 m_EventStart = DateTime.Now;
711 m_InEvent = true; 723 m_InEvent = true;
712 724
725 int start = Util.EnvironmentTickCount();
726
727 // Reset the measurement period when we reach the end of the current one.
728 if (start - MeasurementPeriodTickStart > MaxMeasurementPeriod)
729 MeasurementPeriodTickStart = start;
730
713 m_Script.ExecuteEvent(State, data.EventName, data.Params); 731 m_Script.ExecuteEvent(State, data.EventName, data.Params);
714 732
733 MeasurementPeriodExecutionTime += Util.EnvironmentTickCount() - start;
734
715 m_InEvent = false; 735 m_InEvent = false;
716 m_CurrentEvent = String.Empty; 736 m_CurrentEvent = String.Empty;
717 737
@@ -720,7 +740,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
720 // This will be the very first event we deliver 740 // This will be the very first event we deliver
721 // (state_entry) in default state 741 // (state_entry) in default state
722 // 742 //
723
724 SaveState(m_Assembly); 743 SaveState(m_Assembly);
725 744
726 m_SaveState = false; 745 m_SaveState = false;
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 105d97d..bddb1b9 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -1891,6 +1891,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1891 } 1891 }
1892 } 1892 }
1893 1893
1894 public Dictionary<uint, float> GetObjectScriptsExecutionTimes()
1895 {
1896 long tickNow = Util.EnvironmentTickCount();
1897 Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
1898
1899 lock (m_Scripts)
1900 {
1901 foreach (IScriptInstance si in m_Scripts.Values)
1902 {
1903 if (!topScripts.ContainsKey(si.LocalID))
1904 topScripts[si.LocalID] = 0;
1905
1906// long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
1907// float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond);
1908
1909 // Execution time of the script adjusted by it's measurement period to make scripts started at
1910 // different times comparable.
1911// float adjustedExecutionTime
1912// = (float)si.MeasurementPeriodExecutionTime
1913// / ((float)(tickNow - si.MeasurementPeriodTickStart) / ScriptInstance.MaxMeasurementPeriod)
1914// / TimeSpan.TicksPerMillisecond;
1915
1916 long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
1917
1918 // Avoid divide by zerp
1919 if (ticksElapsed == 0)
1920 ticksElapsed = 1;
1921
1922 // Scale execution time to the ideal 55 fps frame time for these reasons.
1923 //
1924 // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no
1925 // 'script execution time per frame', which is the original purpose of this value.
1926 //
1927 // 2) Giving the raw execution times is misleading since scripts start at different times, making
1928 // it impossible to compare scripts.
1929 //
1930 // 3) Scaling the raw execution time to the time that the script has been running is better but
1931 // is still misleading since a script that has just been rezzed may appear to have been running
1932 // for much longer.
1933 //
1934 // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect
1935 // since the figure does not represent actual execution time and very hard running scripts will
1936 // never exceed 18ms (though this is a very high number for script execution so is a warning sign).
1937 float adjustedExecutionTime
1938 = ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f;
1939
1940 topScripts[si.LocalID] += adjustedExecutionTime;
1941 }
1942 }
1943
1944 return topScripts;
1945 }
1946
1894 public void SuspendScript(UUID itemID) 1947 public void SuspendScript(UUID itemID)
1895 { 1948 {
1896// m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID); 1949// m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID);