From 33448e4ba83b590e0e7e340faf3d7f2cef80c611 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Mon, 26 Oct 2009 07:50:25 -0700 Subject: Optimizations --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 51 ++++++++++++++++---------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 7b19ce3..57042e9 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -73,9 +73,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine private bool m_InitialStartup = true; private int m_ScriptFailCount; // Number of script fails since compile queue was last empty private string m_ScriptErrorMessage; + private Dictionary m_uniqueScripts = new Dictionary(); + private bool m_AppDomainLoading; -// disable warning: need to keep a reference to XEngine.EventManager -// alive to avoid it being garbage collected + // disable warning: need to keep a reference to XEngine.EventManager + // alive to avoid it being garbage collected #pragma warning disable 414 private EventManager m_EventManager; #pragma warning restore 414 @@ -201,6 +203,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_MaxScriptQueue = m_ScriptConfig.GetInt("MaxScriptEventQueue",300); m_StackSize = m_ScriptConfig.GetInt("ThreadStackSize", 262144); m_SleepTime = m_ScriptConfig.GetInt("MaintenanceInterval", 10) * 1000; + m_AppDomainLoading = m_ScriptConfig.GetBoolean("AppDomainLoading", true); m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); @@ -470,6 +473,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (engine != ScriptEngineName) return; + // If we've seen this exact script text before, use that reference instead + if (m_uniqueScripts.ContainsKey(script)) + script = m_uniqueScripts[script]; + else + m_uniqueScripts[script] = script; + Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez, (StateSource)stateSource}; if (stateSource == (int)StateSource.ScriptedRez) @@ -590,14 +599,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine { lock (m_AddingAssemblies) { - assembly = (string)m_Compiler.PerformScriptCompile(script, - assetID.ToString(), item.OwnerID); + m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap); if (!m_AddingAssemblies.ContainsKey(assembly)) { m_AddingAssemblies[assembly] = 1; } else { m_AddingAssemblies[assembly]++; } - linemap = m_Compiler.LineMap(); } string[] warnings = m_Compiler.GetWarnings(); @@ -696,19 +703,22 @@ namespace OpenSim.Region.ScriptEngine.XEngine Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; Evidence evidence = new Evidence(baseEvidence); - AppDomain sandbox = - AppDomain.CreateDomain( - m_Scene.RegionInfo.RegionID.ToString(), - evidence, appSetup); -/* - PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); - AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); - PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); - PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); - CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); - sandboxPolicy.RootCodeGroup = sandboxCodeGroup; - sandbox.SetAppDomainPolicy(sandboxPolicy); -*/ + AppDomain sandbox; + if (m_AppDomainLoading) + sandbox = AppDomain.CreateDomain( + m_Scene.RegionInfo.RegionID.ToString(), + evidence, appSetup); + else + sandbox = AppDomain.CurrentDomain; + /* + PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); + AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); + PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); + PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); + CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); + sandboxPolicy.RootCodeGroup = sandboxCodeGroup; + sandbox.SetAppDomainPolicy(sandboxPolicy); + */ m_AppDomains[appDomain] = sandbox; m_AppDomains[appDomain].AssemblyResolve += @@ -905,9 +915,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine AppDomain domain = m_AppDomains[id]; m_AppDomains.Remove(id); - AppDomain.Unload(domain); + if (domain != AppDomain.CurrentDomain) + AppDomain.Unload(domain); domain = null; -// m_log.DebugFormat("[XEngine] Unloaded app domain {0}", id.ToString()); + // m_log.DebugFormat("[XEngine] Unloaded app domain {0}", id.ToString()); } } -- cgit v1.1 From dd13fa361b12fa2fb1c91c9f74379a305935a87d Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 29 Oct 2009 05:56:37 -0700 Subject: * Misc. formatting cleanup for the previous patch * Added the new AppDomainLoading variable to the [XEngine] section in the example config --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 57042e9..b13e0de 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -710,15 +710,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine evidence, appSetup); else sandbox = AppDomain.CurrentDomain; - /* - PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); - AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); - PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); - PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); - CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); - sandboxPolicy.RootCodeGroup = sandboxCodeGroup; - sandbox.SetAppDomainPolicy(sandboxPolicy); - */ + + //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); + //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); + //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); + //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); + //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); + //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; + //sandbox.SetAppDomainPolicy(sandboxPolicy); + m_AppDomains[appDomain] = sandbox; m_AppDomains[appDomain].AssemblyResolve += -- cgit v1.1 From ec7fd8b1f810a13e7f78448e9ef81113ed3c5bf0 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 29 Oct 2009 06:42:40 -0700 Subject: More performance improvements to XEngine script loading --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 67 ++++++++++---------------- 1 file changed, 25 insertions(+), 42 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index b13e0de..b0fce75 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -50,6 +50,9 @@ using OpenSim.Region.ScriptEngine.Shared.CodeTools; using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Interfaces; +using ScriptCompileQueue = OpenSim.Framework.LocklessQueue; +using Parallel = OpenSim.Framework.Parallel; + namespace OpenSim.Region.ScriptEngine.XEngine { public class XEngine : INonSharedRegionModule, IScriptModule, IScriptEngine @@ -116,7 +119,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine private Dictionary > m_DomainScripts = new Dictionary >(); - private Queue m_CompileQueue = new Queue(100); + private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); IWorkItemResult m_CurrentCompile = null; public string ScriptEngineName @@ -487,16 +490,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine } else { - lock (m_CompileQueue) - { - m_CompileQueue.Enqueue(parms); + m_CompileQueue.Enqueue(parms); - if (m_CurrentCompile == null) - { - m_CurrentCompile = m_ThreadPool.QueueWorkItem( - new WorkItemCallback(this.DoOnRezScriptQueue), - new Object[0]); - } + if (m_CurrentCompile == null) + { + m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); } } } @@ -507,50 +505,35 @@ namespace OpenSim.Region.ScriptEngine.XEngine { m_InitialStartup = false; System.Threading.Thread.Sleep(15000); - lock (m_CompileQueue) + + if (m_CompileQueue.Count == 0) { - if (m_CompileQueue.Count==0) - // No scripts on region, so won't get triggered later - // by the queue becoming empty so we trigger it here - m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, String.Empty); + // No scripts on region, so won't get triggered later + // by the queue becoming empty so we trigger it here + m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, String.Empty); } } - Object o; - lock (m_CompileQueue) + List compiles = new List(); + object[] o; + while (m_CompileQueue.Dequeue(out o)) { - o = m_CompileQueue.Dequeue(); - if (o == null) - { - m_CurrentCompile = null; - return null; - } + compiles.Add(o); } - DoOnRezScript(o); + Parallel.For(0, compiles.Count, delegate(int i) { DoOnRezScript(compiles[i]); }); + + m_CurrentCompile = null; + m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, + m_ScriptErrorMessage); + m_ScriptFailCount = 0; - lock (m_CompileQueue) - { - if (m_CompileQueue.Count > 0) - { - m_CurrentCompile = m_ThreadPool.QueueWorkItem( - new WorkItemCallback(this.DoOnRezScriptQueue), - new Object[0]); - } - else - { - m_CurrentCompile = null; - m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, - m_ScriptErrorMessage); - m_ScriptFailCount = 0; - } - } return null; } - private bool DoOnRezScript(object parm) + private bool DoOnRezScript(object[] parms) { - Object[] p = (Object[])parm; + Object[] p = parms; uint localID = (uint)p[0]; UUID itemID = (UUID)p[1]; string script =(string)p[2]; -- cgit v1.1