ScriptEngine changes in locking. Another step in direction of shared threads.

ThreadPoolClientBranch
Tedd Hansen 2008-02-21 11:28:34 +00:00
parent 7102ac7769
commit 89665faeaf
2 changed files with 22 additions and 24 deletions

View File

@ -60,24 +60,22 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
// Notes: // Notes:
// * Current execution load balancing is optimized for 1 thread, and can cause unfair execute balancing between scripts. // * Current execution load balancing is optimized for 1 thread, and can cause unfair execute balancing between scripts.
// Not noticeable unless server is under high load. // Not noticeable unless server is under high load.
// * This class contains the number of threads used for script executions. Since we are not microthreading scripts yet,
// increase number of threads to allow more concurrent script executions in OpenSim.
// //
public ScriptEngine m_ScriptEngine; public ScriptEngine m_ScriptEngine;
/// <summary> /// <summary>
/// List of threads (classes) processing event queue /// List of threads (classes) processing event queue
/// Note that this may or may not be a reference to a static object depending on PrivateRegionThreads config setting.
/// </summary> /// </summary>
internal List<EventQueueThreadClass> eventQueueThreads; // Thread pool that we work on internal List<EventQueueThreadClass> eventQueueThreads; // Thread pool that we work on
/// <summary> /// <summary>
/// Locking access to eventQueueThreads AND staticGlobalEventQueueThreads. /// Locking access to eventQueueThreads AND staticGlobalEventQueueThreads.
/// Note that this may or may not be a reference to a static object depending on PrivateRegionThreads config setting.
/// </summary> /// </summary>
private object eventQueueThreadsLock = new object(); // private object eventQueueThreadsLock = new object();
// Static objects for referencing the objects above if we don't have private threads: // Static objects for referencing the objects above if we don't have private threads:
internal static List<EventQueueThreadClass> staticEventQueueThreads; // A static reference used if we don't use private threads internal static List<EventQueueThreadClass> staticEventQueueThreads; // A static reference used if we don't use private threads
internal static object staticEventQueueThreadsLock; // Statick lock object reference for same reason // internal static object staticEventQueueThreadsLock; // Statick lock object reference for same reason
/// <summary> /// <summary>
/// Global static list of all threads (classes) processing event queue -- used by max enforcment thread /// Global static list of all threads (classes) processing event queue -- used by max enforcment thread
@ -91,7 +89,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
public object ThreadsToExitLock = new object(); public object ThreadsToExitLock = new object();
public object queueLock = new object(); // Mutex lock object //public object queueLock = new object(); // Mutex lock object
/// <summary> /// <summary>
/// How many threads to process queue with /// How many threads to process queue with
@ -183,7 +181,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{ {
// PRIVATE THREAD POOL PER REGION // PRIVATE THREAD POOL PER REGION
eventQueueThreads = new List<EventQueueThreadClass>(); eventQueueThreads = new List<EventQueueThreadClass>();
eventQueueThreadsLock = new object(); // eventQueueThreadsLock = new object();
} }
else else
{ {
@ -191,12 +189,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
// Crate the static objects // Crate the static objects
if (staticEventQueueThreads == null) if (staticEventQueueThreads == null)
staticEventQueueThreads = new List<EventQueueThreadClass>(); staticEventQueueThreads = new List<EventQueueThreadClass>();
if (staticEventQueueThreadsLock == null) // if (staticEventQueueThreadsLock == null)
staticEventQueueThreadsLock = new object(); // staticEventQueueThreadsLock = new object();
// Now reference our locals to them // Now reference our locals to them
eventQueueThreads = staticEventQueueThreads; eventQueueThreads = staticEventQueueThreads;
eventQueueThreadsLock = staticEventQueueThreadsLock; //eventQueueThreadsLock = staticEventQueueThreadsLock;
} }
ReadConfig(); ReadConfig();
@ -213,7 +211,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
EventExecutionMaxQueueSize = m_ScriptEngine.ScriptConfigSource.GetInt("EventExecutionMaxQueueSize", 300); EventExecutionMaxQueueSize = m_ScriptEngine.ScriptConfigSource.GetInt("EventExecutionMaxQueueSize", 300);
// Now refresh config in all threads // Now refresh config in all threads
lock (eventQueueThreadsLock) lock (eventQueueThreads)
{ {
foreach (EventQueueThreadClass EventQueueThread in eventQueueThreads) foreach (EventQueueThreadClass EventQueueThread in eventQueueThreads)
{ {
@ -232,10 +230,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
private void Stop() private void Stop()
{ {
if (eventQueueThreadsLock != null && eventQueueThreads != null) if (eventQueueThreads != null && eventQueueThreads != null)
{ {
// Kill worker threads // Kill worker threads
lock (eventQueueThreadsLock) lock (eventQueueThreads)
{ {
foreach (EventQueueThreadClass EventQueueThread in eventQueueThreads) foreach (EventQueueThreadClass EventQueueThread in eventQueueThreads)
{ {
@ -247,7 +245,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
} }
// Remove all entries from our event queue // Remove all entries from our event queue
lock (queueLock) lock (eventQueue)
{ {
eventQueue.Clear(); eventQueue.Clear();
} }
@ -361,7 +359,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
/// <param name="param">Array of parameters to match event mask</param> /// <param name="param">Array of parameters to match event mask</param>
public void AddToScriptQueue(uint localID, LLUUID itemID, string FunctionName, Queue_llDetectParams_Struct qParams, params object[] param) public void AddToScriptQueue(uint localID, LLUUID itemID, string FunctionName, Queue_llDetectParams_Struct qParams, params object[] param)
{ {
lock (queueLock) lock (eventQueue)
{ {
if (eventQueue.Count >= EventExecutionMaxQueueSize) if (eventQueue.Count >= EventExecutionMaxQueueSize)
{ {
@ -396,7 +394,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
if (eventQueueThreads.Count == numberOfThreads) if (eventQueueThreads.Count == numberOfThreads)
return; return;
lock (eventQueueThreadsLock) lock (eventQueueThreads)
{ {
int diff = numberOfThreads - eventQueueThreads.Count; int diff = numberOfThreads - eventQueueThreads.Count;
// Positive number: Start // Positive number: Start
@ -426,7 +424,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
public void CheckScriptMaxExecTime() public void CheckScriptMaxExecTime()
{ {
// Iterate through all ScriptThreadClasses and check how long their current function has been executing // Iterate through all ScriptThreadClasses and check how long their current function has been executing
lock (eventQueueThreadsLock) lock (eventQueueThreads)
{ {
foreach (EventQueueThreadClass EventQueueThread in staticGlobalEventQueueThreads) foreach (EventQueueThreadClass EventQueueThread in staticGlobalEventQueueThreads)
{ {

View File

@ -200,7 +200,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
//myScriptEngine.Log.Info("[" + ScriptEngineName + "]: Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName); //myScriptEngine.Log.Info("[" + ScriptEngineName + "]: Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
// OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
lock (eventQueueManager.queueLock) lock (eventQueueManager.eventQueue)
{ {
GotItem = false; GotItem = false;
for (int qc = 0; qc < eventQueueManager.eventQueue.Count; qc++) for (int qc = 0; qc < eventQueueManager.eventQueue.Count; qc++)
@ -230,12 +230,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{ {
///cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined ///cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
#if DEBUG #if DEBUG
eventQueueManager.m_ScriptEngine.Log.Debug("[" + ScriptEngineName + "]: " + //eventQueueManager.m_ScriptEngine.Log.Debug("[" + ScriptEngineName + "]: " +
"Executing event:\r\n" // "Executing event:\r\n"
+ "QIS.localID: " + QIS.localID // + "QIS.localID: " + QIS.localID
+ ", QIS.itemID: " + QIS.itemID // + ", QIS.itemID: " + QIS.itemID
+ ", QIS.functionName: " + // + ", QIS.functionName: " +
QIS.functionName); // QIS.functionName);
#endif #endif
LastExecutionStarted = DateTime.Now.Ticks; LastExecutionStarted = DateTime.Now.Ticks;
KillCurrentScript = false; KillCurrentScript = false;