; ************ TIMER TRAP ROUTINES FOR PROGRAM COUNTER SAMPLING *************** ; ; ; Program counter sampling routines which sample the program counter value ; on every clock interrupt. Clock interrupts occur as often as the sampling ; interval (constant MILLISEC below) specifies. Sampling is initiated by a ; call on PME_INIT and terminated by a call on PME_EXIT. The name of the ; sampling output file can be specified by calling PME_SNAME--if this is not ; done, a default file name is used. ; ; ; Written by Bert Beander, March, 1979. .TITLE PMECLOCK Performance Measurement and Evaluation .IDENT /V01-01/ .LIBRARY "PMEDEFS.MLB" ; Default macro library PMEDEFS ; Define default file name macro $FABDEF ; Define all FAB$ tags $DSCDEF ; Define all DSC$ tags ; FAB, RAB, and all other data areas ; .PSECT PME_DATA,NOEXE,LONG MILLISEC= 10 ; Timing interval in milliseconds INTERVAL: ; Timing interval in 100-nanosecond .LONG -10*1000*MILLISEC ; units--negative sign indicates .LONG -1 ; delta time, not absolute time PMEID = ^A"PME$" ; Timer i.d. for cancelling timer trap DEFNAME: PMEDEFNAME ; Pure copy of the default file name DEFSIZE = .-DEFNAME ; Size of default file name .ALIGN LONG ; Longword align the FAB and RAB OUTFAB: $FAB FNA=OUTFNAME,FNS=DEFSIZE,DNM=<.PMS>,- FAC=PUT,MRS=512,ORG=SEQ,RFM=FIX,DEQ=10 OUTRAB: $RAB FAB=OUTFAB,RAC=SEQ,RBF=BUFFER,RSZ=512 OUTFNAME: PMEDEFNAME ; File name of output sample file .BLKB MAXNAMSIZ-DEFSIZE ; BUFPTR: .LONG 0 ; Buffer pointer (next avail loc) BUFFER: .BLKB 512 ; PC value accumulation buffer BUFEND = . ; End of buffer address .PSECT PME_CODE,EXE,NOWRT,LONG,PIC ; ************** PME_INIT: SAMPLING INITIATION ROUTINE ******************** ; ; ; The program counter sampling initiation routine is called as follows: ; ; CALL PME_INIT ; ; This sets up an asynchronous trap routine which regularly samples the ; current Program Counter value and accumulates all such values in an ; output file. PME_INIT creates that file and initializes it with a ; header record. The name of the output file can be specified by calling ; PME_SFILE before calling PME_INIT (see below), but if PME_SFILE is not ; called, a default file name is supplied. ; ; ; Now create the new output file, connect the RAB to the FAB, and write out ; the header record to that file. ; .ENTRY PME_INIT,^M<> ; Start Sampling entry point INIT: $CREATE FAB=OUTFAB ; Create the sampling output file BLBC R0,ERROR1 ; Make sure it worked $CONNECT RAB=OUTRAB ; Connect the RAB to the FAB BLBC R0,ERROR1 ; $PUT RAB=OUTRAB ; Write out the header record BLBC R0,ERROR1 ; Check for errors $WAIT ; ; Set up the buffer pointer for the program counter accumulation buffer and ; start up the timer with the proper timer interval. ; MOVAL BUFFER,BUFPTR ; Initialize the buffer pointer $SETIMR_S DAYTIM=INTERVAL,ASTADR=PME_TIMAST,REQIDT=#PMEID ; Set timer BLBC R0,ERROR1 ; Make sure status is good RET ; Return to the caller ; Handle any errors which may have occurred along the way ; ERROR1: $EXIT_S CODE=R0 ; Exit with the bad error status code ; ************** PME_EXIT: SAMPLING TERMINATION ROUTINE ******************** ; ; ; The sampling termination routine is called as follows: ; ; CALL PME_EXIT ; ; This cancels the current timer request, puts a zero in the program counter ; accumulation buffer as an end marker (zero is an illegal program counter ; value), writes out the last buffer, and closes the sampling output file. ; .ENTRY PME_EXIT,^M<> ; Terminate Sampling entry point $CANTIM_S REQIDT=#PMEID ; Cancel our timer request MOVL BUFPTR,R0 ; R0 = the current buffer pointer CLRL (R0) ; Insert zero as end-of-file indicator $PUT RAB=OUTRAB ; Write out this last buffer BLBC R0,ERROR2 ; Make sure it worked $WAIT ; $CLOSE FAB=OUTFAB ; Close the file BLBC R0,ERROR2 ; RET ; Return normally ; Handle any error which may have cropped up ; ERROR2: $EXIT_S CODE=R0 ; Exit with the bad status code ; ************** PME_CONT: SAMPLING CONTINUATION ROUTINE **************** ; ; ; Sampling continuation routine which restarts program counter sampling after ; it has been turned off. This routine is called as follows: ; ; CALL PME_CONT ; ; This call does the same thing as a call on PME_INIT but is provided here to ; make time interval sampling compatible with trace sampling of the program ; counter. A user program can thus use either data collection method without ; any change to the program source. Sampling is turned off by another call ; on PME_EXIT. ; ; ; Jump right into the PME_INIT code. ; .ENTRY PME_CONT,^M<> ; Sampling Continuation entry point BRW INIT ; Branch to PME_INIT code ; ******************* TIMER TRAP ROUTINE ******************************** ; ; ; Asychronous trap routine which gets control at every timer interrupt. ; Fill the program counter value of the interrupt location into the ; buffer, and if the buffer is full, write the buffer out to the sample ; file. Then restart the timer and return. ; PME_TIMAST: ; Timer Trap Routine entry point .WORD ^M<> ; Entry mask MOVL BUFPTR,R0 ; R0 = the buffer pointer MOVL 16(AP),(R0)+ ; Put the PC value in the buffer MOVL R0,BUFPTR ; Store back updated buffer pointer MOVAB BUFEND,R1 ; Is the buffer full? CMPL R0,R1 ; BNEQ 10$ ; If not, go to 10$ $PUT RAB=OUTRAB ; Yes--write it out to the sample file BLBC R0,ERROR3 ; Make sure it worked $WAIT ; MOVAB BUFFER,BUFPTR ; Reset buffer pointer to start of buffer 10$: $SETIMR_S DAYTIM=INTERVAL,ASTADR=PME_TIMAST,REQIDT=#PMEID ; Set timer BLBC R0,ERROR3 ; RET ; Return ; Handle any error conditions in the timer trap routine ; ERROR3: $EXIT_S CODE=R0 ; Exit with the bad status code ; ******************* PME_SNAME: SET SAMPLING FILE NAME ********************** ; ; ; This subroutine allows the user to specify the file name to be used for the ; output sampling file. The call is as follows: ; ; CALL PME_SNAME(OUTFILENAME) ; ; where OUTFILENAME is a character string, passed by descriptor, containing ; the desired file name. This routine simply copies the passed file name to ; a local buffer and strips off any trailing blanks. No other checking is ; done on the file name string. If the passed string is completely empty (all ; blanks) or if this routine is not called in the first place, a default file ; name of "PMEFILE.PMS" is supplied instead. ; ; ; Copy the passed file name string to our local file name buffer ; .ENTRY PME_SFILE,^M<> ; Set Sampling File Name entry point MOVL 4(AP),R1 ; R1 = address of string descriptor MOVW DSC$W_LENGTH(R1),R0 ; R0 = the string length CMPW R0,#MAXNAMSIZ ; If the length exceeds the size of our BLEQ 10$ ; local buffer, truncate it MOVW #MAXNAMSIZ,R0 ; 10$: MOVC3 R0,@DSC$A_POINTER(R1),OUTFNAME ; Copy file name to local buffer ; Now scan the name string backwards to strip off any trailing blanks ; MOVAB OUTFNAME[R0],R1 ; R1 = pointer to the end of the string 20$: CMPB -(R1),#^A" " ; Scan backwards for the first non-blank BNEQ 30$ ; or the start of the string SOBGTR R0,20$ ; 30$: MOVB R0,OUTFAB+FAB$B_FNS ; Set the file name size in the FAB ; If the string turned out to be empty (zero length), fill in our default ; file name (PMEFILE) instead. Then return to the caller. ; TSTW R0 ; Is the string empty? BGTR 40$ ; If not, go to 40$ and return MOVC3 #DEFSIZE,DEFNAME,OUTFNAME ; But if so, fill in the default file MOVB #DEFSIZE,OUTFAB+FAB$B_FNS ; name and its size 40$: RET ; Return ; ************** PME_IFILE AND PME_OFILE: DUMMY ROUTINES ****************** ; ; ; These two subroutines are provided only for compatibility with the trace ; method of program counter sampling. They are dummy routines which only ; return--they do nothing else. ; ; ; Return to the caller immediately. ; .ENTRY PME_IFILE,^M<> ; Dummy entry point RET ; Return immediately .ENTRY PME_OFILE,^M<> ; Another dummy entry point RET ; Return immediately .END