home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 620.lha / TP / TP.mod < prev    next >
Text File  |  1992-03-08  |  5KB  |  199 lines

  1. (*---------------------------------------------------------------------------
  2.     :Program.    TP.mod
  3.     :Author.     Fridtjof Siebert
  4.     :Address.    Nobileweg 67, D-7000-Stuttgart-40
  5.     :Shortcut.   [fbs]
  6.     :History.    V1.0, 07-Mar-92, [fbs], first public version
  7.     :Copyright.  FD
  8.     :Language.   Oberon
  9.     :Translator. Amiga Oberon V2.30 (internal version)
  10.     :Contents.   Programm zur statistischen Analyse des Rechenzeitbedarfs
  11.     :Contents.   aller laufenden Tasks.
  12.     :Usage.      SECS/N
  13.     :Usage.      Der Parameter gibt die Anzahl der Sekunden an, die TP
  14.     :Usage.      das System untersuchen soll. Je größer dieser Wert ist,
  15.     :Usage.      desto genauer werden die ausgegebenen Werte.
  16. ---------------------------------------------------------------------------*)
  17.  
  18. (* $IFNOT SmallData  (SmallData will fail!) *)
  19.  
  20. MODULE TP;
  21.  
  22. IMPORT Dos, Exec, Strings, Hardware;
  23.  
  24. CONST
  25.   TaskArraySize = 100;
  26.  
  27. VAR
  28.   tasks: ARRAY TaskArraySize OF STRUCT
  29.            task: Exec.TaskPtr;
  30.            name: ARRAY 256-12 OF CHAR;
  31.            cnt: LONGINT;
  32.            cnt2: LONGINT;
  33.          END;
  34.  
  35.   VertBIntr: Exec.InterruptPtr;  (* Meine Interrupt-Struktur         *)
  36.  
  37.   Count,Max,secs: LONGINT;
  38.   numtasks: LONGINT;
  39.  
  40.   i: LONGINT;
  41.  
  42.   arga: ARRAY 1 OF Exec.APTR;
  43.   liPtr: UNTRACED POINTER TO LONGINT;
  44.   args: Dos.RDArgsPtr;
  45.  
  46.   Me : Exec.TaskPtr;
  47.  
  48.   string: Exec.STRING;
  49.  
  50.   acc,getacc: LONGINT;
  51.  
  52.  
  53. PROCEDURE MyIntProc(); (* $SaveRegs+ $StackChk- *)
  54.  
  55. BEGIN
  56.  
  57.   i := 0;
  58.   WHILE i<numtasks DO
  59.     IF tasks[i].task=Exec.exec.thisTask THEN
  60.       INC(tasks[i].cnt);
  61.       i := numtasks
  62.     END;
  63.     INC(i);
  64.   END;
  65.  
  66.   INC(Count);
  67.  
  68.   IF Count=Max DIV 2 THEN
  69.     FOR i:=0 TO numtasks-1 DO
  70.       tasks[i].cnt2 := tasks[i].cnt;
  71.     END;
  72.   END;
  73.  
  74.   IF Count=Max THEN Exec.Signal(Me,LONGSET{Dos.ctrlC}) END;
  75.  
  76. END MyIntProc; (* $StackChk= *)
  77.  
  78.  
  79. PROCEDURE PrintPerCent(n: LONGINT);
  80. BEGIN
  81. (*
  82.  * I do not know, how to do this better. Suggestions?
  83.  *)
  84.   Dos.PrintF("%ld%ld.%ld%ld %% ",n DIV 1000       ,
  85.                                  n DIV 100  MOD 10,
  86.                                  n DIV 10   MOD 10,
  87.                                  n          MOD 10);
  88. END PrintPerCent;
  89.  
  90.  
  91. PROCEDURE GetTasks(task: Exec.TaskPtr);
  92. BEGIN
  93.   WHILE (task.node.succ#NIL) AND (numtasks<TaskArraySize) DO
  94.     tasks[numtasks].task := task;
  95.     IF task.node.name = NIL THEN
  96.       tasks[numtasks].name := "unnamed";
  97.     ELSE
  98.       COPY(task.node.name^,tasks[numtasks].name);
  99.     END;
  100.     IF (Exec.process = task.node.type) AND (task(Dos.Process).cli#NIL) THEN
  101.       Strings.Append(tasks[numtasks].name,": ");
  102.       COPY(task(Dos.Process).cli.commandName^,string);
  103.       string[ORD(string[0])+1] := 0X;
  104.       Strings.Delete(string,0,1);
  105.       Strings.Append(tasks[numtasks].name,string);
  106.     END;
  107.     task := task.node.succ;
  108.     INC(numtasks);
  109.   END;
  110. END GetTasks;
  111.  
  112.  
  113. BEGIN
  114.  
  115.   IF Dos.dos.lib.version<37 THEN HALT(20) END;
  116.  
  117.   args := Dos.ReadArgs("SECS/N",arga,NIL);
  118.  
  119.   IF args=NIL THEN
  120.  
  121.     IF Dos.PrintFault(Dos.IoErr(),NIL) THEN END;
  122.  
  123.   ELSE
  124.  
  125.     secs := 10;
  126.     liPtr := arga[0];
  127.     IF (liPtr#NIL) AND (liPtr^>0) THEN
  128.       secs := liPtr^;
  129.     END;
  130.     Max := secs * LONG(Exec.exec.vblankFrequency);
  131.  
  132.     Exec.Forbid;
  133.       numtasks := 0;
  134.       GetTasks(Exec.exec.taskReady.head);
  135.       GetTasks(Exec.exec.taskWait .head);
  136.     Exec.Permit;
  137.  
  138.     Me := Exec.exec.thisTask;
  139.  
  140.     NEW(VertBIntr);
  141.   
  142.     IF VertBIntr=NIL THEN HALT(20) END;
  143.   
  144.     VertBIntr.node.type := Exec.interrupt; (* Typ ist Interrupt                *)
  145.     VertBIntr.code := MyIntProc;           (* InterruptProzedur                *)
  146.  
  147.     Dos.PrintF("TP © 1992 by Fridtjof Siebert -- Freely Distributable\n\n"
  148.                "Checking (%ld seconds)...\n\n",secs);
  149.  
  150.   (* Add interrupt and wait for ^C or secs *)
  151.  
  152.     Exec.AddIntServer(Hardware.vertb,VertBIntr);
  153.  
  154.     IF Exec.Wait(LONGSET{Dos.ctrlC})#LONGSET{} THEN END;
  155.  
  156.     Exec.RemIntServer(Hardware.vertb,VertBIntr);
  157.  
  158.     IF Count=Max THEN
  159.  
  160.   (* print cpu-usage percentages: *)
  161.  
  162.       FOR i := 0 TO numtasks-1 DO
  163.         IF tasks[i].cnt#0 THEN
  164.           PrintPerCent(tasks[i].cnt * 10000 DIV Count);
  165.           Dos.PrintF(tasks[i].name);
  166.           Dos.PrintF("\n");
  167.         END;
  168.       END;
  169.   
  170.   (* acc := sqrt( sum[i=0..numtasks-1] ((tasks[i].cnt - 2*tasks[i].cnt2) ^ 2) ) *)
  171.  
  172.       getacc := 0;
  173.       FOR i := 0 TO numtasks-1 DO
  174.         acc := tasks[i].cnt - 2*tasks[i].cnt2;
  175.         INC(getacc,acc * acc);
  176.       END;
  177.   
  178.       acc := 1;                     (* simple integer sqrt(): *)
  179.       REPEAT
  180.         acc := (acc + getacc DIV acc) DIV 2;
  181.       UNTIL (acc*acc<=getacc) AND ((acc+1)*(acc+1)>getacc);
  182.   
  183.       Dos.PrintF("\naccuracy: ");
  184.       PrintPerCent(acc * 10000 DIV Count);
  185.  
  186.     ELSE   (* IF Count=Max THEN ... *)
  187.  
  188.       Dos.PrintF("*** Break.");
  189.  
  190.     END;   (* IF Count=Max THEN ... ELSE ... *)
  191.  
  192.     Dos.PrintF("\n\nbye.\n");
  193.  
  194.   END;   (* IF args=NIL THEN ... ELSE ... *)
  195.  
  196. END TP.
  197. (* $END *)
  198.  
  199.