*DECK TIMER 
USETEXT CCTTEXT 
PROC TIMER(P0,P1,P2); 
          BEGIN 
*CALL ASSEMOP 
          ITEM P0, P1, P2;  # FORMAL PARAMETERS # 
 CONTROL IFEQ CB5$TIMR,"NO";
 $BEGIN 
 CONTROL FI;
  # THIS IS A SET OF ROUTINES WHICHENABLES THE COLLECTION OF
    TIMING INTERVAL STATISTICS. THE ACCUMULATED TIME INTERVALS ARE
    KEPT IN A 50 ENTRY ARRAY. THE FIRST 25 ARE RESERVED FOR THE 
    SUBSYSTEM AND VIRTUAL. THE REST CAN BE USED BY ANYONE. #
  
  ARRAY BOXARRAY[0:50] S(4);
    BEGIN 
      ITEM REALTIMEINT U(0,0,30); 
      ITEM CPUTIMEINT  U(0,30,30); #CPU TIME INTERVAL ACCUMULATED#
      ITEM INTCOUNT U(1,0,60); # NUMBER OF INTERVALS TAKEN #
      ITEM REALSTART   U(2,0,60); # REAL START TIME FOR INTERVAL# 
      ITEM CPUSTART    U(3,0,60); 
    END 
  ITEM I,J,K; # TEMPORARIES#
  ARRAY PHASENAMES[20] S(1);
    ITEM PHASENAME C(0,0,10) = [ "ERROR     ",
                                 "CBINIT    ",
                                 "COPY      ",
                                 "SCANNER   ",
                                 "PICANALYZ ",
                                 "DATABTRAN ",
                                 "DPARSER   ",
                                 "DANALYZER ",
                                 "RPARSER   ",
                                 "RANALYZER ",
                                 "RGEN      ",
                                 "PPARSER   ",
                                 "LPOOLER   ",
                                 "XFORMATTR ",
                                 "PROCTAB   ",
                                 "CGEN      ",
                                 "ASSEMBLER ",
                                 "DFORMATTR ",
                                 "OVERHEAD  ",
                                 "TOTAL     "]; 
  ARRAY PLINE[0:5]; 
     ITEM W C(0,0,10);
  DEF SSP         #1#;
  DEF DBSP        #2#;
  DEF EJECTPAGE   #3#;
  DEF DEFTITLE    #4#;
  DEF DEFSUBTITLE #5#;
  DEF OPENF       #8#;
  DEF CLOSEF      #9#;
  ARRAY GETTIME[0:0] S(2); #USED TO GET CURRENT REAL AND CPU TIME#
    BEGIN 
      ITEM GETREALTIME U(0,0,60); 
      ITEM GETCPUTIME  U(1,0,60); 
    END 
  XREF BEGIN
         PROC STIME; PROC OUTPUT; FUNC DEC C(10); 
         PROC CBLIST; 
       END
  BEGIN 
CONTROL EJECT;
  ENTRY PROC INITTIM(P0,P1,P2); 
    #INITIALIZE BOX P0 WITH REAL TIME P1 AND CPU TIME P2# 
    # IE. SET THE ACCUMULATED TIME TO ITS INITIAL VALUE # 
    REALTIMEINT[P0] = P1; 
    CPUTIMEINT[P0]  = P2; 
    INTCOUNT[P1] = 0; 
    RETURN; 
  
  ENTRY PROC TIMEIN(P1);
    # SAVE THE CPU AND REAL TIME CLOCK VALUES FOR BOX P1, SO
      THAT THE TIME INTERVAL CAN BE CALCULATED.#
    STIME(GETTIME); # GET CPU AND REAL TIME # 
    IF P1 LS 1 OR P1 GR 50 THEN # OUT OF RANGE #
      BEGIN 
        OUTPUT(2," BAD BOX","NUMBER");
        RETURN; 
      END 
  
    REALSTART[P1] = GETREALTIME[0]; 
    CPUSTART[P1]  = GETCPUTIME[0];
    RETURN; 
  
  ENTRY PROC TIMEOUT(P1); 
    # CALCULATE THE TIME INTERVAL FROM THE TIMEIN AND ADD IT TO 
      THE TOTAL IN THE BOX P1#
    STIME(GETTIME); # GET CURRENT TIMES # 
    IF P1 LS 1 OR P1 GR 50 THEN 
      BEGIN 
        OUTPUT(2," BOX NUM.","ERROR");
        RETURN; 
      END 
  
    I = GETREALTIME[0] - REALSTART[P1]; 
    J = GETCPUTIME[0]  - CPUSTART[P1];
    REALTIMEINT[P1] = I + REALTIMEINT[P1];
    CPUTIMEINT[P1] = J + CPUTIMEINT[P1];
    INTCOUNT[P1] = INTCOUNT[P1] + 1;
    RETURN; 
  
  ENTRY PROC SHOWSTATS(P0,P1,P2); 
    # OUTPUT THE STATISTICS ACCUMULATED FOR BOXES P1 THRU P2 IF 
      P0 IS 0 ELSE JUST SHOW STATS FOR BOX P0 # 
    OUTPUT(2," TIMER STA","TISTICS.");
 OUTPUT(5," BOX NUMBR"," REAL TIME"," CPU TIME"," INTERVAL ","COUNT");
    IF P0 NQ 0 THEN 
      BEGIN 
        IF P0 LS 1 OR P0 GR 50 THEN OUTPUT(2,"BAD BOX=",DEC(P0)); 
        ELSE
        OUTPUT(5,DEC(P0),DEC(REALTIMEINT[P0]),DEC(CPUTIMEINT[P0])," ",
                         DEC(INTCOUNT[P0]) ); 
      END 
    ELSE
      BEGIN 
        IF P1 LS 1 OR P2 GR 50 THEN OUTPUT(3,"BAD RANGE",DEC(P1), 
                                              DEC(P2)); 
        ELSE
          BEGIN 
          FOR I = P1 STEP 1 UNTIL P2 DO 
               OUTPUT(5,DEC(I),DEC(REALTIMEINT[I]), 
                           DEC(CPUTIMEINT[I])," ",DEC(INTCOUNT[I]));
          END 
      END 
    END 
ENTRY PROC TREPORT; 
          IF NOT CCTTIMRPT THEN RETURN; 
  CBLIST(DEFSUBTITLE,"   ****  COMPILER TIMING REPORT  ****",38); 
  CBLIST(EJECTPAGE);
  CBLIST(SSP,"PHASE     CPU TIME  PERCENT   REAL TIME PERCENT   ",50);
  FOR I = 1 STEP 1 UNTIL 17 DO
      BEGIN 
      REALTIMEINT[20] = REALTIMEINT[20] + REALTIMEINT[I]; 
      CPUTIMEINT[20] = CPUTIMEINT[20] + CPUTIMEINT[I];
      END 
  REALTIMEINT[18] = REALTIMEINT[19] - REALTIMEINT[20];
  CPUTIMEINT[18] = CPUTIMEINT[19] - CPUTIMEINT[20]; 
  FOR I = 1 STEP 1 UNTIL 19 DO
      BEGIN 
      W[0] = PHASENAME[I];
      W[1] = DEC(CPUTIMEINT[I]);
      W[2] = DEC((CPUTIMEINT[I]*100)/CPUTIMEINT[19]); 
      W[3] = DEC(REALTIMEINT[I]); 
      W[4] = DEC((REALTIMEINT[I]*100)/REALTIMEINT[19]); 
      CBLIST(DBSP,PLINE,50);
      END 
  W[0] = "     CARDS";
  W[1] = " PER CPU M";
  W[2] = "INUTE  =  ";
  W[3] = DEC((CCTLASTLINE*60000)/CPUTIMEINT[19]); 
  CBLIST(DBSP,PLINE,40);
  CBLIST(DBSP,"    ****  END TIMING REPORT  ****",33);
  CBLIST(DEFSUBTITLE," ",1);
 CONTROL IFEQ CB5$TIMR,"NO";
 $END 
 CONTROL FI;
          END 
TERM
