aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XMREngine/XMREngXmrTestLs.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMREngXmrTestLs.cs491
1 files changed, 491 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMREngXmrTestLs.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMREngXmrTestLs.cs
new file mode 100644
index 0000000..266c5aa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/XMREngine/XMREngXmrTestLs.cs
@@ -0,0 +1,491 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using System.Text;
34using System.Threading;
35
36using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
37using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
38using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
39using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
40using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
43
44namespace OpenSim.Region.ScriptEngine.XMREngine
45{
46 public partial class XMREngine {
47
48 private void XmrTestLs (string[] args, int indx)
49 {
50 bool flagFull = false;
51 bool flagQueues = false;
52 bool flagTopCPU = false;
53 int maxScripts = 0x7FFFFFFF;
54 int numScripts = 0;
55 string outName = null;
56 XMRInstance[] instances;
57
58 /*
59 * Decode command line options.
60 */
61 for (int i = indx; i < args.Length; i ++) {
62 if (args[i] == "-full") {
63 flagFull = true;
64 continue;
65 }
66 if (args[i] == "-help") {
67 m_log.Info ("[XMREngine]: xmr ls -full -max=<number> -out=<filename> -queues -topcpu");
68 return;
69 }
70 if (args[i].StartsWith("-max=")) {
71 try {
72 maxScripts = Convert.ToInt32(args[i].Substring(5));
73 } catch (Exception e) {
74 m_log.Error("[XMREngine]: bad max " + args[i].Substring(5) + ": " + e.Message);
75 return;
76 }
77 continue;
78 }
79 if (args[i].StartsWith("-out=")) {
80 outName = args[i].Substring(5);
81 continue;
82 }
83 if (args[i] == "-queues") {
84 flagQueues = true;
85 continue;
86 }
87 if (args[i] == "-topcpu") {
88 flagTopCPU = true;
89 continue;
90 }
91 if (args[i][0] == '-') {
92 m_log.Error("[XMREngine]: unknown option " + args[i] + ", try 'xmr ls -help'");
93 return;
94 }
95 }
96
97 TextWriter outFile = null;
98 if (outName != null) {
99 try {
100 outFile = File.CreateText(outName);
101 } catch (Exception e) {
102 m_log.Error("[XMREngine]: error creating " + outName + ": " + e.Message);
103 return;
104 }
105 } else {
106 outFile = new LogInfoTextWriter(m_log);
107 }
108
109 try {
110 for (int i = 0; i < numThreadScriptWorkers; i ++) {
111 XMRScriptThread th = m_ScriptThreads[i];
112 outFile.WriteLine("Script thread ID: " + th.m_ScriptThreadTID);
113 long execTime = th.m_ScriptExecTime;
114 if (execTime < 0) {
115 execTime += (long)(DateTime.UtcNow - DateTime.MinValue).TotalMilliseconds;
116 }
117 outFile.WriteLine(" execution time: " + execTime + " mS");
118 outFile.WriteLine(" last ran at: " + th.m_LastRanAt.ToString());
119 XMRInstance rins = th.m_RunInstance;
120 if (rins != null) {
121 outFile.WriteLine(" running: " + rins.ItemID.ToString() + " " + rins.m_DescName);
122 if (flagFull) {
123 outFile.WriteLine (rins.RunTestLs (true));
124 }
125 }
126 }
127
128 /*
129 * Scan instance list to find those that match selection criteria.
130 */
131 if (!Monitor.TryEnter(m_InstancesDict, 100)) {
132 m_log.Error("[XMREngine]: deadlock m_LockedDict=" + m_LockedDict);
133 return;
134 }
135 try
136 {
137 instances = new XMRInstance[m_InstancesDict.Count];
138 foreach (XMRInstance ins in m_InstancesDict.Values)
139 {
140 if (InstanceMatchesArgs(ins, args, indx)) {
141 instances[numScripts++] = ins;
142 }
143 }
144 } finally {
145 Monitor.Exit(m_InstancesDict);
146 }
147
148 /*
149 * Maybe sort by descending CPU time.
150 */
151 if (flagTopCPU) {
152 Array.Sort<XMRInstance>(instances, CompareInstancesByCPUTime);
153 }
154
155 /*
156 * Print the entries.
157 */
158 if (!flagFull) {
159 outFile.WriteLine(" ItemID" +
160 " CPU(ms)" +
161 " NumEvents" +
162 " Status " +
163 " World Position " +
164 " <Part>:<Item>");
165 }
166 for (int i = 0; (i < numScripts) && (i < maxScripts); i ++) {
167 outFile.WriteLine(instances[i].RunTestLs(flagFull));
168 }
169
170 /*
171 * Print number of scripts that match selection criteria,
172 * even if we were told to print fewer.
173 */
174 outFile.WriteLine("total of {0} script(s)", numScripts);
175
176 /*
177 * If -queues given, print out queue contents too.
178 */
179 if (flagQueues) {
180 LsQueue(outFile, "start", m_StartQueue, args, indx);
181 LsQueue(outFile, "sleep", m_SleepQueue, args, indx);
182 LsQueue(outFile, "yield", m_YieldQueue, args, indx);
183 }
184 } finally {
185 outFile.Close();
186 }
187 }
188
189 private void XmrTestPev (string[] args, int indx)
190 {
191 bool flagAll = false;
192 int numScripts = 0;
193 XMRInstance[] instances;
194
195 /*
196 * Decode command line options.
197 */
198 int i, j;
199 List<string> selargs = new List<string> (args.Length);
200 MethodInfo[] eventmethods = typeof (IEventHandlers).GetMethods ();
201 MethodInfo eventmethod;
202 for (i = indx; i < args.Length; i ++) {
203 string arg = args[i];
204 if (arg == "-all") {
205 flagAll = true;
206 continue;
207 }
208 if (arg == "-help") {
209 m_log.Info ("[XMREngine]: xmr pev -all | <part-of-script-name> <event-name> <params...>");
210 return;
211 }
212 if (arg[0] == '-') {
213 m_log.Error ("[XMREngine]: unknown option " + arg + ", try 'xmr pev -help'");
214 return;
215 }
216 for (j = 0; j < eventmethods.Length; j ++) {
217 eventmethod = eventmethods[j];
218 if (eventmethod.Name == arg) goto gotevent;
219 }
220 selargs.Add (arg);
221 }
222 m_log.Error ("[XMREngine]: missing <event-name> <params...>, try 'xmr pev -help'");
223 return;
224 gotevent:
225 string eventname = eventmethod.Name;
226 StringBuilder sourcesb = new StringBuilder ();
227 while (++ i < args.Length) {
228 sourcesb.Append (' ');
229 sourcesb.Append (args[i]);
230 }
231 string sourcest = sourcesb.ToString ();
232 string sourcehash;
233 youveanerror = false;
234 Token t = TokenBegin.Construct ("", null, ErrorMsg, sourcest, out sourcehash);
235 if (youveanerror) return;
236 ParameterInfo[] paraminfos = eventmethod.GetParameters ();
237 object[] paramvalues = new object[paraminfos.Length];
238 i = 0;
239 while (!((t = t.nextToken) is TokenEnd)) {
240 if (i >= paramvalues.Length) {
241 ErrorMsg (t, "extra parameter(s)");
242 return;
243 }
244 paramvalues[i] = ParseParamValue (ref t);
245 if (paramvalues[i] == null) return;
246 i ++;
247 }
248 OpenSim.Region.ScriptEngine.Shared.EventParams eps =
249 new OpenSim.Region.ScriptEngine.Shared.EventParams (eventname, paramvalues, zeroDetectParams);
250
251 /*
252 * Scan instance list to find those that match selection criteria.
253 */
254 if (!Monitor.TryEnter(m_InstancesDict, 100)) {
255 m_log.Error("[XMREngine]: deadlock m_LockedDict=" + m_LockedDict);
256 return;
257 }
258
259 try {
260 instances = new XMRInstance[m_InstancesDict.Count];
261 foreach (XMRInstance ins in m_InstancesDict.Values) {
262 if (flagAll || InstanceMatchesArgs (ins, selargs.ToArray (), 0)) {
263 instances[numScripts++] = ins;
264 }
265 }
266 } finally {
267 Monitor.Exit(m_InstancesDict);
268 }
269
270 /*
271 * Post event to the matching instances.
272 */
273 for (i = 0; i < numScripts; i ++) {
274 XMRInstance inst = instances[i];
275 m_log.Info ("[XMREngine]: post " + eventname + " to " + inst.m_DescName);
276 inst.PostEvent (eps);
277 }
278 }
279
280 private object ParseParamValue (ref Token token)
281 {
282 if (token is TokenFloat) {
283 return new LSL_Float (((TokenFloat)token).val);
284 }
285 if (token is TokenInt) {
286 return new LSL_Integer (((TokenInt)token).val);
287 }
288 if (token is TokenStr) {
289 return new LSL_String (((TokenStr)token).val);
290 }
291 if (token is TokenKwCmpLT) {
292 List<double> valuelist = new List<double> ();
293 while (!((token = token.nextToken) is TokenKwCmpGT)) {
294 if (!(token is TokenKwComma)) {
295 object value = ParseParamValue (ref token);
296 if (value == null) return null;
297 if (value is int) value = (double)(int)value;
298 if (!(value is double)) {
299 ErrorMsg (token, "must be float or integer constant");
300 return null;
301 }
302 valuelist.Add ((double)value);
303 } else if (token.prevToken is TokenKwComma) {
304 ErrorMsg (token, "missing constant");
305 return null;
306 }
307 }
308 double[] values = valuelist.ToArray ();
309 switch (values.Length) {
310 case 3: {
311 return new LSL_Vector (values[0], values[1], values[2]);
312 }
313 case 4: {
314 return new LSL_Rotation (values[0], values[1], values[2], values[3]);
315 }
316 default: {
317 ErrorMsg (token, "not rotation or vector");
318 return null;
319 }
320 }
321 }
322 if (token is TokenKwBrkOpen) {
323 List<object> valuelist = new List<object> ();
324 while (!((token = token.nextToken) is TokenKwBrkClose)) {
325 if (!(token is TokenKwComma)) {
326 object value = ParseParamValue (ref token);
327 if (value == null) return null;
328 valuelist.Add (value);
329 } else if (token.prevToken is TokenKwComma) {
330 ErrorMsg (token, "missing constant");
331 return null;
332 }
333 }
334 return new LSL_List (valuelist.ToArray ());
335 }
336 if (token is TokenName) {
337 FieldInfo field = typeof (OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass).GetField (((TokenName)token).val);
338 if ((field != null) && field.IsPublic && (field.IsLiteral || (field.IsStatic && field.IsInitOnly))) {
339 return field.GetValue (null);
340 }
341 }
342 ErrorMsg (token, "invalid constant");
343 return null;
344 }
345
346 private bool youveanerror;
347 private void ErrorMsg (Token token, string message)
348 {
349 youveanerror = true;
350 m_log.Info ("[XMREngine]: " + token.posn + " " + message);
351 }
352
353 private void XmrTestReset (string[] args, int indx)
354 {
355 bool flagAll = false;
356 int numScripts = 0;
357 XMRInstance[] instances;
358
359 if (args.Length <= indx) {
360 m_log.Error("[XMREngine]: must specify part of script name or -all for all scripts");
361 return;
362 }
363
364 /*
365 * Decode command line options.
366 */
367 for (int i = indx; i < args.Length; i ++) {
368 if (args[i] == "-all") {
369 flagAll = true;
370 continue;
371 }
372 if (args[i] == "-help") {
373 m_log.Info ("[XMREngine]: xmr reset -all | <part-of-script-name>");
374 return;
375 }
376 if (args[i][0] == '-') {
377 m_log.Error ("[XMREngine]: unknown option " + args[i] + ", try 'xmr reset -help'");
378 return;
379 }
380 }
381
382 /*
383 * Scan instance list to find those that match selection criteria.
384 */
385 if (!Monitor.TryEnter(m_InstancesDict, 100)) {
386 m_log.Error("[XMREngine]: deadlock m_LockedDict=" + m_LockedDict);
387 return;
388 }
389
390 try {
391 instances = new XMRInstance[m_InstancesDict.Count];
392 foreach (XMRInstance ins in m_InstancesDict.Values) {
393 if (flagAll || InstanceMatchesArgs (ins, args, indx)) {
394 instances[numScripts++] = ins;
395 }
396 }
397 } finally {
398 Monitor.Exit(m_InstancesDict);
399 }
400
401 /*
402 * Reset the instances as if someone clicked their "Reset" button.
403 */
404 for (int i = 0; i < numScripts; i ++) {
405 XMRInstance inst = instances[i];
406 m_log.Info ("[XMREngine]: resetting " + inst.m_DescName);
407 inst.Reset();
408 }
409 }
410
411 private static int CompareInstancesByCPUTime(XMRInstance a, XMRInstance b)
412 {
413 if (a == null) {
414 return (b == null) ? 0 : 1;
415 }
416 if (b == null) {
417 return -1;
418 }
419 if (b.m_CPUTime < a.m_CPUTime) return -1;
420 if (b.m_CPUTime > a.m_CPUTime) return 1;
421 return 0;
422 }
423
424 private void LsQueue(TextWriter outFile, string name, XMRInstQueue queue, string[] args, int indx)
425 {
426 outFile.WriteLine("Queue " + name + ":");
427 lock (queue) {
428 for (XMRInstance inst = queue.PeekHead(); inst != null; inst = inst.m_NextInst) {
429 try {
430
431 /*
432 * Try to print instance name.
433 */
434 if (InstanceMatchesArgs(inst, args, indx)) {
435 outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName);
436 }
437 } catch (Exception e) {
438
439 /*
440 * Sometimes there are instances in the queue that are disposed.
441 */
442 outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName + ": " + e.Message);
443 }
444 }
445 }
446 }
447
448 private bool InstanceMatchesArgs(XMRInstance ins, string[] args, int indx)
449 {
450 bool hadSomethingToCompare = false;
451
452 for (int i = indx; i < args.Length; i ++)
453 {
454 if (args[i][0] != '-') {
455 hadSomethingToCompare = true;
456 if (ins.m_DescName.Contains(args[i])) return true;
457 if (ins.ItemID.ToString().Contains(args[i])) return true;
458 if (ins.AssetID.ToString().Contains(args[i])) return true;
459 }
460 }
461 return !hadSomethingToCompare;
462 }
463 }
464
465 /**
466 * @brief Make m_log.Info look like a text writer.
467 */
468 public class LogInfoTextWriter : TextWriter {
469 private StringBuilder sb = new StringBuilder();
470 private ILog m_log;
471 public LogInfoTextWriter (ILog m_log)
472 {
473 this.m_log = m_log;
474 }
475 public override void Write (char c)
476 {
477 if (c == '\n') {
478 m_log.Info("[XMREngine]: " + sb.ToString());
479 sb.Remove(0, sb.Length);
480 } else {
481 sb.Append(c);
482 }
483 }
484 public override void Close () { }
485 public override Encoding Encoding {
486 get {
487 return Encoding.UTF8;
488 }
489 }
490 }
491}