* A hacky Top Scripts display. It isn't accurate as far as ms accounting, however you can use it to help find out what scripts are causing your simulator to cry.

* Access it from the Estate tools/Debug tab.
0.6.0-stable
Teravus Ovares 2008-05-25 20:50:45 +00:00
parent 76a3bde76e
commit c20f7d6171
9 changed files with 123 additions and 13 deletions

View File

@ -5652,6 +5652,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
handlerLandStatRequest(0, 1, 0, "", this);
}
break;
case "scripts":
handlerLandStatRequest = OnLandStatRequest;
if (handlerLandStatRequest != null)
{
handlerLandStatRequest(0, 0, 0, "", this);
}
break;
default:
m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket.ToString());
break;

View File

@ -313,12 +313,21 @@ namespace OpenSim.Region.Environment.Modules.World.Estate
}
private void HandleLandStatRequest(int parcelID, uint reportType, uint requestFlags, string filter, IClientAPI remoteClient)
{
Dictionary<uint, float> colliders = m_scene.PhysicsScene.GetTopColliders();
Dictionary<uint, float> SceneData = new Dictionary<uint,float>();
List<LandStatReportItem> collidera = new List<LandStatReportItem>();
lock (colliders)
if (reportType == 1)
{
foreach (uint obj in colliders.Keys)
SceneData = m_scene.PhysicsScene.GetTopColliders();
}
else if (reportType == 0)
{
SceneData = m_scene.m_innerScene.GetTopScripts();
}
List<LandStatReportItem> SceneReport = new List<LandStatReportItem>();
lock (SceneData)
{
foreach (uint obj in SceneData.Keys)
{
SceneObjectPart prt = m_scene.GetSceneObjectPart(obj);
if (prt != null)
@ -332,21 +341,30 @@ namespace OpenSim.Region.Environment.Modules.World.Estate
lsri.LocationX = sog.AbsolutePosition.X;
lsri.LocationY = sog.AbsolutePosition.Y;
lsri.LocationZ = sog.AbsolutePosition.Z;
lsri.Score = colliders[obj];
lsri.Score = SceneData[obj];
lsri.TaskID = sog.UUID;
lsri.TaskLocalID = sog.LocalId;
lsri.TaskName = sog.GetPartName(obj);
lsri.OwnerName = m_scene.CommsManager.UUIDNameRequestString(sog.OwnerID);
if (filter.Length != 0)
{
if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
{
}
else
{
continue;
}
}
collidera.Add(lsri);
SceneReport.Add(lsri);
}
}
}
}
}
remoteClient.SendLandStatReply(reportType, requestFlags, (uint)collidera.Count,collidera.ToArray());
remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray());
}

View File

@ -174,6 +174,9 @@ namespace OpenSim.Region.Environment.Scenes
public event AvatarKillData OnAvatarKilled;
public delegate void ScriptTimerEvent(uint localID, double timerinterval);
public event ScriptTimerEvent OnScriptTimerEvent;
public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj);
@ -332,6 +335,7 @@ namespace OpenSim.Region.Environment.Scenes
private RequestParcelPrimCountUpdate handlerRequestParcelPrimCountUpdate = null;
private ParcelPrimCountTainted handlerParcelPrimCountTainted = null;
private ObjectBeingRemovedFromScene handlerObjectBeingRemovedFromScene = null;
private ScriptTimerEvent handlerScriptTimerEvent = null;
public void TriggerOnScriptChangedEvent(uint localID, uint change)
{
@ -755,5 +759,16 @@ namespace OpenSim.Region.Environment.Scenes
}
}
// this lets us keep track of nasty script events like timer, etc.
public void TriggerTimerEvent(uint objLocalID, double Interval)
{
handlerScriptTimerEvent = OnScriptTimerEvent;
if (handlerScriptTimerEvent != null)
{
handlerScriptTimerEvent(objLocalID, Interval);
}
}
}
}

View File

@ -846,6 +846,37 @@ namespace OpenSim.Region.Environment.Scenes
return result;
}
public Dictionary<uint, float> GetTopScripts()
{
Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
List<EntityBase> EntityList = GetEntities();
int limit = 0;
foreach (EntityBase ent in EntityList)
{
if (ent is SceneObjectGroup)
{
SceneObjectGroup grp = (SceneObjectGroup)ent;
if ((grp.RootPart.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Scripted) != 0)
{
if (grp.scriptScore >= 0.01)
{
topScripts.Add(grp.LocalId, grp.scriptScore);
limit++;
if (limit >= 100)
{
break;
}
}
grp.scriptScore = 0;
}
}
}
return topScripts;
}
#endregion
#region Other Methods

View File

@ -90,6 +90,7 @@ namespace OpenSim.Region.Environment.Scenes
/// since the group's last persistent backup
/// </summary>
public bool HasGroupChanged = false;
public float scriptScore = 0f;
@ -959,6 +960,10 @@ namespace OpenSim.Region.Environment.Scenes
public void AddScriptLPS(int count)
{
if (scriptScore + count >= float.MaxValue - count)
scriptScore = 0;
scriptScore += (float)count;
InnerScene d = m_scene.m_innerScene;
d.AddToScriptLPS(count);
}

View File

@ -2752,6 +2752,14 @@ namespace OpenSim.Region.Environment.Scenes
PhysActor.OnCollisionUpdate -= PhysicsCollision;
}
}
if ((GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Scripted) != 0)
{
m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
}
else
{
m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting;
}
LocalFlags=(LLObject.ObjectFlags)objectflagupdate;
@ -2812,6 +2820,30 @@ namespace OpenSim.Region.Environment.Scenes
GetProperties(client);
m_updateFlag = 2;
}
private void handleTimerAccounting(uint localID, double interval)
{
if (localID == LocalId)
{
float sec = (float)interval;
if (m_parentGroup != null)
{
if (sec == 0)
{
if (m_parentGroup.scriptScore + 0.001f >= float.MaxValue - 0.001)
m_parentGroup.scriptScore = 0;
m_parentGroup.scriptScore += 0.001f;
return;
}
if (m_parentGroup.scriptScore + (0.001f / sec) >= float.MaxValue - (0.001f / sec))
m_parentGroup.scriptScore = 0;
m_parentGroup.scriptScore += (0.001f / sec);
}
}
}
}
}

View File

@ -474,7 +474,7 @@ namespace OpenSim.Region.ScriptEngine.Common
public void llSensor(string name, string id, int type, double range, double arc)
{
m_host.AddScriptLPS(1);
m_host.AddScriptLPS(300);
LLUUID keyID = LLUUID.Zero;
LLUUID.TryParse(id, out keyID);
@ -1818,7 +1818,7 @@ namespace OpenSim.Region.ScriptEngine.Common
public void llSleep(double sec)
{
m_host.AddScriptLPS(1);
m_host.AddScriptLPS((int)(sec * 100));
Thread.Sleep((int)(sec * 1000));
}
@ -2582,7 +2582,7 @@ namespace OpenSim.Region.ScriptEngine.Common
public void llResetScript()
{
m_host.AddScriptLPS(1);
m_host.AddScriptLPS(800);
m_ScriptEngine.m_ScriptManager.ResetScript(m_localID, m_itemID);
}
@ -4279,7 +4279,7 @@ namespace OpenSim.Region.ScriptEngine.Common
ScriptManager sm;
IScript script = null;
m_host.AddScriptLPS(1);
m_host.AddScriptLPS(8000);
// These functions are supposed to be robust,
// so get the state one step at a time.

View File

@ -316,6 +316,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.AsyncCommandPlugin
m_CmdManager.m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "sensor", EventQueueManager.llDetectNull,
new object[] { new LSL_Types.LSLInteger(SensedObjects.Length) });
}
m_CmdManager.m_ScriptEngine.World.EventManager.TriggerTimerEvent(ts.localID, ts.interval);
}
}
}

View File

@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.AsyncCommandPlugin
// Add it to queue
m_CmdManager.m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", EventQueueManager.llDetectNull,
null);
m_CmdManager.m_ScriptEngine.World.EventManager.TriggerTimerEvent(ts.localID, ((double)ts.interval / 10000000));
// set next interval
//ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);