diff options
Diffstat (limited to '')
3 files changed, 105 insertions, 2 deletions
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); |