C C CPU UTILIZATION vs TIME OF DAY PLOT ROUTINE C C NAME OF ROUTINE: UPLOT C C REV DATE AUTHOR REASON C +-------+------------+---------------------+------------------------------+ C 1.0 12/10/80 NOEL CARBONI INITIAL ENTRY C 1.1 4/29/81 NOEL CARBONI WON'T RE-PROMPT IF NO DATA FND C C C PROGRAM USAGE: C C THIS PROGRAM WILL PRINT A LABELED HISTOGRAM OF SYSTEM CPU UTILIZATION C AND PRINT THE STATISTICS FOR THE FOUR HIGHEST UTILIZATION PERIODS C C CALLING SEQUENCE: (ASSUMING UPL IS INSTALLED) C C >UPL C > C ENTER DATE: 12/10/80 C C AT THIS POINT THE HISTOGRAM WILL BE IN 'UPLOT.RPT' C C C C FILES USED: C C OUTPUT IS IN 'UPLOT.RPT' - UNIT 1 C C PROGRAM UPLOT IMPLICIT INTEGER*2(A-Z) INTEGER*4 AV2 DOUBLE PRECISION XTIME,UTIX,KTIX,XTIX,YTIX,ZTIX,NTIX,NUTIX,VAL LOGICAL NUM REAL F BYTE DAT,INBUF,DUMMY,OUTLIN,COLN,CRHRH,CRHRL,CRMNH,CRMNL DIMENSION UTIL(96,3),DAT(30),SRFREC(32),OUTLIN(100) DIMENSION INBUF(80) NUM(DUMMY)=DUMMY.GE.'0'.AND.DUMMY.LE.'9' C C OPEN FILES-- 1 IS OUTPUT: UPLOT.RPT C 2 IS INPUT: SRF.OLD WHICH IS MAINTAINED BY @SRFMAINT C OPEN (UNIT=1,NAME='DB:UPLOT.RPT',TYPE='NEW',DISPOSE='SAVE', * RECORDSIZE=133) OPEN (UNIT=2,NAME='DB1:[1,210]SRF.OLD',TYPE='OLD',ACCESS='DIRECT', * FORM='UNFORMATTED',READONLY,RECORDSIZE=16,ASSOCIATEVARIABLE=AV2) AV2=1 C C SET UP SYMBOLS C STRTUP=1 STATS=3 SHUTDN=4 RTYPE=1 RYEAR=2 RMON=3 RDAY=4 RHOUR=5 RMIN=6 RSEC=7 RTICK=8 RTPS=9 RTIMH=10 RTIML=11 RTUSRH=12 RTUSRL=13 RTKNLH=14 RTKNLL=15 RTNULH=16 RTNULL=17 C C PROMPT USER FOR DATE OF REPORT C 1 WRITE(5,10) 10 FORMAT('$DATE: ') READ(5,20,END=1999) INBUF 20 FORMAT(80A1) C C DECODE CHARACTER INPUT C FT=0 LT=2360 PTR=1 MN=0 DY=0 YR=0 C C FIND FIRST NUMERIC CHARACTER C 100 IF (NUM(INBUF(PTR))) GOTO 110 PTR=PTR+1 IF (PTR.LE.80) GOTO 100 105 WRITE (5,30) 30 FORMAT(' ERROR: INVALID DATE.') GOTO 1 C C WE HAVE FIRST DIGIT OF DATE HERE C 110 MN=MN*10+INBUF(PTR)-48 PTR=PTR+1 IF (PTR.GT.80) GOTO 105 IF (NUM(INBUF(PTR))) GOTO 110 C C MONTH OK HERE - GO FOR DAY C 115 PTR=PTR+1 IF (PTR.GT.80) GOTO 105 IF (.NOT.NUM(INBUF(PTR))) GOTO 115 C C FOUND FIRST NUMERIC OF DAY C 120 DY=10*DY+INBUF(PTR)-48 PTR=PTR+1 IF (PTR.GT.80) GOTO 105 IF (NUM(INBUF(PTR))) GOTO 120 C C GOT DAY - LETS GET YEAR C 125 PTR=PTR+1 IF (PTR.GT.80) GOTO 105 IF (.NOT.NUM(INBUF(PTR))) GOTO 125 C C FOUND FIRST NUMERIC OF YEAR C 130 YR=10*YR+INBUF(PTR)-48 PTR=PTR+1 IF (PTR.GT.80) GOTO 105 IF (NUM(INBUF(PTR))) GOTO 130 C C WE HAVE COMPLETE DATE HERE. A VALID DELIMITER (' ') HAS BEEN C FOUND AND WE MAY NOW GET THE TIME RANGE (IF ANY) C 140 PTR=PTR+1 IF (PTR.GT.80) GOTO 300 IF (.NOT.NUM(INBUF(PTR))) GOTO 140 C C FOUND FIRST NUMERIC CHARACTER OF START TIME C DIGCT=0 160 FT=10*FT+INBUF(PTR)-48 DIGCT=DIGCT+1 PTR=PTR+1 IF (PTR.GT.80) GOTO 170 IF (NUM(INBUF(PTR))) GOTO 160 C C FOUND FIRST DELIMITER (HH MM SEPARATOR IN START TIME) C 180 PTR=PTR+1 IF (PTR.GT.80.AND.DIGCT.GT.2) GOTO 300 IF (PTR.GT.80) GOTO 170 IF (.NOT.NUM(INBUF(PTR))) GOTO 180 C C IF START TIME IS > TWO DIGITS THEN THE ENTIRE START TIME IS IN A C CONTIGUOUS DIGIT STRING C IF (DIGCT.GT.2) GOTO 190 C C FOUND FIRST DIGIT C 210 FT=10*FT+INBUF(PTR)-48 PTR=PTR+1 IF (PTR.GT.80) GOTO 170 IF (NUM(INBUF(PTR))) GOTO 210 GOTO 195 C C THIS IS THE START TIME ERROR HANDLER C 170 WRITE(5,40) 40 FORMAT(' ERROR: INVALID START TIME') GOTO 1 C C C HERE WE HAVE FOUND THE SEPARATOR BETWEEN START TIME AND END TIME C 195 PTR=PTR+1 IF (PTR.GT.80) GOTO 300 IF (.NOT.NUM(INBUF(PTR))) GOTO 195 C C WE HAVE FIRST DIGIT OF END TIME C 190 LT=0 DIGCT=0 220 LT=LT*10+INBUF(PTR)-48 DIGCT=DIGCT+1 PTR=PTR+1 IF (PTR.GT.80) GOTO 230 IF (NUM(INBUF(PTR))) GOTO 220 C C CHECK IF END TIME IS CONTIGUOUS C IF (DIGCT.GT.2) GOTO 300 C C FOUND DELIMITER IN END TIME C LOOK FOR FIRST DIGIT OF MINUTES C 240 PTR=PTR+1 IF (PTR.GT.80) GOTO 230 IF (.NOT.NUM(INBUF(PTR))) GOTO 240 C C *WHEW* FIRST DIGIT OF END TIME MINUTES C 250 LT=LT*10+INBUF(PTR)-48 PTR=PTR+1 IF (PTR.GT.80) GOTO 230 IF (NUM(INBUF(PTR))) GOTO 250 GOTO 300 C C END TIME ERROR HANDLER C 230 WRITE(5,50) 50 FORMAT(' ERROR: INVALID END TIME') GOTO 1 C C C WE HAVE ALL VALUES IN THEIR INTEGER FORMS C CHECK ACTUAL VALUES C 300 IF (MN.GT.12.OR.MN.LT.1) GOTO 105 IF (DY.GT.31.OR.DY.LT.1) GOTO 105 IF (FT.GT.LT.OR.LT.GT.2360) GOTO 230 IF (FT.GT.2360) GOTO 170 C C LETS GET HOUR AND MINUTE SEPARATE C FH=FT/100 FM=FT-FH*100 LH=LT/100 LM=LT-LH*100 C C CHECK FOR BAD MINUTES C IF (FM.GT.60) GOTO 170 IF (LM.GT.60) GOTO 230 C C WE NEED TO INITIALIZE OUTPUT ARRAY C DO 490 I=1,96 UTIL(I,1)=-1 UTIL(I,2)=-1 490 CONTINUE C C DATAFLAG=0 WHEN NO DATA FOR THE TIME RANGE HAS BEEN FOUND C DATAFL=0 C C START ACTUALLY LOOKING FOR THE PROPER RECORDS IN SRF.OLD NOW C CALL ERRSET(39,.TRUE.,.FALSE.,.TRUE.,.FALSE.,31) 500 READ(2'AV2,END=598,ERR=598) SRFREC IF (SRFREC(RTYPE).EQ.STRTUP) GOTO 510 GOTO 500 C C WE HAVE A STARTUP RECORD HERE IN SRFREC C NOW SEE IF IT IS THE RIGHT DATE C 510 CONTINUE C The following 2 lines removed 2/16/81 JNC - will always read till EOF C IF (DATAFL.NE.0.AND.(SRFREC(RYEAR).GT.YR.OR.SRFREC(RMON).GT. C * MN.OR.SRFREC(RDAY).GT.DY)) GOTO 598 IF (SRFREC(RYEAR).NE.YR.OR.SRFREC(RMON).NE.MN.OR. * SRFREC(RDAY).NE.DY) GOTO 500 C C WE HAVE CORRECT STARTUP RECORD FOR THE DATE INPUT C NOW WE MUST SAVE THE STARTUP TIME C DATAFL=1 SHR=SRFREC(RHOUR) SMN=SRFREC(RMIN) IF (SRFREC(RSEC).GT.29) SMN=SMN+1 IF (SMN.LT.60) GOTO 519 SHR=SHR+1 SMN=0 C C RESET CURRENT # OF TICKS IN USER/KERNEL MODE C 519 KTIX=0.D0 UTIX=0.D0 NUTIX=0.D0 SHTF=0 C C NOW LOOK FOR THE SYSTEM STATISTICS RECORD C 520 IF (SHTF.EQ.1) GOTO 500 READ(2'AV2,END=598,ERR=598) SRFREC IF (SRFREC(RTYPE).GT.SHUTDN.OR.SRFREC(RTYPE).LT.1) GOTO 500 IF (SRFREC(RTYPE).EQ.SHUTDN) SHTF=1 IF (SHTF.NE.1.AND.SRFREC(RTYPE).NE.STATS) GOTO 520 C C WE HAVE A SYSTEM STATISTICS RECORD HERE C XTIME=VAL(SRFREC(RTIMH),SRFREC(RTIML)) EHR=XTIME/216000.D0 EMN=(XTIME-EHR*216000.D0)/3600.D0+.5 AMN=SMN+EMN IF (AMN.LT.60) GOTO 530 AMN=AMN-60 EHR=EHR+1 530 AHR=SHR+EHR C C NOW WE HAVE THE ABSOLUTE TIME IN AHR & AMN C AND WE NOW NEED TO DETERMINE ITS POSITION ON THE GRAPH C C FOR INSTANCE: C C IDEALLY THE FIRST LINE SHOULD BE PRINTED FOR 00:00 TO 00:15 C HOWEVER, THE START TIME FOR THIS PERIOD WILL ACTUALLY BE C THE START TIME OF SRF. C C TIMES THAT START FROM 00:00 THRU 00:29 WILL BE PUT IN THE C FIRST POSITION, 30:00 THRU 44:00 IN THE SECOND, ETC. C D WRITE(5,8880) AHR,AMN D8880 FORMAT(' HOUR: ',I4,' MIN: ',I4) P=AHR*4+AMN/15 IF (P.LE.0) P=1 C C NOW WE NEED TO CALCULATE THE DIFFERENTIAL NUMBER OF TICKS C FROM THE LAST KNOWN NUMBER (THIS IS NECESSARY BECAUSE SRF C KEEPS TRACK OF NUMBER OF TICKS IN KERNEL/USER MODE SINCE C STARTUP OF SRF) C C THE OLD VALUES ARE STORED IN KTIX, UTIX, AND NUTIX C C GET VALUES OF STATISTICS IN TICKS C XTIX=VAL(SRFREC(RTUSRH),SRFREC(RTUSRL)) YTIX=VAL(SRFREC(RTKNLH),SRFREC(RTKNLL)) NTIX=VAL(SRFREC(RTNULH),SRFREC(RTNULL)) ZTIX=(XTIX-UTIX)+(YTIX-KTIX)+(NTIX-NUTIX) C C FILL ARRAY C UTIL(P,3)=AMN UTIL(P,1)=((YTIX-KTIX)/ZTIX)*1000 UTIL(P,2)=((XTIX-UTIX)/ZTIX)*1000 C C KEEP TRACK OF OLD VALUES C KTIX=YTIX UTIX=XTIX NUTIX=NTIX C C DONE! C GO BACK FOR ANOTHER RECORD C GOTO 520 C C DONE WITH FILE. CHECK IF ANY DATA TO REPORT C 598 IF (DATAFL.NE.0) GOTO 1000 WRITE(5,998) 998 FORMAT(' NO REPORT. NO RECORDS MATCH GIVEN DATE.') GOTO 999 C C NOW TO PLOT THE HISTOGRAM C FIRST THE HEADING C 1000 WRITE(1,1010) MN,DY,YR 1010 FORMAT('1',5X,'CPU UTILIZATION vs TIME OF DAY',//, * 6X,'DATE: ',I2,'/',I2,'/',I2,///,10X,'0%',7X,'10%', * 7X,'20%',7X,'30%',7X,'40%',7X,'50%',7X,'60%',7X,'70%',7X, * '80%',7X,'90%',6X,'100% NULL %',/,' 00:00 +', * 10('---------+')) C C SET UP TO KEEP TRACK OF MAXIMUM AND MINIMUM AND AVERAGE CPU UTILIZATION C C85T=0 C85K=0 C85U=0 CPUT=0 CPUK=0 CPUU=0 INTV=0 C C MASTER DO LOOP C DO 1200 N=1,96 C C CHECK IF STATISTICS GATHERED FOR THAT TIME C IF (UTIL(N,1).NE.-1) GOTO 1020 INTV=0 WRITE(1,1070) 1070 FORMAT(10X,'| N O S T A T I S T I C S A V A I L A B L E', * 52X,'|') GOTO 1200 C C SET UP LIMITS FOR THE KKKKK AND UUUUU C 1020 MK=UTIL(N,1)/10.+.5 MU=(UTIL(N,1)+UTIL(N,2))/10.+.5 C C FILL OUTPUT ARRAY C DO 1030 I=1,100 OUTLIN(I)=' ' IF (I.EQ.100) OUTLIN(I)='|' IF (MU.GE.I) OUTLIN(I)='U' IF (MK.GE.I) OUTLIN(I)='K' 1030 CONTINUE C C DO WE NEED TO PLAY WITH TIME? WE DO IF THE LAST INTERVAL HAD NO C STATISTICS OR IF WE ARE ON EVERY FOURTH INTERVAL C M=N L=(M/4)*4 AHR=M/4 IF (M.NE.L.AND.INTV.EQ.1) GOTO 1040 INTV=1 C C CONVERT TIME TO CHARACTER FOR LEADING ZEROS C M=M/4 CRHRH=M/10 CRHRL=M-CRHRH*10+48 CRHRH=CRHRH+48 C CRMNH=UTIL(N,3)/10 CRMNL=UTIL(N,3)-CRMNH*10+48 CRMNH=CRMNH+48 COLN=':' GOTO 1050 1040 COLN=' ' CRMNH=' ' CRMNL=' ' CRHRH=' ' CRHRL=' ' C C OUTPUT A LINE C 1050 F=(1000-UTIL(N,1)-UTIL(N,2))/10. CPUK=CPUK+UTIL(N,1) CPUU=CPUU+UTIL(N,2) CPUT=CPUT+1 IF (AHR.LT.8.OR.AHR.GE.17) GOTO 1055 C85K=C85K+UTIL(N,1) C85U=C85U+UTIL(N,2) C85T=C85T+1 1055 CONTINUE IF (F.EQ.0.1) GOTO 1058 WRITE(1,1060) CRHRH,CRHRL,COLN,CRMNH,CRMNL,OUTLIN,F 1060 FORMAT(' ',5A1,4X,'|',100A1,3X,F5.1,' %') GOTO 1200 1058 WRITE(1,1059) CRHRH,CRHRL,COLN,CRMNH,CRMNL,OUTLIN 1059 FORMAT(' ',5A1,4X,'|',100A1,6X,'T I L T') 1200 CONTINUE WRITE(1,1210) 1210 FORMAT(10X,'+',10('---------+')) C C DO AVERAGE LINE C CPUK=CPUK/(1.0*CPUT)+.5 CPUU=CPUU/(1.0*CPUT)+.5 MK=CPUK/10.0+.5 MU=(CPUK+CPUU)/10.0+.5 DO 1220 I=1,100 OUTLINE(I)=' ' IF (I.EQ.100) OUTLINE(I)='|' IF (I.LE.MU) OUTLINE(I)='U' IF (I.LE.MK) OUTLINE(I)='K' 1220 CONTINUE F=(1000-CPUK-CPUU)/10. WRITE(1,1230) OUTLINE,F 1230 FORMAT(' AVERAGE |',100A1,3X,F5.1,' %') IF (C85T.NE.0) GOTO 1236 WRITE(1,1210) WRITE(1,1233) WRITE(1,1210) 1233 FORMAT(' 8-5 AVG ', * '| N O S T A T I S T I C S A V A I L A B L E',52X,'|') GOTO 999 1236 WRITE(1,1210) C85K=C85K/(1.0*C85T)+.5 C85U=C85U/(1.0*C85T)+.5 MK=C85K/10.0+.5 MU=(C85K+C85U)/10.0+.5 DO 1235 I=1,100 OUTLINE(I)=' ' IF (I.EQ.100) OUTLINE(I)='|' IF (I.LE.MU) OUTLINE(I)='U' IF (I.LE.MK) OUTLINE(I)='K' 1235 CONTINUE F=(1000-C85K-C85U)/10. WRITE(1,1240) OUTLINE,F WRITE(1,1210) 1240 FORMAT(' 8-5 AVG |',100A1,3X,F5.1,' %') C C TEMPORARY END C 999 CLOSE (UNIT=1) CLOSE (UNIT=2) 1999 CALL EXIT END C C VAL IS A FUNCTION THAT RETURNS A DOUBLE PRECISION REAL VALUE C CORRESPONDING TO A DOUBLE WORD VALUE. C DOUBLE PRECISION FUNCTION VAL(XH,XL) INTEGER XH,XL DOUBLE PRECISION XX IF (XH.LT.0) GOTO 100 XX=XH*65536.D0 10 IF (XL.LT.0) XX=XX+65536. XX=XX+XL VAL=XX RETURN 100 XX=(65536.D0+XH)*65536.D0 GOTO 10 END