RAND@merrimack.EDU ("Rand P. Hall") (06/01/88)
Does anyone have/know of the availability of the LoadAverage device driver source code? The driver *image* was shipped with older versions of the Columbia University FINGER program. I find it to be a nice metric of system load and would rather not see it die under V5. In the event that the source never surfaces, has anyone done anything similar? Rand P. Hall rand@merrimack.edu (csnet) Director, Academic Computing 617.683.7111 Merrimack College 315 Turnpike Rd. "There is elegance in simplicity." North Andover, Mass. 01845 - Kimball S. Maddocks
adelman@WARBUCKS.AI.SRI.COM (Kenneth Adelman) (06/07/88)
> Does anyone have/know of the availability of the LoadAverage device > driver source code? The driver *image* was shipped with older versions > of the Columbia University FINGER program. I find it to be a nice > metric of system load and would rather not see it die under V5. > > In the event that the source never surfaces, has anyone done anything similar? The driver was written by David Kashtan of SRI International. I've converted it for use under VMS V5 and SMP, and also added some additional statistics to it. If you keep reading past the first 12 bytes which contain the load, the next 12 you get are the average blocking priority, and the last 12 are the average disk i/o queue length. Although the code is in to support Multiprocessors, the driver has never been tested on a real Multiprocessing machine. Kenneth Adelman SRI International .TITLE LAVDRIVER VAX/VMS Load Average Pseudo Device .IDENT /Version 3.03/ .SBTTL DOCUMENTATION ;---------------S-R-I-International-Artificial-Intelligence-Center----------- ; ; ; MODULE NAME: ; ; LAVDRIVER ; ; PURPOSE: ; ; This is a pseudo device which supplies load average information to ; programs wishing to display some indication of system load. ; ; KEYWORDS: ; ; Drivers ; ; USAGE: ; ; Standard system QIO calls. ; ; The driver is installed via sysgen. The following is the correct ; sysgen command sequence. ; ; SYSGEN> LOAD LAVDRIVER ; SYSGEN> CONNECT LAV0 /NOADA/DRIVER=LAVDRIVER ; ; Note: LAVDRIVER.EXE should reside in [SYS$LDR] ; ; ; SPECIAL REQUIREMENTS: ; ; none ; ; LANGUAGE: ; ; VAX-11 MACRO ; ; PARAMETERS: ; ; none ; ; SPECIAL TECHNIQUES: ; ; none ; ; AUTHOR: ; ; David Kashtan ; ; DATE CREATED: ; ; Wed Jul 21 11:25:19 1982 ; ; MAINTAINED BY: ; ; David Kashtan ; ; UPDATES: ; ; Modified for VMS V5 SMP Thu Oct 8 1987 Kenneth Adelman / LBL ; ;---------------S-R-I-International-Artificial-Intelligence-Center----------- .SBTTL DEFINITIONS .LIBRARY /SYS$LIBRARY:LIB.MLB/ ;+ --- ; ; DEFINE CONTROL BLOCK OFFSETS & OTHER SYSTEM STUFF BY CALLING 'DEF' MACROS ; ;- --- $CPUDEF ;DEFINE PER-CPU STRUCTURE $CRBDEF ;DEFINE CHANNEL REQUEST BLOCK $DCDEF ;DEFINE DEVICE TYPES $DDBDEF ;DEFINE DEVICE DATA BLOCK $DEVDEF ;DEFINE DEVICE CONSTANTS $DPTDEF ;DEFINE DRIVER PROLOGUE TABLE $DYNDEF ;DEFINE DYNAMIC STRUCTURE CODES $FKBDEF ;DEFINE FORK BLOCK CODES $IODEF ;DEFINE I/O FUNCTION CODES $IRPDEF ;DEFINE I/O REQUEST PACKET $PCBDEF ;DEFINE PROCESS CONTROL BLOCK $PHDDEF ;DEFINE PROCESS HEADER $PRVDEF ;DEFINE VMS PRIVS $TQEDEF ;DEFINE TIMER QUEUE ENTRY $UCBDEF ;DEFINE UNIT CONTROL BLOCK $VECDEF ;DEFINE VECTOR OFFSETS ; .SBTTL DRIVER PROLOGUE TABLE ;+ --- ; ; DRIVER CHARACTERISTICS ; ;- --- DPTAB - END=LAV_END, -;END OF DRIVER (SIZE) ADAPTER=NULL, -;UNIBUS DEVICE UCBSIZE=UCB$C_Length, -;UNIT CONTROL BLOCK LENGTH MAXUNITS=1, -;ONLY ONE LAV0 DEVICE UNLOAD=LAV_UNLOAD, -;UNLOAD ROUTINE NAME=LAVDRIVER, -;DRIVER NAME SMP=YES ;Works under SMP ;+ --- ; ; INITIALIZATION INFORMATION ; ;- --- DPT_STORE INIT DPT_STORE UCB,UCB$B_FLCK,B,SPL$C_IOLOCK8 ;FORK IPL LEVEL (UBA #1 = 8) DPT_STORE UCB,UCB$B_DIPL,B,21 ;DEVICE IPL LEVEL (BR5 = 21) DPT_STORE UCB,UCB$L_DEVCHAR,L, -;DEVICE CHARACTERISTICS: <- DEV$M_AVL! -; DEVICE AVAILABLE DEV$M_REC! -; RECORD ORIENTED DEV$M_IDV! -; INPUT DEVICE DEV$M_SHR -; SHARED > DPT_STORE UCB,UCB$W_DEVBUFSIZ, -;DEVICE BUFFER SIZE W,36 ; (36 bytes) ;+ --- ; ; RE-INITIALIZATION INFORMATION ; ;- --- DPT_STORE REINIT DPT_STORE DDB,DDB$L_DDT,D,LAV$DDT ;DRIVER DISPATCH TABLE DPT_STORE CRB, -;CONTROLLER INITIALIZATION ROUTINE CRB$L_INTD+VEC$L_INITIAL,D,- LAV_CONTROLLER_INIT DPT_STORE CRB, -;UNIT INITIALIZATION ROUTINE CRB$L_INTD+VEC$L_UNITINIT,D,- LAV_UNIT_INIT DPT_STORE END ; .SBTTL DRIVER DISPATCH TABLE ;+ --- ; ; ADDRESSES OF VARIOUS DRIVER ENTRY POINTS ; ;- --- DDTAB - DEVNAM=LAV, -;DEVICE NAME START=0, -;ADDRESS OF START I/O ENTRY POINT UNSOLIC=0, -;ADDRESS OF UNSOLICITED INT. ROUTINE FUNCTB=LAV_FUNCTABLE, -;ADDRESS OF FUNCTION DECISION TABLE CANCEL=0, -;ADDRESS OF CANCEL I/O ENTRY POINT REGDMP=0, -;ADDRESS OF REGISTER DUMP ROUTINE DIAGBF=0, -;SIZE OF DIAGNOSTIC BUFFER ERLGBF=0 ;SIZE OF ERROR LOG BUFFER ; .SBTTL FUNCTION DECISION TABLE LAV_FUNCTABLE: ;+ --- ; ; SPECIFY LEGAL FUNCTION CODES ; ;- --- FUNCTAB , -;LEGAL FUNCTION CODE ENTRY < -; READVBLK, -;READ VIRTUAL BLOCK READLBLK, -;READ LOGICAL BLOCK READPBLK, -;READ PHYSICAL BLOCK WRITEVBLK, -;WRITE VIRTUAL BLOCK WRITELBLK, -;WRITE LOGICAL BLOCK WRITEPBLK, -;WRITE PHYSICAL BLOCK > ;+ --- ; ; SPECIFY BUFFERED I/O FUNCTION CODES ; ;- --- FUNCTAB , -;BUFFERED FUNCTION CODE ENTRY <> ;NONE ;+ --- ; ; SPECIFY 1ST FDT ROUTINE ; ;- --- FUNCTAB GET_LOAD_AVE, -;GET THE CURRENT LOAD AVERAGES < -;USED BY: READVBLK, -;READ VIRTUAL BLOCK READLBLK, -;READ LOGICAL BLOCK READPBLK -;READ PHYSICAL BLOCK > ; ;+ --- ; ; SPECIFY 2ND FDT ROUTINE ; ;- --- FUNCTAB SET_PRIORITIES, -;SET WHICH PRIORITIES ARE SCANNED < -;USED BY: WRITEVBLK, -;WRITE VIRTUAL BLOCK WRITELBLK, -;WRITE LOGICAL BLOCK WRITEPBLK -;WRITE PHYSICAL BLOCK > ; ; .SBTTL READ FDT ROUTINE ;+ --- ; ; GET_LOAD_AVE READ FDT ROUTINE ; ; FUNCTIONAL DESCRIPTION: ; ; All this routine does is verify the read arguments and return M1->M15 ; ; INPUTS: ; ; R3 = I/O Packet address ; R4 = Current Process Control Block address ; R5 = Unit Control Block Address ; R6 = Channel Control Block Address ; R7 = Function Code ; R8 = Scratch ; R9 = Scratch ; ; 0(AP) --> Read Size ; 4(AP) --> Read Buffer ; ; OUTPUTS: ; ; none ; ;- --- GET_LOAD_AVE: ;+ --- ; Get Read Size (limited to 36 bytes) ;- --- MOVZWL 4(AP),R0 ;Get Read Size CMPL R0,#36 ;Bigger than 36?? BLEQU 10$ ;No: MOVL #36,R0 ;Yes: Truncate to 36 bytes 10$: ;+ --- ; Make sure that the buffer is writeable ;- --- IFNOWRT R0,@(AP),ACCVIO ;Return SS$_ACCVIO if no write ;+ --- ; Move the data ;- --- PUSHR #^M<R0,R1,R2,R3,R4,R5> ;Be conservative!!! MOVC3 R0,M1,@(AP) ;Move the Data POPR #^M<R0,R1,R2,R3,R4,R5> ;Restore registers ;+ --- ; Complete the I/O request ;- --- ASHL #16,R0,R0 ;Set transfer size BISW2 #SS$_NORMAL,R0 ;Set Completion code JMP G^EXE$FINISHIOC ;Complete the request ;+ --- ; Return an access violation ;- --- ACCVIO: MOVZWL #SS$_ACCVIO,R0 ;Set return code CLRL R1 JMP G^EXE$ABORTIO ;Abort the I/O request .SBTTL WRITE FDT ROUTINE ;+ --- ; ; SET_PRIORITIES WRITE FDT ROUTINE ; ; FUNCTIONAL DESCRIPTION: ; ; All this routine does is verify the write arguments and change the ; priorities mask. ; ; INPUTS: ; ; R3 = I/O Packet address ; R4 = Current Process Control Block address ; R5 = Unit Control Block Address ; R6 = Channel Control Block Address ; R7 = Function Code ; R8 = Scratch ; R9 = Scratch ; ; 0(AP) --> Write Size ; 4(AP) --> Write Buffer ; ; OUTPUTS: ; ; none ; ;- --- SET_PRIORITIES: ;+ --- ; Check privs (must have CMKRNL) ;- --- ASSUME PHD$Q_PRIVMSK EQ 0 BBC #PRV$V_CMKRNL,@PCB$L_PHD(R4),NOPRIV ;+ --- ; Get Write Size (limited to 4 bytes) ;- --- MOVZWL 4(AP),R0 ;Get Write Size CMPL R0,#4 ;Bigger than 4?? BLEQU 10$ ;No: MOVL #4,R0 ;Yes: Truncate to 4 bytes 10$: ;+ --- ; Make sure that the buffer is readable ;- --- IFNORD R0,@(AP),ACCVIO ;Return SS$_ACCVIO if no write ;+ --- ; Move the data ;- --- MOVL @(AP),PRIORITY_MASK ;+ --- ; Complete the I/O request ;- --- ASHL #16,R0,R0 ;Set transfer size BISW2 #SS$_NORMAL,R0 ;Set Completion code JMP G^EXE$FINISHIOC ;Complete the request ;+ --- ; Return and access violation ;- --- NOPRIV: MOVZWL #SS$_NOPRIV,R0 ;Set return code CLRL R1 JMP G^EXE$ABORTIO ;Abort the I/O request .SBTTL CONTROLLER INITIALIZATION ROUTINE ;+ --- ; ; ROUTINE CALLED WHEN THE LOADING PROCEDURE SETS UP THE CONTROLLER ; ; INPUT REGISTERS: ; R0 = SCRATCH ; R5 = ADDRESS OF UNIT CONTROL BLOCK ; ; REGISTERS MODIFIED: ; R0 = SCRATCH ; ; SIDE EFFECTS: ; LOAD AVERAGE WATCHER IS SET UP ; ;- --- LAV_CONTROLLER_INIT: TSTL HAVEINITED ; If power failure recovery, BEQL 1$ ; don't reenter the TQE block. RSB 1$: MOVL #1,HAVEINITED ; SET LOAD AVES TO ZERO CLRF M1 CLRF M5 CLRF M15 CLRF P1 CLRF P5 CLRF P15 CLRF Q1 CLRF Q5 CLRF Q15 ; SET UP THE LOAD AVERAGE WATCHING CODE (INSERT THE TIMER QUEUE ENTRY) ; ; Fork to a lower IPL ; MOVQ R4,-(SP) ; Not allowed to modify R4 or R5 MOVAQ FKB,R5 PUSHAB 10$ ; Trick EXE$FORK into returning to us. PUSHAB 20$ ; Address to fork to JMP G^EXE$FORK 10$: MOVQ (SP)+,R4 ; Restore R4, R5 15$: RSB ; Return from unit init routine ; ; Now running at IPL 6 ; 20$: MOVAB UPDATE_LOAD_AVERAGE,TQE_PC MOVAL TQE,R5 MOVB #1,RUNNING ; CURRENTLY RUNNING CLRB STOPPING ; AND NOT STOPPING READ_SYSTIME R0 JSB G^EXE$INSTIMQ 30$: RSB ;AND RETURN ; .SBTTL CONTROLLER UNLOAD ROUTINE ;+ --- ; ; ROUTINE CALLED WHEN THE DRIVER IS RELOADED ; ; INPUT REGISTERS: ; R0 = SCRATCH ; R5 = ADDRESS OF UNIT CONTROL BLOCK ; ; REGISTERS MODIFIED: ; R0 = SCRATCH ; ; SIDE EFFECTS: ; 1st call TQE entry is removed ; 2nd call driver is unloaded ;- --- LAV_UNLOAD: TSTB RUNNING ; If not running, unload BNEQ 10$ MOVL #SS$_NORMAL,R0 ; If not running, ok to unload driver RSB 10$: MOVB #1,STOPPING ; SET THE STOPPING FLAG CLRL R0 RSB ; .SBTTL UNIT INITIALIZATION ROUTINE ;+ --- ; ; ROUTINE CALLED WHEN THE LOADING PROCEDURE SETS UP THE UNIT. ; THE DEVICE ONLINE BIT IS SET IN THE UCB. ; ; INPUT REGISTERS: ; R0 = SCRATCH ; R5 = ADDRESS OF UNIT CONTROL BLOCK ; ; REGISTERS MODIFIED: ; R0 = SCRATCH ; ; SIDE EFFECTS: ; UNIT ONLINE BIT IS SET IN UCB ; ;- --- LAV_UNIT_INIT: BISW #UCB$M_ONLINE,UCB$W_STS(R5) ;SET STATUS = ONLINE RSB ; .SBTTL LOCAL DATA ;+ --- ; Local Data for the Load Average Watcher ;- --- M1: .FLOAT 0.0 ;1 Min. Load Ave. M5: .FLOAT 0.0 ;5 Min. Load Ave. M15: .FLOAT 0.0 ;15 Min. Load Ave. P1: .FLOAT 0.0 ;1 Min. Priority Ave. P5: .FLOAT 0.0 ;5 Min. Priority Ave. P15: .FLOAT 0.0 ;15 Min. Priority Ave. Q1: .FLOAT 0.0 ;1 Min. Ave disk queue len Q5: .FLOAT 0.0 ;5 Min. Ave disk queue len Q15: .FLOAT 0.0 ;15 Min. Ave disk queue len F1: .FLOAT 0.983471453 ;1 min. load ave. constants F11: .FLOAT 0.016528547 F2: .FLOAT 0.996672213 ;5 min. load ave. constants F12: .FLOAT 0.003327787 F3: .FLOAT 0.998889506 ;15 min. load ave. constants F13: .FLOAT 0.001110494 TQE: .LONG 0 ;TIMER QUEUE ELEMENT (FLINK) .LONG 0 ;(BLINK) .WORD 0 ;SIZE .BYTE DYN$C_TQE ;TYPE .BYTE TQE$C_SSREPT ;REQUEST == REPEAT TQE_PC: .LONG 0 ;PC TO CALL .LONG 0 ;N/A .LONG 0 ;N/A TQE_DUE:.LONG 0 ;DUE TIME .LONG 0 .LONG 100000*100 ;Repeat time (1 Sec.) .LONG 0 HAVEINITED: .LONG 0 ; Set if alread initied RUNNING: .BYTE 0 ; True if TQE entry is in queue. STOPPING: .BYTE 0 ; SET TO REQUEST TQE TO ABORT PRIORITY_MASK: .LONG 0 ; Check all priorities FKB: .LONG 0 ; FQFL .LONG 0 ; FQBL .WORD 0 ; SIZE .BYTE DYN$C_FRK ; TYPE .BYTE IPL$_TIMER ; IPL LOW ENOUGH TO LOCK TIMER FKB_PC: .LONG 0 ; PC .LONG 0 ; R3 .LONG 0 ; R4 .SBTTL Load Average Watching Code UPDATE_LOAD_AVERAGE: ;We link into the ;VMS kernel via the timer q ;and is entered by JSB when ;each 1 sec. interval ends. ;R0-R4 are available ;--- ; See if we are supposed to abort ;--- TSTB STOPPING BEQL 10$ MOVL G^EXE$AR_TQENOREPT,R5 CLRB RUNNING RSB 10$: CLRL R2 ;Initialize the run count=0 ;+ --- ; Check the run queues for the number of processes in 'COM' state ;- --- CLRL R1 ;Initialize summary word pos=0 LOCK SCHED BICL3 PRIORITY_MASK,@#SCH$GL_Comqs,R4 ;Get masked queues Find_Comq: ;Find a run queue with entries SUBL3 R1,#32,R0 ;Calculate #bits left (32-R1) FFS R1,R0,R4,R1 ;Look for an active queue BEQL Ncomo ;None: look for procs waiting ; for inswap MOVAQ @#SCH$AQ_Comh[R1],R0 ;Got one: get its queue header MOVL R0,R3 ;Save terminating address 10$: MOVL (R0),R0 ;Get the next process in the q CMPL R0,R3 ;End of queue? BEQL 20$ ;Yes: look for next queue INCL R2 ;No: count this process BRB 10$ ;and try the next one 20$: INCL R1 ;Queue done, look for next one BRB Find_Comq ;+ --- ; Check the COMO queues for the number of processes in 'COM' state (outswap) ;- --- Ncomo: CLRL R1 ;Initialize summary word pos=0 BICL3 PRIORITY_MASK,@#SCH$GL_Comoqs,R4 ;Get masked queues Find_Comoq: ;Find a run queue with entries SUBL3 R1,#32,R0 ;Calculate #bits left (32-R1) FFS R1,R0,R4,R1 ;Look for an active queue BEQL Nwait ;None: look for procs waiting ; for resources MOVAQ @#SCH$AQ_Comoh[R1],R0 ;Got one: get its queue header MOVL R0,R3 ;Save terminating address 10$: MOVL (R0),R0 ;Get the next process in the q CMPL R0,R3 ;End of queue? BEQL 20$ ;Yes: look for next queue INCL R2 ;No: count this process BRB 10$ ;and try the next one 20$: INCL R1 ;Queue done, look for next one BRB Find_Comoq ;+ --- ; Count processes in collided page wait ;- --- Nwait: MOVAQ @#SCH$GQ_Colpgwq,R0 ;Get the collided page wait q 10$: MOVL (R0),R0 ;Get the next process in the q CMPL R0,#SCH$GQ_Colpgwq ;End of queue? BEQL Npfw ;Yes: look at page fault waits INCL R2 ;No: count this process BRB 10$ ;and try the next one ;+ --- ; Count processes in page fault wait ;- --- Npfw: MOVAQ @#SCH$GQ_PfwQ,R0 ;Get the page fault wait q 10$: MOVL (R0),R0 ;Get the next process in the q CMPL R0,#SCH$GQ_Pfwq ;End of queue? BEQL Nfpw ;Yes: look at free page waits INCL R2 ;No: count this process BRB 10$ ;and try the next one ;+ --- ; Count processes in free page wait ;- --- Nfpw: MOVAQ @#SCH$GQ_FpgwQ,R0 ;Get the free page wait q 10$: MOVL (R0),R0 ;Get the next process in the q CMPL R0,#SCH$GQ_Fpgwq ;End of queue? BEQL Count_Done ;Yes: all done INCL R2 ;No: count this process BRB 10$ ;and try the next one Count_Done: UNLOCK SCHED ; ; Count done, now scan through each CPU. Store the LOWEST priority ; found and the number of executing CPUs. ; CLRL R3 ; Lowest priority CLRL R4 ; Number of CPUs active CLRL R1 ; Current CPU index 11$: SUBL3 R1,#32,R0 ;Calculate #bits left (32-R1) FFS R1,R0,@#SMP$GL_ACTIVE_CPUS,R1 ;Look for an active CPU BEQL 35$ 15$: MOVL g^SMP$GL_CPU_DATA[R1],R0 ; Get the CPU database BEQL 30$ ; This CPU doesn't exist INCL R4 ; Seen one more CPU CMPL CPU$L_CURPCB(R0),@#SCH$AR_NULLPCB ; Running 'the null job'? BEQL 20$ BBS CPU$B_CUR_PRI(R0),PRIORITY_MASK,20$ ; but priority is 'masked' INCL R2 ; CPU is active. 20$: CMPB CPU$B_CUR_PRI(R0),R3 ; Store the lowest executing priority BLEQU 30$ MOVB CPU$B_CUR_PRI(R0),R3 30$: INCL R1 BRB 11$ ; Check for all 32 CPUs. 35$: ;+ --- ; Count done, calculate the load ave. ;- --- CVTLF R2,R2 ;Float the count of processes CVTLF R4,R4 ;Float the count of CPUs DIVF2 R4,R2 ;Load is Processes/CPUs. ; 1 min. load ave. MULF3 R2,F11,R0 ;La=OldLa*F+NewLa*(1-F) MULF3 M1,F1,R1 ADDF3 R0,R1,M1 ; 5 min. load ave. MULF3 R2,F12,R0 MULF3 M5,F2,R1 ADDF3 R0,R1,M5 ; 15 min. load ave. MULF3 R2,F13,R0 MULF3 M15,F3,R1 ADDF3 R0,R1,M15 CMPB R3,#255 ; NULL JOB BNEQ 40$ MOVB #32,R3 ; TREAT AS PRIORITY 0 40$: SUBB3 R3,#32,R2 CVTBF R2,R2 ; 1 min. priority ave. MULF3 R2,F11,R0 ;La=OldLa*F+NewLa*(1-F) MULF3 P1,F1,R1 ADDF3 R0,R1,P1 ; 5 min. load ave. MULF3 R2,F12,R0 MULF3 P5,F2,R1 ADDF3 R0,R1,P5 ; 15 min. load ave. MULF3 R2,F13,R0 MULF3 P15,F3,R1 ADDF3 R0,R1,P15 ; ; Update the disk queue length information ; QUEUE_LEN: CLRL R2 ; R2 = Sun of queue lengths PUSHR #^M<R10,R11> CLRQ R10 ; Indicate start of I/O d.b. 10$: JSB G^IOC$SCAN_IODB ; Get next DDB and UCB into R10, R11 BLBC R0,40$ ; no more, done CMPB #DC$_DISK,UCB$B_DEVCLASS(R10) ; Is this controller a disk? BEQL 20$ CLRL R10 ; Go for next controller BRB 10$ 20$: BBC #DEV$V_MNT,UCB$L_DEVCHAR(R10),10$ ; Skip if not mounted BITL #<DEV$M_CDP+DEV$M_SSM>,UCB$L_DEVCHAR2(R10) ; class driver or shadow set member? BNEQ 10$ ; if so, skip ; BBS UCB$V_MNTVERIP,UCB$L_STS(R10),10$ ; Mount verify in progress CVTWL UCB$W_QLEN(R10),R0 ; Get queue length BGEQ 30$ CLRL R0 ; negative queu length is a temporary condition 30$: CMPL R0,R2 BLEQ 10$ MOVL R0,R2 BRB 10$ 40$: POPR #^M<R10,R11> ; restore registers CVTLF R2,R2 ;Float the count ; 1 min. queue ave. MULF3 R2,F11,R0 ;La=OldLa*F+NewLa*(1-F) MULF3 Q1,F1,R1 ADDF3 R0,R1,Q1 ; 5 min. queue ave. MULF3 R2,F12,R0 MULF3 Q5,F2,R1 ADDF3 R0,R1,Q5 ; 15 min. queue ave. MULF3 R2,F13,R0 MULF3 Q15,F3,R1 ADDF3 R0,R1,Q15 RSB ;Return to clock dispatcher .SBTTL END OF DRIVER ;+ --- ; ; END OF DRIVER ; ;- --- LAV_END: ;LET DPTAB KNOW THE DRIVER SIZE ; .END
kvc@nrcvax.UUCP (Kevin Carosso) (06/13/88)
In article <8806030523.AA01300@ucbvax.Berkeley.EDU> RAND@merrimack.EDU ("Rand P. Hall") writes: >Does anyone have/know of the availability of the LoadAverage device >driver source code? The driver *image* was shipped with older versions >of the Columbia University FINGER program. I find it to be a nice >metric of system load and would rather not see it die under V5. > >In the event that the source never surfaces, has anyone done anything similar? If you're talking about Dave Kashtan's LAVDRIVER, I have a copy of it somewhere converted to VMS V5. I'll dig it up and post it if I can find it and it works on my 5.0 system. /Kevin Carosso kvc@nrc.com Network Research Co. kvc@ymir.bitnet kvc@nrcvax.uucp