Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
avinationmerge
Melanie 2012-04-13 03:00:48 +01:00
commit fe65b51876
8 changed files with 179 additions and 110 deletions

View File

@ -175,6 +175,16 @@ namespace OpenSim.Region.Framework.Interfaces
/// </returns>
List<TaskInventoryItem> GetInventoryItems(string name);
/// <summary>
/// Get inventory items by type.
/// </summary>
/// <param type="name"></param>
/// <returns>
/// A list of inventory items of that type.
/// If no inventory items of that type then an empty list is returned.
/// </returns>
List<TaskInventoryItem> GetInventoryItems(InventoryType type);
/// <summary>
/// Get the scene object referenced by an inventory item.
/// </summary>

View File

@ -84,6 +84,14 @@ namespace OpenSim.Region.Framework.Interfaces
/// </summary>
void StartProcessing();
/// <summary>
/// Get the execution times of all scripts in the given array if they are currently running.
/// </summary>
/// <returns>
/// A float the value is a representative execution time in milliseconds of all scripts in that Array.
/// </returns>
float GetScriptExecutionTime(List<UUID> itemIDs);
/// <summary>
/// Get the execution times of all scripts in each object.
/// </summary>

View File

@ -4031,6 +4031,45 @@ namespace OpenSim.Region.Framework.Scenes
return count;
}
/// <summary>
/// A float the value is a representative execution time in milliseconds of all scripts in the link set.
/// </summary>
public float ScriptExecutionTime()
{
IScriptModule[] engines = Scene.RequestModuleInterfaces<IScriptModule>();
if (engines.Length == 0) // No engine at all
return 0.0f;
float time = 0.0f;
// get all the scripts in all parts
SceneObjectPart[] parts = m_parts.GetArray();
List<TaskInventoryItem> scripts = new List<TaskInventoryItem>();
for (int i = 0; i < parts.Length; i++)
{
scripts.AddRange(parts[i].Inventory.GetInventoryItems(InventoryType.LSL));
}
// extract the UUIDs
List<UUID> ids = new List<UUID>(scripts.Count);
foreach (TaskInventoryItem script in scripts)
{
if (!ids.Contains(script.ItemID))
{
ids.Add(script.ItemID);
}
}
// Offer the list of script UUIDs to each engine found and accumulate the time
foreach (IScriptModule e in engines)
{
if (e != null)
{
time += e.GetScriptExecutionTime(ids);
}
}
return time;
}
/// <summary>
/// Returns a count of the number of running scripts in this groups parts.
/// </summary>

View File

@ -267,14 +267,9 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
{
Items.LockItemsForRead(true);
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
Items.LockItemsForRead(false);
foreach (TaskInventoryItem item in items)
{
if ((int)InventoryType.LSL == item.InvType)
CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
}
List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
foreach (TaskInventoryItem item in scripts)
CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
}
public ArrayList GetScriptErrors(UUID itemID)
@ -305,17 +300,11 @@ namespace OpenSim.Region.Framework.Scenes
/// </param>
public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
{
Items.LockItemsForRead(true);
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
Items.LockItemsForRead(false);
foreach (TaskInventoryItem item in items)
List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
foreach (TaskInventoryItem item in scripts)
{
if ((int)InventoryType.LSL == item.InvType)
{
RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
m_part.RemoveScriptEvents(item.ItemID);
}
RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
m_part.RemoveScriptEvents(item.ItemID);
}
}
@ -1291,17 +1280,15 @@ namespace OpenSim.Region.Framework.Scenes
public int ScriptCount()
{
int count = 0;
lock (m_items)
Items.LockItemsForRead(true);
foreach (TaskInventoryItem item in m_items.Values)
{
foreach (TaskInventoryItem item in m_items.Values)
if (item.InvType == (int)InventoryType.LSL)
{
if (item.InvType == (int)InventoryType.LSL)
{
count++;
}
count++;
}
}
Items.LockItemsForRead(false);
return count;
}
/// <summary>
@ -1315,7 +1302,7 @@ namespace OpenSim.Region.Framework.Scenes
return 0;
int count = 0;
List<TaskInventoryItem> scripts = GetInventoryScripts();
List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
foreach (TaskInventoryItem item in scripts)
{
@ -1347,22 +1334,24 @@ namespace OpenSim.Region.Framework.Scenes
{
List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
lock (m_items)
ret = new List<TaskInventoryItem>(m_items.Values);
Items.LockItemsForRead(true);
ret = new List<TaskInventoryItem>(m_items.Values);
Items.LockItemsForRead(false);
return ret;
}
public List<TaskInventoryItem> GetInventoryScripts()
public List<TaskInventoryItem> GetInventoryItems(InventoryType type)
{
List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
lock (m_items)
{
foreach (TaskInventoryItem item in m_items.Values)
if (item.InvType == (int)InventoryType.LSL)
ret.Add(item);
}
Items.LockItemsForRead(true);
foreach (TaskInventoryItem item in m_items.Values)
if (item.InvType == (int)type)
ret.Add(item);
Items.LockItemsForRead(false);
return ret;
}
@ -1384,35 +1373,32 @@ namespace OpenSim.Region.Framework.Scenes
if (engines.Length == 0) // No engine at all
return ret;
Items.LockItemsForRead(true);
foreach (TaskInventoryItem item in m_items.Values)
List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
foreach (TaskInventoryItem item in scripts)
{
if (item.InvType == (int)InventoryType.LSL)
foreach (IScriptModule e in engines)
{
foreach (IScriptModule e in engines)
if (e != null)
{
if (e != null)
string n = e.GetXMLState(item.ItemID);
if (n != String.Empty)
{
string n = e.GetXMLState(item.ItemID);
if (n != String.Empty)
if (oldIDs)
{
if (oldIDs)
{
if (!ret.ContainsKey(item.OldItemID))
ret[item.OldItemID] = n;
}
else
{
if (!ret.ContainsKey(item.ItemID))
ret[item.ItemID] = n;
}
break;
if (!ret.ContainsKey(item.OldItemID))
ret[item.OldItemID] = n;
}
else
{
if (!ret.ContainsKey(item.ItemID))
ret[item.ItemID] = n;
}
break;
}
}
}
}
Items.LockItemsForRead(false);
return ret;
}
@ -1422,27 +1408,21 @@ namespace OpenSim.Region.Framework.Scenes
if (engines.Length == 0)
return;
List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
Items.LockItemsForRead(true);
foreach (TaskInventoryItem item in m_items.Values)
foreach (TaskInventoryItem item in scripts)
{
if (item.InvType == (int)InventoryType.LSL)
foreach (IScriptModule engine in engines)
{
foreach (IScriptModule engine in engines)
if (engine != null)
{
if (engine != null)
{
if (item.OwnerChanged)
engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
item.OwnerChanged = false;
engine.ResumeScript(item.ItemID);
}
if (item.OwnerChanged)
engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
item.OwnerChanged = false;
engine.ResumeScript(item.ItemID);
}
}
}
Items.LockItemsForRead(false);
}
}
}

View File

@ -3540,6 +3540,25 @@ namespace OpenSim.Region.Framework.Scenes
return count;
}
/// <summary>
/// A float the value is a representative execution time in milliseconds of all scripts in all attachments.
/// </summary>
public float ScriptExecutionTime()
{
float time = 0.0f;
lock (m_attachments)
{
foreach (SceneObjectGroup gobj in m_attachments)
{
if (gobj != null)
{
time += gobj.ScriptExecutionTime();
}
}
}
return time;
}
/// <summary>
/// Returns the total count of running scripts in all parts.
/// </summary>

View File

@ -11176,7 +11176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ret.Add(new LSL_Integer(av.RunningScriptCount() * 16384));
break;
case ScriptBaseClass.OBJECT_SCRIPT_TIME:
ret.Add(new LSL_Float(0));
ret.Add(new LSL_Float(av.ScriptExecutionTime() / 1000.0f));
break;
case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE:
ret.Add(new LSL_Integer(1));
@ -11244,9 +11244,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount() * 16384));
break;
case ScriptBaseClass.OBJECT_SCRIPT_TIME:
// Average cpu time per simulator frame expended on all scripts in the object
// Not currently available at Object level
ret.Add(new LSL_Float(0));
// Average cpu time in seconds per simulator frame expended on all scripts in the object
ret.Add(new LSL_Float(obj.ParentGroup.ScriptExecutionTime() / 1000.0f));
break;
case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE:
// according to the SL wiki A prim or linkset will have prim

View File

@ -1997,47 +1997,61 @@ namespace OpenSim.Region.ScriptEngine.XEngine
if (!topScripts.ContainsKey(si.LocalID))
topScripts[si.RootLocalID] = 0;
// long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
// float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond);
// Execution time of the script adjusted by it's measurement period to make scripts started at
// different times comparable.
// float adjustedExecutionTime
// = (float)si.MeasurementPeriodExecutionTime
// / ((float)(tickNow - si.MeasurementPeriodTickStart) / ScriptInstance.MaxMeasurementPeriod)
// / TimeSpan.TicksPerMillisecond;
long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
// Avoid divide by zerp
if (ticksElapsed == 0)
ticksElapsed = 1;
// Scale execution time to the ideal 55 fps frame time for these reasons.
//
// 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no
// 'script execution time per frame', which is the original purpose of this value.
//
// 2) Giving the raw execution times is misleading since scripts start at different times, making
// it impossible to compare scripts.
//
// 3) Scaling the raw execution time to the time that the script has been running is better but
// is still misleading since a script that has just been rezzed may appear to have been running
// for much longer.
//
// 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect
// since the figure does not represent actual execution time and very hard running scripts will
// never exceed 18ms (though this is a very high number for script execution so is a warning sign).
float adjustedExecutionTime
= ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f;
topScripts[si.RootLocalID] += adjustedExecutionTime;
topScripts[si.RootLocalID] += CalculateAdjustedExectionTime(si, tickNow);
}
}
return topScripts;
}
public float GetScriptExecutionTime(List<UUID> itemIDs)
{
if (itemIDs == null|| itemIDs.Count == 0)
{
return 0.0f;
}
float time = 0.0f;
long tickNow = Util.EnvironmentTickCount();
IScriptInstance si;
// Calculate the time for all scripts that this engine is executing
// Ignore any others
foreach (UUID id in itemIDs)
{
si = GetInstance(id);
if (si != null && si.Running)
{
time += CalculateAdjustedExectionTime(si, tickNow);
}
}
return time;
}
private float CalculateAdjustedExectionTime(IScriptInstance si, long tickNow)
{
long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
// Avoid divide by zero
if (ticksElapsed == 0)
ticksElapsed = 1;
// Scale execution time to the ideal 55 fps frame time for these reasons.
//
// 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no
// 'script execution time per frame', which is the original purpose of this value.
//
// 2) Giving the raw execution times is misleading since scripts start at different times, making
// it impossible to compare scripts.
//
// 3) Scaling the raw execution time to the time that the script has been running is better but
// is still misleading since a script that has just been rezzed may appear to have been running
// for much longer.
//
// 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect
// since the figure does not represent actual execution time and very hard running scripts will
// never exceed 18ms (though this is a very high number for script execution so is a warning sign).
return ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f;
}
public void SuspendScript(UUID itemID)
{
// m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID);

View File

@ -36,7 +36,7 @@
; How often {in hours} should the disk be checked for expired filed
; Specify 0 to disable expiration checking
FileCleanupTimer = .166 ;roughly every 10 minutes
FileCleanupTimer = 1.0 ;every hour
; If WAIT_ON_INPROGRESS_REQUESTS has been defined then this specifies how
; long (in miliseconds) to block a request thread while trying to complete
@ -60,4 +60,4 @@
; cache, and request all assets that are found that are not already cached (this
; will cause those assets to be cached)
;
; DeepScanBeforePurge = false
DeepScanBeforePurge = true