aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs578
1 files changed, 578 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs
new file mode 100644
index 0000000..6b752bd
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs
@@ -0,0 +1,578 @@
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.Yengine
45{
46 public partial class Yengine
47 {
48
49 private void XmrTestLs(string[] args, int indx)
50 {
51 bool flagFull = false;
52 bool flagQueues = false;
53 bool flagTopCPU = false;
54 int maxScripts = 0x7FFFFFFF;
55 int numScripts = 0;
56 string outName = null;
57 XMRInstance[] instances;
58
59 /*
60 * Decode command line options.
61 */
62 for(int i = indx; i < args.Length; i++)
63 {
64 if(args[i] == "-full")
65 {
66 flagFull = true;
67 continue;
68 }
69 if(args[i] == "-help")
70 {
71 m_log.Info("[YEngine]: xmr ls -full -max=<number> -out=<filename> -queues -topcpu");
72 return;
73 }
74 if(args[i].StartsWith("-max="))
75 {
76 try
77 {
78 maxScripts = Convert.ToInt32(args[i].Substring(5));
79 }
80 catch(Exception e)
81 {
82 m_log.Error("[YEngine]: bad max " + args[i].Substring(5) + ": " + e.Message);
83 return;
84 }
85 continue;
86 }
87 if(args[i].StartsWith("-out="))
88 {
89 outName = args[i].Substring(5);
90 continue;
91 }
92 if(args[i] == "-queues")
93 {
94 flagQueues = true;
95 continue;
96 }
97 if(args[i] == "-topcpu")
98 {
99 flagTopCPU = true;
100 continue;
101 }
102 if(args[i][0] == '-')
103 {
104 m_log.Error("[YEngine]: unknown option " + args[i] + ", try 'xmr ls -help'");
105 return;
106 }
107 }
108
109 TextWriter outFile = null;
110 if(outName != null)
111 {
112 try
113 {
114 outFile = File.CreateText(outName);
115 }
116 catch(Exception e)
117 {
118 m_log.Error("[YEngine]: error creating " + outName + ": " + e.Message);
119 return;
120 }
121 }
122 else
123 {
124 outFile = new LogInfoTextWriter(m_log);
125 }
126
127 try
128 {
129
130 /*
131 * Scan instance list to find those that match selection criteria.
132 */
133 if(!Monitor.TryEnter(m_InstancesDict, 100))
134 {
135 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
136 return;
137 }
138 try
139 {
140 instances = new XMRInstance[m_InstancesDict.Count];
141 foreach(XMRInstance ins in m_InstancesDict.Values)
142 {
143 if(InstanceMatchesArgs(ins, args, indx))
144 {
145 instances[numScripts++] = ins;
146 }
147 }
148 }
149 finally
150 {
151 Monitor.Exit(m_InstancesDict);
152 }
153
154 /*
155 * Maybe sort by descending CPU time.
156 */
157 if(flagTopCPU)
158 {
159 Array.Sort<XMRInstance>(instances, CompareInstancesByCPUTime);
160 }
161
162 /*
163 * Print the entries.
164 */
165 if(!flagFull)
166 {
167 outFile.WriteLine(" ItemID" +
168 " CPU(ms)" +
169 " NumEvents" +
170 " Status " +
171 " World Position " +
172 " <Part>:<Item>");
173 }
174 for(int i = 0; (i < numScripts) && (i < maxScripts); i++)
175 {
176 outFile.WriteLine(instances[i].RunTestLs(flagFull));
177 }
178
179 /*
180 * Print number of scripts that match selection criteria,
181 * even if we were told to print fewer.
182 */
183 outFile.WriteLine("total of {0} script(s)", numScripts);
184
185 /*
186 * If -queues given, print out queue contents too.
187 */
188 if(flagQueues)
189 {
190 LsQueue(outFile, "start", m_StartQueue, args, indx);
191 LsQueue(outFile, "sleep", m_SleepQueue, args, indx);
192 LsQueue(outFile, "yield", m_YieldQueue, args, indx);
193 }
194 }
195 finally
196 {
197 outFile.Close();
198 }
199 }
200
201 private void XmrTestPev(string[] args, int indx)
202 {
203 bool flagAll = false;
204 int numScripts = 0;
205 XMRInstance[] instances;
206
207 /*
208 * Decode command line options.
209 */
210 int i, j;
211 List<string> selargs = new List<string>(args.Length);
212 MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods();
213 MethodInfo eventmethod;
214 for(i = indx; i < args.Length; i++)
215 {
216 string arg = args[i];
217 if(arg == "-all")
218 {
219 flagAll = true;
220 continue;
221 }
222 if(arg == "-help")
223 {
224 m_log.Info("[YEngine]: xmr pev -all | <part-of-script-name> <event-name> <params...>");
225 return;
226 }
227 if(arg[0] == '-')
228 {
229 m_log.Error("[YEngine]: unknown option " + arg + ", try 'xmr pev -help'");
230 return;
231 }
232 for(j = 0; j < eventmethods.Length; j++)
233 {
234 eventmethod = eventmethods[j];
235 if(eventmethod.Name == arg)
236 goto gotevent;
237 }
238 selargs.Add(arg);
239 }
240 m_log.Error("[YEngine]: missing <event-name> <params...>, try 'xmr pev -help'");
241 return;
242 gotevent:
243 string eventname = eventmethod.Name;
244 StringBuilder sourcesb = new StringBuilder();
245 while(++i < args.Length)
246 {
247 sourcesb.Append(' ');
248 sourcesb.Append(args[i]);
249 }
250 string sourcest = sourcesb.ToString();
251 string sourcehash;
252 youveanerror = false;
253 Token t = TokenBegin.Construct("", null, ErrorMsg, sourcest, out sourcehash);
254 if(youveanerror)
255 return;
256 ParameterInfo[] paraminfos = eventmethod.GetParameters();
257 object[] paramvalues = new object[paraminfos.Length];
258 i = 0;
259 while(!((t = t.nextToken) is TokenEnd))
260 {
261 if(i >= paramvalues.Length)
262 {
263 ErrorMsg(t, "extra parameter(s)");
264 return;
265 }
266 paramvalues[i] = ParseParamValue(ref t);
267 if(paramvalues[i] == null)
268 return;
269 i++;
270 }
271 OpenSim.Region.ScriptEngine.Shared.EventParams eps =
272 new OpenSim.Region.ScriptEngine.Shared.EventParams(eventname, paramvalues, zeroDetectParams);
273
274 /*
275 * Scan instance list to find those that match selection criteria.
276 */
277 if(!Monitor.TryEnter(m_InstancesDict, 100))
278 {
279 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
280 return;
281 }
282
283 try
284 {
285 instances = new XMRInstance[m_InstancesDict.Count];
286 foreach(XMRInstance ins in m_InstancesDict.Values)
287 {
288 if(flagAll || InstanceMatchesArgs(ins, selargs.ToArray(), 0))
289 {
290 instances[numScripts++] = ins;
291 }
292 }
293 }
294 finally
295 {
296 Monitor.Exit(m_InstancesDict);
297 }
298
299 /*
300 * Post event to the matching instances.
301 */
302 for(i = 0; i < numScripts; i++)
303 {
304 XMRInstance inst = instances[i];
305 m_log.Info("[YEngine]: post " + eventname + " to " + inst.m_DescName);
306 inst.PostEvent(eps);
307 }
308 }
309
310 private object ParseParamValue(ref Token token)
311 {
312 if(token is TokenFloat)
313 {
314 return new LSL_Float(((TokenFloat)token).val);
315 }
316 if(token is TokenInt)
317 {
318 return new LSL_Integer(((TokenInt)token).val);
319 }
320 if(token is TokenStr)
321 {
322 return new LSL_String(((TokenStr)token).val);
323 }
324 if(token is TokenKwCmpLT)
325 {
326 List<double> valuelist = new List<double>();
327 while(!((token = token.nextToken) is TokenKwCmpGT))
328 {
329 if(!(token is TokenKwComma))
330 {
331 object value = ParseParamValue(ref token);
332 if(value == null)
333 return null;
334 if(value is int)
335 value = (double)(int)value;
336 if(!(value is double))
337 {
338 ErrorMsg(token, "must be float or integer constant");
339 return null;
340 }
341 valuelist.Add((double)value);
342 }
343 else if(token.prevToken is TokenKwComma)
344 {
345 ErrorMsg(token, "missing constant");
346 return null;
347 }
348 }
349 double[] values = valuelist.ToArray();
350 switch(values.Length)
351 {
352 case 3:
353 {
354 return new LSL_Vector(values[0], values[1], values[2]);
355 }
356 case 4:
357 {
358 return new LSL_Rotation(values[0], values[1], values[2], values[3]);
359 }
360 default:
361 {
362 ErrorMsg(token, "not rotation or vector");
363 return null;
364 }
365 }
366 }
367 if(token is TokenKwBrkOpen)
368 {
369 List<object> valuelist = new List<object>();
370 while(!((token = token.nextToken) is TokenKwBrkClose))
371 {
372 if(!(token is TokenKwComma))
373 {
374 object value = ParseParamValue(ref token);
375 if(value == null)
376 return null;
377 valuelist.Add(value);
378 }
379 else if(token.prevToken is TokenKwComma)
380 {
381 ErrorMsg(token, "missing constant");
382 return null;
383 }
384 }
385 return new LSL_List(valuelist.ToArray());
386 }
387 if(token is TokenName)
388 {
389 FieldInfo field = typeof(OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass).GetField(((TokenName)token).val);
390 if((field != null) && field.IsPublic && (field.IsLiteral || (field.IsStatic && field.IsInitOnly)))
391 {
392 return field.GetValue(null);
393 }
394 }
395 ErrorMsg(token, "invalid constant");
396 return null;
397 }
398
399 private bool youveanerror;
400 private void ErrorMsg(Token token, string message)
401 {
402 youveanerror = true;
403 m_log.Info("[YEngine]: " + token.posn + " " + message);
404 }
405
406 private void XmrTestReset(string[] args, int indx)
407 {
408 bool flagAll = false;
409 int numScripts = 0;
410 XMRInstance[] instances;
411
412 if(args.Length <= indx)
413 {
414 m_log.Error("[YEngine]: must specify part of script name or -all for all scripts");
415 return;
416 }
417
418 /*
419 * Decode command line options.
420 */
421 for(int i = indx; i < args.Length; i++)
422 {
423 if(args[i] == "-all")
424 {
425 flagAll = true;
426 continue;
427 }
428 if(args[i] == "-help")
429 {
430 m_log.Info("[YEngine]: xmr reset -all | <part-of-script-name>");
431 return;
432 }
433 if(args[i][0] == '-')
434 {
435 m_log.Error("[YEngine]: unknown option " + args[i] + ", try 'xmr reset -help'");
436 return;
437 }
438 }
439
440 /*
441 * Scan instance list to find those that match selection criteria.
442 */
443 if(!Monitor.TryEnter(m_InstancesDict, 100))
444 {
445 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
446 return;
447 }
448
449 try
450 {
451 instances = new XMRInstance[m_InstancesDict.Count];
452 foreach(XMRInstance ins in m_InstancesDict.Values)
453 {
454 if(flagAll || InstanceMatchesArgs(ins, args, indx))
455 {
456 instances[numScripts++] = ins;
457 }
458 }
459 }
460 finally
461 {
462 Monitor.Exit(m_InstancesDict);
463 }
464
465 /*
466 * Reset the instances as if someone clicked their "Reset" button.
467 */
468 for(int i = 0; i < numScripts; i++)
469 {
470 XMRInstance inst = instances[i];
471 m_log.Info("[YEngine]: resetting " + inst.m_DescName);
472 inst.Reset();
473 }
474 }
475
476 private static int CompareInstancesByCPUTime(XMRInstance a, XMRInstance b)
477 {
478 if(a == null)
479 {
480 return (b == null) ? 0 : 1;
481 }
482 if(b == null)
483 {
484 return -1;
485 }
486 if(b.m_CPUTime < a.m_CPUTime)
487 return -1;
488 if(b.m_CPUTime > a.m_CPUTime)
489 return 1;
490 return 0;
491 }
492
493 private void LsQueue(TextWriter outFile, string name, XMRInstQueue queue, string[] args, int indx)
494 {
495 outFile.WriteLine("Queue " + name + ":");
496 lock(queue)
497 {
498 for(XMRInstance inst = queue.PeekHead(); inst != null; inst = inst.m_NextInst)
499 {
500 try
501 {
502
503 /*
504 * Try to print instance name.
505 */
506 if(InstanceMatchesArgs(inst, args, indx))
507 {
508 outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName);
509 }
510 }
511 catch(Exception e)
512 {
513
514 /*
515 * Sometimes there are instances in the queue that are disposed.
516 */
517 outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName + ": " + e.Message);
518 }
519 }
520 }
521 }
522
523 private bool InstanceMatchesArgs(XMRInstance ins, string[] args, int indx)
524 {
525 bool hadSomethingToCompare = false;
526
527 for(int i = indx; i < args.Length; i++)
528 {
529 if(args[i][0] != '-')
530 {
531 hadSomethingToCompare = true;
532 if(ins.m_DescName.Contains(args[i]))
533 return true;
534 if(ins.ItemID.ToString().Contains(args[i]))
535 return true;
536 if(ins.AssetID.ToString().Contains(args[i]))
537 return true;
538 }
539 }
540 return !hadSomethingToCompare;
541 }
542 }
543
544 /**
545 * @brief Make m_log.Info look like a text writer.
546 */
547 public class LogInfoTextWriter: TextWriter
548 {
549 private StringBuilder sb = new StringBuilder();
550 private ILog m_log;
551 public LogInfoTextWriter(ILog m_log)
552 {
553 this.m_log = m_log;
554 }
555 public override void Write(char c)
556 {
557 if(c == '\n')
558 {
559 m_log.Info("[YEngine]: " + sb.ToString());
560 sb.Remove(0, sb.Length);
561 }
562 else
563 {
564 sb.Append(c);
565 }
566 }
567 public override void Close()
568 {
569 }
570 public override Encoding Encoding
571 {
572 get
573 {
574 return Encoding.UTF8;
575 }
576 }
577 }
578}