*DECK DB$ACM1 
USETEXT CDCSCTX 
      PROC DB$ACM1  ; 
 #
* *   DB$ACM1  TERMINATE MESSAGE FOR ACCOUNTING  PAGE  1
* *       R.C.KLOENNE                            2/11/77
* *       W.R. SMITH                             10/09/80 
* * 
* * 
* DC  PURPOSE 
* 
*     FORMAT ACCOUNT MESSAGES FOR CDCS SCP TERMINATION
* 
* DC  ENTRY CONDITIONS
* 
*     CDCSRCP AND CDCSRIO CONTAIN CDCS-S STARTING CP AND IO TIMES.
*     DB$NOS IS TRUE IF ON THE NOS OPERATING SYSTEM.
* 
* DC  EXIT CONDITIONS 
* 
*     THREE DAYFILE MESSAGES ARE GENERATED. FORMATS ARE:  
*          1. "CDCS CHARGED XXXXXX.XXX CP SECONDS       " 
*             "             YYYYYY.YYY IO SECONDS.      " 
*          2. "CDCS USED    XXXXXX.XXX CP SECONDS       " 
*             "             YYYYYY.YYY IO SECONDS.      " 
*          3. CDCS ZZ.ZZ PER CENT CPU USAGE.
* 
* DC  CALLING ROUTINES
* 
*     DB$RCVR    REPRIEVE PROCESSOR 
*     DB$TERM    CDCS TERMINATION ROUTINE 
* 
* DC  CALLED  ROUTINES
* 
# 
      XREF FUNC DB$CDEB C(10);  # INTEGER TO BLANK FILLED DECIMAL      #
      XREF FUNC DB$CDEC C(10);  # INTEGER TO ZERO FILLED DECIMAL       #
      XREF FUNC MOD I;       # FTN MODULUS FUNCTION                    #
      XREF PROC DB$FLOP;     # GENERATE FLOW POINT                     #
      XREF PROC DB$MSG  ;    # OUTPUT MESSAGE TO DAYFILE               #
      XREF PROC DB$CPT ;  # GET CP TIME                                #
      XREF PROC DB$IOT ;  # GET IO TIME                                #
      XREF PROC DB$NCPT;  # GET CP TIME FOR NOS                        #
      XREF PROC DB$NIOT;  # GET IO TIME FOR NOS                        #
      XREF PROC DB$NCLK;  # GET REAL TIME CLOCK FOR NOS                #
      XREF ITEM DB$NOS B; # TRUE IF NOS OPERATING SYSTEM               #
# 
* 
* DC  NON-LOCAL VARIABLES MODIFIED
* 
*     CDCSRCP 
*     CDCSRIO 
* 
* DC  DESCRIPTION 
* 
*     DB$ACM1 DIRECTS THE WRITING OF THE CDCS DAYFILE 
*     MESSAGES THAT SHOW HOW MUCH TIME WAS CHARGED TO USERS, AND HOW
*     MUCH TIME WAS ACTUALLY USED BY CDCS.
*     ALSO, CPU UTILIZATION FIGURE WILL BE REPORTED ON NOS. 
* 
 #
      BEGIN 
      CONTROL EJECT;
  
# 
      LOCAL  VARIABLES
# 
      ARRAY TEMPTIMES S(2); 
        BEGIN 
        ITEM TEMPCP       I(0,00,60); 
        ITEM TEMPCPSEC    U(0,24,24); 
        ITEM TEMPCPMIL    U(0,48,12); 
        ITEM TEMPIO       I(1,00,60); 
        ITEM TEMPIOSEC    U(1,24,24); 
        ITEM TEMPIOMIL    U(1,48,12); 
        END 
  
      ARRAY ACCMSG S(4);
        BEGIN 
        ITEM ACCMSG1  C(0,00,15) = ["  CDCS CHARGED "]; 
        ITEM ACCMSG1A C(0,42,07);  # TO CHANGE "CHARGED" TO "USED"     #
        ITEM ACCMSG2  C(1,30,06);  # CP SECONDS                        #
        ITEM ACCMSG3  C(2,06,01) = ["."]; 
        ITEM ACCMSG4  C(2,12,03);  # CP MILLISECONDS                   #
        ITEM ACCMSG5  C(2,30,15) = [" CP SECONDS   :"]; 
        END 
  
      ARRAY IOMSG S(4); 
        BEGIN 
        ITEM IOMSG1  C(0,00,15) = ["               "];
        ITEM IOMSG2  C(1,30,06);  # IO SECONDS                         #
        ITEM IOMSG3  C(2,06,01) = ["."];
        ITEM IOMSG4  C(2,12,03);  # IO MILLISECONDS                    #
        ITEM IOMSG5  C(2,30,13) = [" IO SECONDS.:"];
        END 
  
      ARRAY CPUUTIL S(4);        # CPU UTILIZATION MESSAGE TEXT        #
        BEGIN 
        ITEM CPUUTIL1 C(0,00,07) = ["  CDCS "]; 
        ITEM CPUUTIL2 C(0,42,02);  # PER CENT CPU USAGE                #
        ITEM CPUUTIL3 C(0,54,01) = ["."]; 
        ITEM CPUUTIL4 C(1,00,02);  # PER CENT CPU USAGE (HUNDREDTHS)   #
        ITEM CPUUTIL5 C(1,12,21) = [" PER CENT CPU USAGE.:"]; 
        END 
      BASED ARRAY ACCNO S(1) ;
        BEGIN 
        ITEM ACCSEC  U(0,24,24);
        ITEM ACCMIL  U(0,48,12);
        END 
  
      ITEM CPUSED I;          # CP TIME USED BY CDCS (MS)              #
      ITEM INITCPSEC I;       # INITIAL CP SECONDS                     #
      ITEM INITCPMIL I;       # INITIAL CP MILLISECONDS                #
      ITEM INITIOSEC I;       # INITIAL IO SECONDS                     #
      ITEM INITIOMIL I;       # INITIAL IO MILLISECONDS                #
      ITEM TEMP I;            # TEMPORARY WORK AREA                    #
      ITEM TEMPUSAGE I;       # CPU USAGE WORK AREA                    #
      CONTROL EJECT;
  
 #
*     RETURN IF NO ACCOUNTING.
 #
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("ACM1   "); 
      CONTROL ENDIF;
  
      IF NOT ACCNFLAG THEN
        RETURN; 
  
#     CALCULATE TIMES, FORMAT MESSAGE, AND WRITE "CHARGED" MESSAGE     #
#     TO DAYFILE.                                                      #
  
#     CDCSCP AND CDCSIO CONTAIN THE TOTAL TIMES CHARGED TO THE UCP-S,  #
#     IN MICROSECONDS.                                                 #
  
      TEMPCPSEC[0] = CDCSCP / 1000000;  # CP TIME CHARGED              #
      TEMPCPMIL[0] = MOD((CDCSCP/1000),1000); 
      ACCMSG2[0] = DB$CDEB(TEMPCPSEC[0],6); 
      ACCMSG4[0] = DB$CDEC(TEMPCPMIL[0],3); 
  
      TEMPIOSEC[0] = CDCSIO / 1000000;  # IO TIME CHARGED              #
      TEMPIOMIL[0] = MOD((CDCSIO/1000),1000); 
      IOMSG2[0] = DB$CDEB(TEMPIOSEC[0],6);
      IOMSG4[0] = DB$CDEC(TEMPIOMIL[0],3);
      DB$MSG(ACCMSG); 
      DB$MSG(IOMSG);
  
#     SAVE START TIMES                                                 #
  
      P<ACCNO> = LOC(CDCSRCP);
      INITCPSEC = ACCSEC[0];
      INITCPMIL = ACCMIL[0];
      P<ACCNO> = LOC(CDCSRIO);
      INITIOSEC = ACCSEC[0];
      INITIOMIL = ACCMIL[0];
  
#     GET CDCS END TIMES                                               #
  
      DB$CPT(LOC(CDCSRCP)); 
      DB$IOT(LOC(CDCSRIO)); 
      IF DB$NOS              # TRUE IF ON NOS OPERATING SYSTEM         #
      THEN                   # GET TIMES FROM NOS ROUTINES             #
        BEGIN 
        DB$NCPT(LOC(CDCSRCP));
        DB$NIOT(LOC(CDCSRIO));
        END 
      CONTROL EJECT;
  
#      CALCULATE TIMES, FORMAT MESSAGE, AND WRITE "USED" MESSAGE       #
#     TO DAYFILE.                                                      #
  
      P<ACCNO> = LOC(CDCSRCP);     # CP TIME USED                      #
      TEMPCPSEC[0] = ACCSEC[0]; 
      TEMPCPMIL[0] = ACCMIL[0]; 
      TEMP = TEMPCPSEC[0] * 1000 + TEMPCPMIL[0];
      CPUSED = TEMP - (INITCPSEC * 1000 + INITCPMIL); 
      TEMPCPSEC[0] = CPUSED / 1000; 
      TEMPCPMIL[0] = CPUSED - (TEMPCPSEC[0] * 1000);
      ACCMSG2[0] = DB$CDEB(TEMPCPSEC[0],6); 
      ACCMSG4[0] = DB$CDEC(TEMPCPMIL[0],3); 
  
      P<ACCNO> = LOC(CDCSRIO);     # IO TIME USED                      #
      TEMPIOSEC[0] = ACCSEC[0]; 
      TEMPIOMIL[0] = ACCMIL[0]; 
      TEMP = TEMPIOSEC[0] * 1000 + TEMPIOMIL[0];
      TEMP = TEMP - (INITIOSEC * 1000 + INITIOMIL); 
      TEMPIOSEC[0] = TEMP / 1000; 
      TEMPIOMIL[0] = TEMP - (TEMPIOSEC[0] * 1000);
      IOMSG2[0] = DB$CDEB(TEMPIOSEC[0],6);
      IOMSG4[0] = DB$CDEC(TEMPIOMIL[0],3);
      ACCMSG1A[0] = "USED   ";
  
      DB$MSG(ACCMSG); 
      DB$MSG(IOMSG);
  
      IF DB$NOS              # TRUE IF ON NOS OPERATING SYSTEM         #
      THEN
        BEGIN 
  
#       PRINT THE CPU UTILIZATION FIGURE                               #
#       CPU UTILIZATION = REAL TIME USED / CP TIME USED                #
  
        DB$NCLK(LOC(TEMPIO));  # GET CLOCK TIME IN MILLISEC. IN TEMPIO #
        P<ACCNO> = LOC(CDCSRCP);
  
#       COMPUTE CP UTILIZATION WITH THE FOLLOWING EQUATION             #
#                                                                      #
#         CP UTILIZATION = CP TIME (MS) * 10000 / REAL ELAPSED TIME(MS)#
#                                                                      #
#       THE FOUR DIGIT INTEGER RESULT REPRESENTS THE RATIO OF CPTIME   #
#       TO REAL ELAPSED TIME WITH FOUR DIGIT PRECISION.  IF THE VALUE  #
#       OF THE INTEGER WERE NNNN THE LOGICAL VALUE OF THE NUMBER WOULD #
#       BE NNNN * 10**-4 (I.E. THERE IS AN ASSUMED DECIMAL POINT).     #
#       SINCE THE CPU UTILIZATION FIGURE WHICH IS WRITTEN TO THE       #
#       CDCS DAYFILE IS OF THE FORM XX.YY PERCENT THE FOUR DIGIT       #
#       INTEGER IS DIVIDED BY 100 AND THE RESULTANT TWO DIGIT          #
#       INTEGER IS REPRESENTATIVE OF THE XX PORTION OF THE XX.YY       #
#       FIGURE REPRESENTING PERCENT CPU USAGE.  THIS RESULTANT TWO     #
#       DIGIT INTEGER IS THEN MULTIPLIED BY 100 AND SUBTRACTED FROM    #
#       THE ORIGINAL FOUR DIGIT INTEGER PREVIOUSLY CALCULATED.  THE    #
#       RESULT OF THIS CALCULATION IS A TWO DIGIT INTEGER WHICH IS     #
#       REPRESENTATIVE OF THE YY OR HUNDREDTHS OF A PERCENT PORTION    #
#       OF THE XX.YY FIGURE REPRESENTING CPU USAGE.                    #
#                                                                      #
        TEMP = CPUSED * 10000/TEMPIO; 
        TEMPUSAGE = TEMP/100; 
        CPUUTIL2[0] = DB$CDEB(TEMPUSAGE,2); 
        TEMPUSAGE = TEMP-TEMPUSAGE*100; 
        CPUUTIL4[0] = DB$CDEC(TEMPUSAGE,2); 
        DB$MSG(CPUUTIL);
        END 
      END         # DB$ACM1 # 
  
      TERM
