Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_3_19910112
-
utilities/pchist.mac
There are no other files named pchist.mac in the archive.
;<BEEBE.UTILITY>PCHIST.MAC.23, 25-Sep-83 01:29:16, Edit by BEEBE
;Inserted many comments, increased histogram table size,
;made output more informative, pretabbed operand fields for
;better readability, changed interactive input, added status report,
;fixed Monitor flag use (it was flipped), allow repeated output of
;histogram to different files or with different formats.
;<BEEBE.UTILITIES>PCHIST.MAC.10 10-Oct-80 18:21 EDIT BY BEEBE
;added linear histogram scale option -- logarithmic is usually uninformative
;<PERF-TOOLS>PCHIST.MAC.10, 7-Jun-78 17:12:29, EDIT BY MURPHY
;CPU CONDITIONALS
;<PERF-TOOLS>PCHIST.MAC.9, 21-Sep-77 15:01:36, EDIT BY MURPHY
;<PERF-TOOLS>PCHIST.MAC.7, 30-Aug-77 17:31:03, EDIT BY HURLEY
;<PERF-TOOLS>PCHIST.MAC.6, 30-Aug-77 17:01:18, EDIT BY HURLEY
;<PERF-TOOLS>PCHIST.MAC.5, 26-Aug-77 16:26:53, EDIT BY HURLEY
;<PERF-TOOLS>PCHIST.MAC.4, 26-Aug-77 15:10:52, EDIT BY HURLEY
;<PERF-TOOLS>PCHIST.MAC.3, 26-Aug-77 11:14:31, EDIT BY HURLEY
;<PERF-TOOLS>PCHIST.MAC.2, 26-Aug-77 11:07:16, EDIT BY HURLEY
;<HURLEY>PCHIST.MAC.8, 4-Mar-77 09:11:04, EDIT BY HURLEY
;<HURLEY>PCHIST.MAC.6, 27-Jan-77 14:14:36, EDIT BY MURPHY
;<HURLEY>PCHIST.MAC.5, 20-Jul-76 18:29:32, EDIT BY HURLEY
TITLE PCHIST - Histogram Gatherer
SEARCH MONSYM,MACSYM
SALL
.REQUIRE SYS:MACREL
.REQUEST SYS:FORLIB
EXTERN ALOG10
IFNDEF KLFLG,<KLFLG==1>
IFNDEF KSFLG,<KSFLG==0>
DEFINE SELCPU (KLCOD,KSCOD)<
IFN KLFLG,<KLCOD>
IFN KSFLG,<KSCOD>>
; Ac symbols...
V=0 ;Value reg for FORLIB subroutine
T1=1 ;Monitor call Ac
T2=2 ; " "
T3=3 ; " "
T4=4 ; " "
Q1=5 ;scratch
Q2=6 ;scratch
Q3=7 ;unused
I=15 ;Base register for breakpoint routine region
CX=16 ;unused
P=17 ;stack pointer
BPRPAG==100 ;breakpoint routine page start (region
;includes histogram buckets)
BPRCOD==BPRPAG_11 ;breakpoint routine address
PCHIST: RESET% ;clear to begin
MOVE P,[IOWD PDLEN,PDL] ;initialize stack
MOVEI I,BPRCOD ;setup base register for breakpoint
;routine and table access
JRST 5,[10000,,0
REL3]
ERJMP .+1
TDZA T1,T1
REL3: SETO T1,
MOVEM T1,MONTYP(I) ;Set MONITOR PC recording flag
TMSG <
PCHIST: Fork/Job Run-Time Program Counter Histogram Utility
Version of [24-Sep-83]
You must have WHEEL capability to run this program because it
SNOOPs into the running Monitor to insert a timer breakpoint routine!
>
TMSG <
Name of the program being observed: >
HRROI T1,PRGNAM
MOVE T2,[RD%BEL+5*PRGNML]
SETZ T3,
RDTTY% ;Read program name (used on output listing)
JRST ERROR
TMSG <
Include time spent in MONITOR mode? (Y or N) >
CALL YESNO
TDZA T1,T1 ;NO
SETO T1, ;YES
MOVEM T1,MONFLG(I) ;save MONITOR PC recording flag
TMSG <
Starting address of region to be observed (octal): >
CALL GETADR
JSP ERROR
HRRZM T2,SADR(I) ;save starting address
TMSG <
Bucket size (octal): >
CALL GETADR
JSP ERROR
JUMPLE T2,PCHIST ;restart if bucket size illegal
MOVEM T2,BLKSIZ(I) ;save bucket size
TMSG <
Job number (or non-digit to look at a fork): >
CALL GETDEC
JRST NOTJBN ;was not number, try fork id
MOVNM T2,FORKN(I) ;save -(job number)
JRST NOTJB1
NOTJBN: TMSG <
Fork number of FORK being watched: >
CALL GETADR ;expect octal fork number
JSP ERROR
HRRZM T2,FORKN(I) ;save +(fork number)
NOTJB1: TMSG <
[PCHIST - Clearing tables and inserting Monitor traps] >
SETZM INDEX(I)
SETZM TOTAL(I) ;clear total of PC counts in range
SETZM TABLE(I) ;clear first word of table
HRLI T1,TABLE(I) ;set up BLT word
HRRI T1,TABLE+1(I)
BLT T1,TABLE+TABLEN-1(I) ;clear PC buckets
SETZM OVRFLO(I) ;clear MONITOR PC count
SETZM PILVL(I) ;clear interrupt PC count
; Now insert the Monitor breakpoint trap using SNOOP
MOVEI T1,.SNPLC ;flag to lock breakpoint routine in
;memory -- cannot have page faults
;during PC counting
MOVEI T2,<BPRLEN+777>/1000 ;count of pages to lock
MOVEI T3,BPRPAG ;first page to lock
SNOOP%
JRST ERROR
LSH T2,11 ;Monitor page number corresponding to
;our BPRPAG
MOVEM T2,INDEX(I) ;save Monitor's page number
MOVSI Q1,-INSTBL ;instruction table
TIMER1: HLRZ T1,INSTAB(Q1)
HRRZ T2,INSTAB(Q1)
ADD T2,INDEX(I)
HRRM T2,BPRCOD(T1)
AOBJN Q1,TIMER1
MOVSI Q1,-SYMTBL
JUMPE Q1,TIMER4
; Get absolute addresses of the Monitor symbols we need
TIMER2: MOVEI T1,.SNPSY ;code to get address of Monitor symbol
MOVE T2,SYMTAB(Q1) ;radix-50 symbol
MOVE T3,SYMTAB+1(Q1) ;radix-50 program name containing previous
SNOOP%
JRST ERROR
MOVE T3,SYMTAB+2(Q1) ;offset of returned symbol
HRRM T2,BPRCOD(T3) ;symbol value
ADD Q1,[2,,2]
AOBJN Q1,TIMER2 ;continue scan of Monitor symbol table
TIMER4: MOVE T1,SY3(I)
AOS T1 ;put BP at TIMIN0+1
MOVEM T1,BP1ADR ;address in Monitor space to patch
HRRZ T1,SY5(I)
SKIPE MONTYP(I)
AOS T1
HRRM T1,SY5(I)
MOVEI T1,.SNPDB ;code to define a breakpoint
MOVEI T2,1 ;number of breakpoint
MOVE T3,BP1ADR ;address in Monitor space to patch
MOVE T4,[XPCW BP1R] ;instruction to execute before patched
;instruction is executed
SKIPN MONTYP(I)
MOVE T4,[JSR BP2R]
ADD T4,INDEX(I)
TLZ T4,37
SNOOP% ;define breakpoint
JRST ERROR
MOVEI T1,.SNPIB ;insert breakpoints and start analyzing
SNOOP%
JRST ERROR
; The trap is now under way and the breakpoint routine is busy
; collecting PC counts. We just sit here waiting for the user to request
; us to stop the histogramming.
TMSG <
[PCHIST - Traps installed]
Type <CTL-B> to break, <CTL-Y> for status report >
TIMER3: PBIN% ;get a byte
CAIN T1,.CHCNB ;CTL-B?
JRST TIMER7 ;Yes
CAIN T1,.CHCNY ;CTL-Y?
CALL STATUS ;Yes
JRST TIMER3 ;Get next input byte.
TIMER7: TMSG <
[PCHIST breaking]
Confirm with <CR> to print PC histogram,
or type <CTL-P> to resume collection as if CTL-B had not been typed >
TIMER5: PBIN% ;get a byte
CAIN T1,.CHCNP ;CTL-P?
JRST TIMER6 ;Yes, proceed with collection.
CAIE T1,.CHCUN ;CTL-_
CAIN T1,.CHLFD ;Linefeed
JRST TYPANS ;was CTL-_ or Linefeed, all done
JRST TIMER5 ;ignore, get next byte
TIMER6: TMSG <
[PCHIST proceeding]
>
JRST TIMER3
TYPANS: MOVEI T1,.SNPUL ;code to unlock and release storage and
;remove all breakpoints
SNOOP% ;undo the patches
JRST ERROR
TMSG <
PC histogram collection terminated and Monitor unpatched.>
;
; The PC histogramming is complete. Now just output the results.
;
TYPAN0: TMSG <
Output histogram and timing results to file: >
MOVSI T1,(GJ%FOU!GJ%MSG!GJ%CFM!GJ%FNS!GJ%SHT) ;460003
MOVE T2,[.PRIIN,,.PRIOU] ;[100,,101]
GTJFN% ;get output file JFN
JRST [ MOVEI T1,.PRIOU
HRLOI T2,.FHSLF
SETZ T3,
ERSTR% ;print most recent error message
JFCL ;ignore error
JFCL ;ignore error
JRST TYPAN0] ;try again
MOVEM T1,JFN
MOVE T2,[FLD(7,OF%BSZ)!OF%WR] ;[70000,,100000]
OPENF% ;open the output file
JRST [ MOVEI T1,.PRIOU
HRLOI T2,.FHSLF
SETZ T3,
ERSTR% ;print most recent error message
JFCL ;ignore error
JFCL ;ignore error
HRRZ T1,JFN
RLJFN% ;release the JFN
JFCL ;ignore errors
JRST TYPAN0] ;try again
TMSG <
Logarithmic histogram scale? (Y or N) >
SETOM LOGFLG ;default is logarithmic scale
CALL YESNO
SETZM LOGFLG ;NO, use linear scale
;
; We have an output file, now format and print the histogram data
;
MOVE T1,JFN
FMSG <
PCHIST: Fork/Job Run-Time Program Counter Histogram Utility
Version of [24-Sep-83]
PC Histogram of Program >
HRROI T2,PRGNAM
SOUT%
SETO T2,
SETZ T3,
ODTIM% ;print dd-mon-yy hh:mm:ss
JFCL
FMSG <
Total samples taken = >
MOVE T2,NSAMP(I)
MOVEI T3,^D10
NOUT%
JFCL
FMSG < (number of traps to PCHIST)>
FMSG <
Total samples used = >
MOVE T2,TOTAL(I)
MOVEI T3,12
NOUT%
JFCL
SKIPN TOTAL(I)
JRST TYPDON ;quit if no samples collected
FMSG < (>
FLTR T2,TOTAL(I)
FLTR T3,NSAMP(I)
FDVR T2,T3
CALL PCTOUT
FMSG <%)>
FMSG < (difference from total is Scheduler)
PC values outside selected range are accumulated in nearest endpoint bucket.>
SKIPN LOGFLG
JRST FIXMSG ;jump if LINEAR scale
FMSG <
Hits Bucket Percent 0.1 1.0 10. 100
>
JRST PASTHD
FIXMSG: FMSG <
Hits Bucket Percent 000000000.111111111.222222222.333333333.444444444.555555555.666666666.777777777.888888888.999999999
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
>
PASTHD: MOVE T2,TOTAL(I) ;compute 0.1% of total
IDIVI T2,^D1000
SKIPG T2
MOVEI T2,1 ;cutoff at 1 if total < 1000
MOVEM T2,MINCNT ;this is cutoff for histogram
MOVE Q1,SADR(I) ;start address
MOVSI Q2,-TABLEN
HRR Q2,I ;[-TABLEN,,breakpoint routine base address]
TYPLOP: MOVE T2,TABLE(Q2) ;PC count for this bucket
CAMGE T2,MINCNT ;above cutoff?
JRST TYPLP1 ;NO, do not print this bucket
MOVEI T3,12 ;decimal
NOUT% ;print count
JFCL
MOVEI T2,.CHTAB
BOUT% ;then a TAB
MOVE T2,Q1
MOVEI T3,10 ;octal
NOUT% ;print bucket address
JFCL
MOVEI T2,.CHTAB
BOUT% ;then another TAB
FLTR T3,TOTAL(I)
FLTR T2,TABLE(Q2)
FDVR T2,T3
CALL PCTOUT ;then percent of total
CALL TYPGRA ;and finally histogram bar
TYPLP1: ADD Q1,BLKSIZ(I) ;next bucket address
AOBJN Q2,TYPLOP ;loop until table printed
SKIPN T2,OVRFLO(I) ;Monitor count = 0?
JRST TYPPIL ;Yes
MOVEI T3,12 ;No, print decimal
NOUT% ;count
JFCL
MOVEI T2,.CHTAB
BOUT% ;then TAB
FMSG <MONITR> ;then name
MOVEI T2,.CHTAB ;then TAB
BOUT%
FLTR T2,OVRFLO(I)
FLTR T3,TOTAL(I)
FDVR T2,T3
CALL PCTOUT ;then percent
CALL TYPGRA ;and finally histogram bar
TYPPIL: SKIPN T2,PILVL(I) ;Interrupt level count = 0?
JRST TYPDON ;Yes
MOVEI T3,12 ;No, print decimal
NOUT% ;count
JFCL
MOVEI T2,.CHTAB
BOUT% ;then a TAB
FMSG <PILEVL > ;then name
FLTR T2,PILVL(I)
FLTR T3,TOTAL(I)
FDVR T2,T3
CALL PCTOUT ;then percent
CALL TYPGRA ;and finally histogram bar
TYPDON: HRRZ T1,JFN ;all done
CLOSF% ;close the output file
JFCL ;ignore errors
TMSG <
[PCHIST exit - type CONTINUE to print histogram again]>
HALTF% ;quit
JRST TYPAN0 ;CONTINUE with printing
;Miscellaneous subroutines
PCTOUT: FMPR T2,[100.0] ;type a percent of value in T2
MOVE T3,[1B4!1B6!37B17!2B23!2B29]
FLOUT%
JFCL
RET
STATUS: TMSG <
Total PC samples: >
MOVEI T1,.PRIOU
MOVE T2,NSAMP(I)
MOVEI T3,12 ;print decimal
NOUT% ;count
JFCL
TMSG < In program: >
MOVEI T1,.PRIOU
MOVE T2,TOTAL(I)
MOVEI T3,12 ;print decimal
NOUT% ;count
JFCL
TMSG < In Monitor: >
MOVEI T1,.PRIOU
MOVE T2,OVRFLO(I)
MOVEI T3,12 ;print decimal
NOUT% ;count
JFCL
TMSG < In interrupt handlers: >
MOVEI T1,.PRIOU
MOVE T2,PILVL(I)
MOVEI T3,12 ;print decimal
NOUT% ;count
JFCL
TMSG <
>
RET
TYPGRA: PUSH P,T2 ;type histogram graph
MOVEI T2,.CHTAB
BOUT% ;TAB
BOUT% ;TAB
MOVEI T2,0(P) ;get address of value
MOVE V,0(T2) ;get value
PUSH P,T2 ;construct 1-word arg list
SKIPN LOGFLG
JRST FIXVAL ;jump if linear scale
MOVEI 16,0(P) ;point to arg list
CALL ALOG10 ;take LOG10 of value
FADRI V,(1.0) ;select range
FMPRI V,(16.0) ;scale value
FIXVAL: FIXR T3,V
SUB P,[2,,2] ;flush stack
MOVE T1,JFN
MOVEI T2,"*" ;marker symbol for histogram bar
JUMPLE T3,SPALP2 ;flush if too small
SPALOP: SOJLE T3,SPALP1
BOUT%
JRST SPALOP ;output histogram bar
SPALP1: MOVEI T2,"*"
BOUT% ;final star on bar
SPALP2: MOVEI T2,.CHCRT
BOUT%
MOVEI T2,.CHLFD ;end-of-line
BOUT%
RET
GETDEC: SKIPA T4,[^D10] ;get decimal value from terminal
GETADR: MOVEI T4,^D8 ;get octal (address) value from terminal
MOVE T1,[100,,101]
HRROI T2,STRING
MOVE T3,[RD%BRK!RD%TOP!RD%JFN+STRNGL]
RDTXT% ;obsolete JSYS, oh well...
JRST ERROR
HRROI T1,STRING
MOVE T3,T4
NIN%
RET
AOS 0(P)
RET
RET
YESNO: MOVE T1,[100,,101] ;Get Y or N answer from terminal
HRROI T2,STRING
MOVE T3,[RD%BRK!RD%RAI!RD%TOP!RD%JFN+STRNGL]
RDTXT% ;obsolete JSYS, oh well...
JRST ERROR
LDB T1,[POINT 7,STRING,6]
CAIN T1,"Y"
RETSKP ;YES
CAIN T1,"N"
RET ;NO
TMSG < you must type Y or N! >
JRST YESNO ;keep trying
ERROR: MOVEI T1,.PRIOU ;fatal error - print message and quit
HRLOI T2,.FHSLF
SETZ T3,
ERSTR% ;print most recent error message
JFCL
JFCL
HALTF%
JRST PCHIST ;start over if CONTINUEd
INSTAB: RL1,,SAV1I ;instruction table
RL2,,INDEX
RL3,,BP1R
RL4,,RL1
RL5,,BP2R
RL6,,MONTYP
INSTBL==.-INSTAB
SYMTAB: ;Monitor symbol table request area
RADIX50 0,FORKX
0
FORKX: SY1
RADIX50 0,FKJOB
0
FKJOB: SYA1
SELCPU <
RADIX50 0,TIMINT
0
TIMINT: SY2
RADIX50 0,TIMINT
0
SY5>,<
RADIX50 0,PIAPRX
0
PIAPRX: SY2
RADIX50 0,PIAPRX
0
SY5>
RADIX50 0,TIMIN0
0
TIMIN0: SY3
RADIX50 0,UPDL
0
UPDL: SY4
RADIX50 0,INSKED
0
INSKED: SY6
SYMTBL==.-SYMTAB
JFN: 0
MINCNT: 0
BP1ADR: 0 ;breakpoint routine address
STRNGL==20
STRING: BLOCK STRNGL ;buffer for RDTTY input text
PRGNML==40
PRGNAM: BLOCK PRGNML ;buffer for program name
PDLEN==40
PDL: BLOCK PDLEN ;push-down stack
;Breakpoint routine and PC histogram bucket tables
LOC BPRPAG_11 ;start in memory at absolute page boundary
PHASE 0
BPR: ;Breakpoint routine entered at each
;timer tick
BP1R: 0
0
0
RL4: RL1
BP2R: 0
RL1: MOVEM I,SAV1I
RL2: MOVE I,INDEX
MOVEM T1,SAV1T1(I)
MOVEM T2,SAV1T2(I)
MOVEM T3,SAV1T3(I)
MOVEM T4,SAV1T4(I)
AOS NSAMP(I) ;count total samples (times this routine
;entered)
SKIPGE T2,FORKN(I) ;+(value) means fork
MOVN T2,FORKN(I) ;-(value), so have job number
SY1: HRRZ T1,FORKX
SKIPGE FORKN(I) ;+(value) means fork
SYA1: HLRZ T1,FKJOB(T1) ;-(value), so have job number
SY6: SKIPG INSKED
CAME T1,T2
JRST BP1A(I)
CONSZ PI,67400 ;PI level?
JRST BP1PI(I) ;yes
SY2: MOVE T2,.-. ;flags
TLNN T2,10000
SKIPN MONFLG(I) ;skip if Monitor PC's being counted
SKIPA ;no Monitor counting
JRST BP1B(I)
SY5: HRRZ T1,.-. ;PC
TLNN T2,10000
SY4: MOVE T1,UPDL
HRRZS T1
SUB T1,SADR(I) ;offset from counting region start
SKIPGE T1 ;positive
MOVEI T1,0 ;negative, make offset 0
IDIV T1,BLKSIZ(I) ;bucket number = offset/(bucketsize)
CAIL T1,TABLEN ;past end of table?
MOVEI T1,TABLEN-1 ;yes, put in last bucket
JRST BP1C(I) ;go increment bucket count
BP1PI: MOVEI T1,PILVL-TABLE ;bucket number for interrupt level counting
JRST BP1C(I) ;go increment bucket count
BP1B: MOVEI T1,OVRFLO-TABLE ;bucket number for Monitor level counting
BP1C: ADDI T1,TABLE(I) ;bucket address
AOS 0(T1) ;increment bucket count
AOS TOTAL(I) ;increment total count
BP1A: MOVE T1,SAV1T1(I) ;restore registers
MOVE T2,SAV1T2(I)
MOVE T3,SAV1T3(I)
MOVE T4,SAV1T4(I)
MOVE I,SAV1I(I)
RL6: SKIPE MONTYP
RL3: XJRSTF BP1R ;return from breakpoint to Monitor
RL5: JRSTF @BP2R
SAV1T1: 0
SAV1T2: 0
SAV1T3: 0
SAV1T4: 0
SAV1I: 0
SY3: 0
LOGFLG: -1 ;default value is logarithmic scale
SADR: 0 ;starting address of region
BLKSIZ: 0 ;histogram bucket size -- each counter
;is covers this many words in program
INDEX: 0
TOTAL: 0 ;count of PC's in range
NSAMP: 0 ;total number of PC's trapped
TABLEN==10000 ;PC histogram table -- this cannot be
;too big, or Monitor will refuse to lock
;it in memory
TABLE: BLOCK TABLEN
OVRFLO: 0 ;Monitor PC count word
PILVL: 0 ;Interrupt level count word
FORKN: 0 ;fork number (+) or job number (-)
MONFLG: 0 ;Non-zero means recording PC's in
;Monitor
MONTYP: 0
BPRLEN==.-BPR ;size of breakpoint routine
DEPHASE
RELOC
END PCHIST