diff options
Diffstat (limited to '')
8 files changed, 174 insertions, 114 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 6fba249..e955a58 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -503,7 +503,11 @@ namespace OpenSim | |||
503 | string currentCommand; | 503 | string currentCommand; |
504 | while ((currentCommand = readFile.ReadLine()) != null) | 504 | while ((currentCommand = readFile.ReadLine()) != null) |
505 | { | 505 | { |
506 | if (currentCommand != String.Empty) | 506 | currentCommand = currentCommand.Trim(); |
507 | if (!(currentCommand == "" | ||
508 | || currentCommand.StartsWith(";") | ||
509 | || currentCommand.StartsWith("//") | ||
510 | || currentCommand.StartsWith("#"))) | ||
507 | { | 511 | { |
508 | m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'"); | 512 | m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'"); |
509 | m_console.RunCommand(currentCommand); | 513 | m_console.RunCommand(currentCommand); |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index c303d6d..61d604f 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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | ||
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
30 | using System.IO; | 31 | using System.IO; |
32 | using System.Linq; | ||
31 | using System.Reflection; | 33 | using System.Reflection; |
32 | using System.Security; | 34 | using System.Security; |
33 | using log4net; | 35 | using log4net; |
@@ -45,8 +47,6 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
45 | { | 47 | { |
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 48 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | 49 | ||
48 | private delegate void LookupUUIDS(List<UUID> uuidLst); | ||
49 | |||
50 | public Scene Scene { get; private set; } | 50 | public Scene Scene { get; private set; } |
51 | public IUserManagement UserManager { get; private set; } | 51 | public IUserManagement UserManager { get; private set; } |
52 | 52 | ||
@@ -876,98 +876,77 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
876 | if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false)) | 876 | if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false)) |
877 | return; | 877 | return; |
878 | 878 | ||
879 | Dictionary<uint, float> SceneData = new Dictionary<uint,float>(); | 879 | Dictionary<uint, float> sceneData = null; |
880 | List<UUID> uuidNameLookupList = new List<UUID>(); | 880 | List<UUID> uuidNameLookupList = new List<UUID>(); |
881 | 881 | ||
882 | if (reportType == 1) | 882 | if (reportType == 1) |
883 | { | 883 | { |
884 | SceneData = Scene.PhysicsScene.GetTopColliders(); | 884 | sceneData = Scene.PhysicsScene.GetTopColliders(); |
885 | } | 885 | } |
886 | else if (reportType == 0) | 886 | else if (reportType == 0) |
887 | { | 887 | { |
888 | SceneData = Scene.SceneGraph.GetTopScripts(); | 888 | IScriptModule scriptModule = Scene.RequestModuleInterface<IScriptModule>(); |
889 | |||
890 | if (scriptModule != null) | ||
891 | sceneData = scriptModule.GetObjectScriptsExecutionTimes(); | ||
889 | } | 892 | } |
890 | 893 | ||
891 | List<LandStatReportItem> SceneReport = new List<LandStatReportItem>(); | 894 | List<LandStatReportItem> SceneReport = new List<LandStatReportItem>(); |
892 | lock (SceneData) | 895 | if (sceneData != null) |
893 | { | 896 | { |
894 | foreach (uint obj in SceneData.Keys) | 897 | var sortedSceneData |
898 | = sceneData.Select( | ||
899 | item => new { Measurement = item.Value, Part = Scene.GetSceneObjectPart(item.Key) }); | ||
900 | |||
901 | sortedSceneData.OrderBy(item => item.Measurement); | ||
902 | |||
903 | int items = 0; | ||
904 | |||
905 | foreach (var entry in sortedSceneData) | ||
895 | { | 906 | { |
896 | SceneObjectPart prt = Scene.GetSceneObjectPart(obj); | 907 | // The object may have been deleted since we received the data. |
897 | if (prt != null) | 908 | if (entry.Part == null) |
909 | continue; | ||
910 | |||
911 | // Don't show scripts that haven't executed or where execution time is below one microsecond in | ||
912 | // order to produce a more readable report. | ||
913 | if (entry.Measurement < 0.001) | ||
914 | continue; | ||
915 | |||
916 | items++; | ||
917 | SceneObjectGroup so = entry.Part.ParentGroup; | ||
918 | |||
919 | LandStatReportItem lsri = new LandStatReportItem(); | ||
920 | lsri.LocationX = so.AbsolutePosition.X; | ||
921 | lsri.LocationY = so.AbsolutePosition.Y; | ||
922 | lsri.LocationZ = so.AbsolutePosition.Z; | ||
923 | lsri.Score = entry.Measurement; | ||
924 | lsri.TaskID = so.UUID; | ||
925 | lsri.TaskLocalID = so.LocalId; | ||
926 | lsri.TaskName = entry.Part.Name; | ||
927 | lsri.OwnerName = UserManager.GetUserName(so.OwnerID); | ||
928 | |||
929 | if (filter.Length != 0) | ||
898 | { | 930 | { |
899 | SceneObjectGroup sog = prt.ParentGroup; | 931 | 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 | { | 932 | { |
914 | if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter))) | ||
915 | { | ||
916 | } | ||
917 | else | ||
918 | { | ||
919 | continue; | ||
920 | } | ||
921 | } | 933 | } |
922 | 934 | else | |
923 | SceneReport.Add(lsri); | 935 | { |
936 | continue; | ||
937 | } | ||
924 | } | 938 | } |
939 | |||
940 | SceneReport.Add(lsri); | ||
941 | |||
942 | if (items >= 100) | ||
943 | break; | ||
925 | } | 944 | } |
926 | } | 945 | } |
927 | 946 | ||
928 | remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray()); | 947 | remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray()); |
929 | |||
930 | if (uuidNameLookupList.Count > 0) | ||
931 | LookupUUID(uuidNameLookupList); | ||
932 | } | 948 | } |
933 | 949 | ||
934 | private static void LookupUUIDSCompleted(IAsyncResult iar) | ||
935 | { | ||
936 | LookupUUIDS icon = (LookupUUIDS)iar.AsyncState; | ||
937 | icon.EndInvoke(iar); | ||
938 | } | ||
939 | |||
940 | private void LookupUUID(List<UUID> uuidLst) | ||
941 | { | ||
942 | LookupUUIDS d = LookupUUIDsAsync; | ||
943 | |||
944 | d.BeginInvoke(uuidLst, | ||
945 | LookupUUIDSCompleted, | ||
946 | d); | ||
947 | } | ||
948 | |||
949 | private void LookupUUIDsAsync(List<UUID> uuidLst) | ||
950 | { | ||
951 | UUID[] uuidarr; | ||
952 | |||
953 | lock (uuidLst) | ||
954 | { | ||
955 | uuidarr = uuidLst.ToArray(); | ||
956 | } | ||
957 | |||
958 | for (int i = 0; i < uuidarr.Length; i++) | ||
959 | { | ||
960 | // string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]); | ||
961 | |||
962 | IUserManagement userManager = Scene.RequestModuleInterface<IUserManagement>(); | ||
963 | if (userManager != null) | ||
964 | userManager.GetUserName(uuidarr[i]); | ||
965 | |||
966 | // we drop it. It gets cached though... so we're ready for the next request. | ||
967 | // diva commnent 11/21/2010: uh?!? wft? | ||
968 | // justincc comment 21/01/2011: A side effect of userManager.GetUserName() I presume. | ||
969 | } | ||
970 | } | ||
971 | #endregion | 950 | #endregion |
972 | 951 | ||
973 | #region Outgoing Packets | 952 | #region Outgoing Packets |
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 18c45dd..9cab2e1 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | ||
30 | using OpenMetaverse; | 31 | using OpenMetaverse; |
31 | 32 | ||
32 | namespace OpenSim.Region.Framework.Interfaces | 33 | namespace OpenSim.Region.Framework.Interfaces |
@@ -74,5 +75,14 @@ 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> | ||
83 | /// A dictionary where the key is the root object ID of a linkset | ||
84 | /// and the value is a representative execution time in milliseconds of all scripts in that linkset. | ||
85 | /// </returns> | ||
86 | Dictionary<uint, float> GetObjectScriptsExecutionTimes(); | ||
77 | } | 87 | } |
78 | } | 88 | } \ 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..b04f6b6 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | |||
@@ -78,12 +78,38 @@ 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; } |
84 | string ScriptName { get; } | 99 | string ScriptName { get; } |
85 | UUID ItemID { get; } | 100 | UUID ItemID { get; } |
86 | UUID ObjectID { get; } | 101 | UUID ObjectID { get; } |
102 | |||
103 | /// <summary> | ||
104 | /// UUID of the root object for the linkset that the script is in. | ||
105 | /// </summary> | ||
106 | UUID RootObjectID { get; } | ||
107 | |||
108 | /// <summary> | ||
109 | /// Local id of the root object for the linkset that the script is in. | ||
110 | /// </summary> | ||
111 | uint RootLocalID { get; } | ||
112 | |||
87 | uint LocalID { get; } | 113 | uint LocalID { get; } |
88 | UUID AssetID { get; } | 114 | UUID AssetID { get; } |
89 | Queue EventQueue { get; } | 115 | Queue EventQueue { get; } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 968351b..6e36742 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -164,6 +164,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
164 | 164 | ||
165 | public uint LocalID { get; private set; } | 165 | public uint LocalID { get; private set; } |
166 | 166 | ||
167 | public UUID RootObjectID { get; private set; } | ||
168 | |||
169 | public uint RootLocalID { get; private set; } | ||
170 | |||
167 | public UUID AssetID { get; private set; } | 171 | public UUID AssetID { get; private set; } |
168 | 172 | ||
169 | public Queue EventQueue { get; private set; } | 173 | public Queue EventQueue { get; private set; } |
@@ -172,6 +176,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
172 | 176 | ||
173 | public TaskInventoryItem ScriptTask { get; private set; } | 177 | public TaskInventoryItem ScriptTask { get; private set; } |
174 | 178 | ||
179 | public DateTime TimeStarted { get; private set; } | ||
180 | |||
181 | public long MeasurementPeriodTickStart { get; private set; } | ||
182 | |||
183 | public long MeasurementPeriodExecutionTime { get; private set; } | ||
184 | |||
185 | public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute; | ||
186 | |||
175 | public void ClearQueue() | 187 | public void ClearQueue() |
176 | { | 188 | { |
177 | m_TimerQueued = false; | 189 | m_TimerQueued = false; |
@@ -190,6 +202,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
190 | Engine = engine; | 202 | Engine = engine; |
191 | LocalID = part.LocalId; | 203 | LocalID = part.LocalId; |
192 | ObjectID = part.UUID; | 204 | ObjectID = part.UUID; |
205 | RootLocalID = part.ParentGroup.LocalId; | ||
206 | RootObjectID = part.ParentGroup.UUID; | ||
193 | ItemID = itemID; | 207 | ItemID = itemID; |
194 | AssetID = assetID; | 208 | AssetID = assetID; |
195 | PrimName = primName; | 209 | PrimName = primName; |
@@ -458,6 +472,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
458 | 472 | ||
459 | Running = true; | 473 | Running = true; |
460 | 474 | ||
475 | TimeStarted = DateTime.Now; | ||
476 | MeasurementPeriodTickStart = Util.EnvironmentTickCount(); | ||
477 | MeasurementPeriodExecutionTime = 0; | ||
478 | |||
461 | if (EventQueue.Count > 0) | 479 | if (EventQueue.Count > 0) |
462 | { | 480 | { |
463 | if (m_CurrentWorkItem == null) | 481 | if (m_CurrentWorkItem == null) |
@@ -710,8 +728,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
710 | m_EventStart = DateTime.Now; | 728 | m_EventStart = DateTime.Now; |
711 | m_InEvent = true; | 729 | m_InEvent = true; |
712 | 730 | ||
731 | int start = Util.EnvironmentTickCount(); | ||
732 | |||
733 | // Reset the measurement period when we reach the end of the current one. | ||
734 | if (start - MeasurementPeriodTickStart > MaxMeasurementPeriod) | ||
735 | MeasurementPeriodTickStart = start; | ||
736 | |||
713 | m_Script.ExecuteEvent(State, data.EventName, data.Params); | 737 | m_Script.ExecuteEvent(State, data.EventName, data.Params); |
714 | 738 | ||
739 | MeasurementPeriodExecutionTime += Util.EnvironmentTickCount() - start; | ||
740 | |||
715 | m_InEvent = false; | 741 | m_InEvent = false; |
716 | m_CurrentEvent = String.Empty; | 742 | m_CurrentEvent = String.Empty; |
717 | 743 | ||
@@ -720,7 +746,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
720 | // This will be the very first event we deliver | 746 | // This will be the very first event we deliver |
721 | // (state_entry) in default state | 747 | // (state_entry) in default state |
722 | // | 748 | // |
723 | |||
724 | SaveState(m_Assembly); | 749 | SaveState(m_Assembly); |
725 | 750 | ||
726 | m_SaveState = false; | 751 | m_SaveState = false; |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 105d97d..3697f78 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -1083,7 +1083,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1083 | 1083 | ||
1084 | if (!m_PrimObjects[localID].Contains(itemID)) | 1084 | if (!m_PrimObjects[localID].Contains(itemID)) |
1085 | m_PrimObjects[localID].Add(itemID); | 1085 | m_PrimObjects[localID].Add(itemID); |
1086 | |||
1087 | } | 1086 | } |
1088 | 1087 | ||
1089 | if (!m_Assemblies.ContainsKey(assetID)) | 1088 | if (!m_Assemblies.ContainsKey(assetID)) |
@@ -1891,6 +1890,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1891 | } | 1890 | } |
1892 | } | 1891 | } |
1893 | 1892 | ||
1893 | public Dictionary<uint, float> GetObjectScriptsExecutionTimes() | ||
1894 | { | ||
1895 | long tickNow = Util.EnvironmentTickCount(); | ||
1896 | Dictionary<uint, float> topScripts = new Dictionary<uint, float>(); | ||
1897 | |||
1898 | lock (m_Scripts) | ||
1899 | { | ||
1900 | foreach (IScriptInstance si in m_Scripts.Values) | ||
1901 | { | ||
1902 | if (!topScripts.ContainsKey(si.LocalID)) | ||
1903 | topScripts[si.RootLocalID] = 0; | ||
1904 | |||
1905 | // long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; | ||
1906 | // float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond); | ||
1907 | |||
1908 | // Execution time of the script adjusted by it's measurement period to make scripts started at | ||
1909 | // different times comparable. | ||
1910 | // float adjustedExecutionTime | ||
1911 | // = (float)si.MeasurementPeriodExecutionTime | ||
1912 | // / ((float)(tickNow - si.MeasurementPeriodTickStart) / ScriptInstance.MaxMeasurementPeriod) | ||
1913 | // / TimeSpan.TicksPerMillisecond; | ||
1914 | |||
1915 | long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; | ||
1916 | |||
1917 | // Avoid divide by zerp | ||
1918 | if (ticksElapsed == 0) | ||
1919 | ticksElapsed = 1; | ||
1920 | |||
1921 | // Scale execution time to the ideal 55 fps frame time for these reasons. | ||
1922 | // | ||
1923 | // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no | ||
1924 | // 'script execution time per frame', which is the original purpose of this value. | ||
1925 | // | ||
1926 | // 2) Giving the raw execution times is misleading since scripts start at different times, making | ||
1927 | // it impossible to compare scripts. | ||
1928 | // | ||
1929 | // 3) Scaling the raw execution time to the time that the script has been running is better but | ||
1930 | // is still misleading since a script that has just been rezzed may appear to have been running | ||
1931 | // for much longer. | ||
1932 | // | ||
1933 | // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect | ||
1934 | // since the figure does not represent actual execution time and very hard running scripts will | ||
1935 | // never exceed 18ms (though this is a very high number for script execution so is a warning sign). | ||
1936 | float adjustedExecutionTime | ||
1937 | = ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f; | ||
1938 | |||
1939 | topScripts[si.RootLocalID] += adjustedExecutionTime; | ||
1940 | } | ||
1941 | } | ||
1942 | |||
1943 | return topScripts; | ||
1944 | } | ||
1945 | |||
1894 | public void SuspendScript(UUID itemID) | 1946 | public void SuspendScript(UUID itemID) |
1895 | { | 1947 | { |
1896 | // m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID); | 1948 | // m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID); |