;*************************** AMUS Program Label ******************************
; Filename: BENCH.M68 Date: 06/22/90
; Category: UTIL Hash Code: 015-414-142-352 Version: 1.0(100)
; Initials: ESS/AM Name: CREED A. ERICKSON
; Company: Telephone #:
; Related Files: NONE
; Min. Op. Sys.: Expertise Level: BEG
; Special: Use LNKLIT BENCH after initial assembly
; Description: A "stopwatch" program which keeps track of various system
; resources (CPU time, disk read and writes, elapsed time) which can be
; used to benchmark programs.
;*****************************************************************************
;************************************************************************
; *
; BENCH.M68 - A stopwatch for benchmarking programs. *
; *
;************************************************************************
; Copyright (c) 1990 - Creed A. Erickson.
; All Rights Reserved.
;
; Justification:
;
; BENCH is a utility which, when incorporated into CMD and DO files,
; will keep track of system resources spent by a program or process.
; Resources tracked are:
;
; CPU time.
; Connect time (elapsed real-time).
; Disk reads.
; Disk writes.
;
; Usage:
;
; .BENCH keyword
;
; Supported keywords are:
;
; START - Start/reset the stopwatch.
; ON - Start/reset the stopwatch.
; YES - Start/reset the stopwatch.
; MARK - Display elasped time, keep timing.
; LAP - Display elasped time, keep timing.
; STOP - Display elasped time, shut off stopwatch.
; OFF - Display elasped time, shut off stopwatch.
; NO - Display elasped time, shut off stopwatch.
;
; Example CMD file:
;
; :R
; LOAD SYS:BENCH ; Load for speed.
; BENCH ON ; Start the clock.
; RUN TEST1 ; Run the first test program.
; BENCH MARK ; Mark the elasped time (LAP).
; RUN TEST2 ; Run the second test program.
; BENCH OFF ; Shut off the clock.
;
; Notes:
;
; o To save time and remove some variability in the timing, it is
; highly desirable to load BENCH into user or system memory.
;
; o If the process being timed invokes LOGOFF, the "stopwatch" will
; be lost.
;
; Edit History (most recent first):
;
;[100] 06/13/90 Designed and implemented by Creed A. Erickson.
;
; Define impure area.
;
OFINI
OFDEF JB.CPU, 4 ; Saved CPU time.
OFDEF JB.CON, 4 ; Saved connect time.
OFDEF JB.DSR, 4 ; Saved disk reads.
OFDEF JB.DSW, 4 ; Saved disk writes.
OFDEF LP.CPU, 4 ; Lap CPU time.
OFDEF LP.CON, 4 ; Lap connect time (not used).
OFDEF LP.DSR, 4 ; Lap disk reads.
OFDEF LP.DSW, 4 ; Lap disk writes.
OFSIZ S..IMP
BENCH: PHDR -1,0,PH$REE!PH$REU ; Is reentrant & reusable.
CALL CMD ; Get command.
BEQ 10$ ; Got a good command.
TYPECR <?Command format error.>; Had a command error.
BR XSIT ; All done.
; Command code is in D1:
;
; 0 = Start
; 1 = Lap
; 2 = Stop
;
10$: CALL IMPGET ; Get or index impure.
JOBIDX A6 ; Get job index.
LEA A0, JOBCPU(A6) ; Index stuff to save.
LEA A6, ACTTBL ; Index the action table.
LSLW D1, #1 ; Multiply by 2 for word indexing.
ADDW D1, A6 ; Add offset into table.
ADDW @A6, A6 ; Add in offset from table.
JMP @A6 ; Go do it.
ACTTBL: OFFSET START
OFFSET LAP
OFFSET STOP
;**********
; START *
;**********
; Start the stopwatch.
;
START: LEA A1, JB.CPU(A5) ; Index the saved block.
MOV (A0)+, (A1)+ ; Move CPU time.
MOV (A0)+, (A1)+ ; Bypass connect time.
MOV (A0)+, (A1)+ ; Move disk reads.
MOV (A0)+, (A1)+ ; Move disk writes.
GTIMEI JB.CON(A5) ; Set connect time.
GDATEI D1 ; Get today.
SUB #2444240., D1 ; Convert to days since 1/1/80
SWAP D1 ; Put in high order.
LSL D1 ; Shift up a bit.
OR D1, JB.CON(A5) ; Store.
BR XSIT ; All done.
;*********
; STOP *
;*********
; Stop the stopwatch.
;
STOP: LEA A1, LP.CPU(A5) ; Index lap block.
MOV (A0)+, (A1)+ ; Move CPU time.
MOV (A0)+, (A1)+ ; Move connect time.
MOV (A0)+, (A1)+ ; Move disk reads.
MOV (A0)+, (A1)+ ; Move disk writes.
CALL REPORT ; Report the statistics.
MOVW #0, -10(A5) ; Zap the module flags.
BR XSIT ; All done.
;********
; LAP *
;********
; Display elapsed time so far.
;
LAP: LEA A1, LP.CPU(A5) ; Index lap block.
MOV (A0)+, (A1)+ ; Move CPU time.
MOV (A0)+, (A1)+ ; Move connect time.
MOV (A0)+, (A1)+ ; Move disk reads.
MOV (A0)+, (A1)+ ; Move disk writes.
BCALL REPORT ; Report the statistics.
XSIT: EXIT
;***********
; REPORT *
;***********
; Report statistics.
;
; Passed:
;
; A5 := The BENMRK.%%% inpure module.
;
; Returns:
;
; Nothing.
;
; Side effects:
;
; Destroys A2, D1
;
; Notes:
;
; Some code shamelessly liberated from LOG.M68 and LOGOFF.M68
;
REPORT:
; Display Disk reads and writes.
;
MOV LP.DSR(A5), D1 ; Get count of disk reads.
SUB JB.DSR(A5), D1 ; Subtract starting count.
DCVT 0, OT$TRM ; Output to terminal.
TYPESP < reads,> ; Say what the number is about.
MOV LP.DSW(A5), D1 ; Get count of disk writes.
SUB JB.DSW(A5), D1 ; Less starting count.
DCVT 0, OT$TRM ; Output to the terminal.
TYPE < writes. > ; Say what the number is.
; Display CPU time.
;
TYPESP < CPU time: >
MOV LP.CPU(A5), D1 ; Get amount of CPU time used.
SUB JB.CPU(A5), D1 ; Less starting count.
SUB A2, A2 ; display on terminal
CALL $OTCPU ; display CPU time
; Display connect (or elapsed) time.
;
TYPESP <, Elapsed time:>
MOV JB.CON(A5), D1 ; Get user's connect time.
SUB A2,A2 ; display on terminal
CALL $OTCON ; display connect time
CRLF
RTN
;***********
; IMPGET *
;***********
; Index or allocate the impure area.
;
; Passed:
;
; Nothing.
;
; Returned:
;
; A5 => Inpure area.
;
; Side effects:
;
; Destroys A1.
;
IMPGET:
LEA A1, MODNAM ; Index the module name.
SRCH @A1, A5, F.USR ; Find the module.
BEQ 99$ ; Found, all done.
; Module not found, make a new one.
; Use stack for temporary MCB.
;
PUSH #S..IMP ; Size to allocate.
PUSH ; Room for index.
GETMEM @SP ; Allocate the module.
BEQ 10$ ; OK, proceed.
TYPECR <?Insufficient memory.> ; Failed, report error.
JMP XSIT ; And bomb out.
10$: POP A5 ; Get the index.
POP ; Clean up stack.
; Name the module. Remember, A1 is still pointed at the name block.
;
MOV (A1)+, -6(A5) ; Move in a module name.
MOVW @A1, -2(A5) ; Move in a module extension.
; Flag the module as permanent.
;
MOVW #<FIL!LOK>, -10(A5) ; Lock as memory file.
99$: RTN ; Return to caller.
MODNAM: WORD [BEN], [MRK], [%%%] ; Name is BENMRK.%%%
;********
; CMD *
;********
; Parse command line for proper command word.
;
; Passed:
;
; A2 => Standard AMOS command line pointer.
;
; Returned:
;
; D1 := Command value:
;
; 0 = Start
; 1 = Lap
; 2 = Stop
; Z-bit Set if valid command word encountered, reset otherwise.
;
; Side effects:
;
; Destroys A2, A1, D1.
;
; Credits:
;
; This routine was inspired by a similar, bu more extensive
; routine by Brett R. Halle.
;
CMD: BYP ; Bypass white space.
LIN ; End of line?
BNE 05$ ; No, scan the line.
LCC #0 ; Yes, flag bad line.
BR 99$ ; All done.
05$: LEA A1, KEYWORD ; Index the keyword table.
MOV A2, A0 ; Save A2 command line index.
BR 20$
; Come to here to skip over a keyword entry.
;
10$: TSTB (A1)+ ; End of string?
BNE 10$ ; No, loop for more.
TSTB (A1)+ ; Yes, skip value.
MOV A0, A2 ; Restore command line index.
TSTB @A1 ; End of table?
BNE 20$ ; No.
LCC #0 ; Yes, flag failure.
BR 99$ ; And exit this routine.
20$: LIN ; End of line?
BEQ 30$ ; Yes.
CMPB @A2, #$SPACE ; End of word?
BLE 30$ ; Yes.
MOVB (A1)+, D1 ; No, get next keyword byte.
BEQ 10$ ; End of keyword, didn't match.
CMPB D1, (A2)+ ; Compare to command line.
BEQ 20$ ; Matched, compare next.
BR 10$ ; Didn't match, next keyword.
; Come to here if command line terminated. Test for end of keyword also.
;
30$: TSTB (A1)+ ; End of keyword?
BNE 10$ ; Nope, try the next keyword.
CLR D1 ; Yep, preclear D1.
MOVB @A1, D1 ; Get the keyword value.
LCC #PS.Z ; Flag success.
99$: MOV A0, A2 ; Restore command line pointer.
RTN ; Return to caller.
;*********************
; Keyword table... *
;*********************
; Table of valid keywords and their values.
;
DEFINE KWD WRD, VAL
ASCIZ "WRD"
BYTE VAL
ENDM
KEYWORD:
KWD <ON>, 0 ; Start the clock.
KWD <START>, 0 ; Start the clock.
KWD <YES>, 0 ; Start the clock.
KWD <LAP>, 1 ; Report a "Lap" time.
KWD <MARK>, 1 ; Report a "Lap" time.
KWD <OFF>, 2 ; Stop the clock.
KWD <STOP>, 2 ; Stop the clock.
KWD <NO>, 2 ; Stop the clock.
BYTE 0 ; End of table.
EVEN ; Force to even address.