From:	SMTP%"turion@research.ptt.nl" 21-MAR-1994 17:43:03.97
To:	EVERHART
CC:	
Subj:	part 8 status tool

X-Newsgroups: comp.os.vms
From: turion_s@dnlts0research.ptt.nl. (Paul Turion)
Subject: part 8 status tool
Message-ID: <1994Mar21.144429.1387@news.research.ptt.nl>
Sender: turion_s@research.ptt.nl (Paul Turion)
Nntp-Posting-Host: dnlts0.research.ptt.nl
Reply-To: turion@research.ptt.nl
Organization: PTT Research
X-Newsreader: mxrn 6.18-4
Date: Mon, 21 Mar 1994 14:44:29 GMT
Lines: 505
To: Info-VAX@CRVAX.SRI.COM
X-Gateway-Source-Info: USENET


-- 
 ------- --------------------  			Paul Turion 
| p t t |  r e s e a r c h   |			The Netherlands
|      _|                    | 			e-mail address
|    _|_|   .  .  .  .  .    |			P.Turion@research.ptt.nl
|___|_|      
My interest is in the future because
I am going to spend the rest of my life there.
-+-+-+-+-+-+-+-+ START OF PART 8 -+-+-+-+-+-+-+-+
X`032
X    .SBTTL    FUNCTION DECISION TABLE
XLAV_FUNCTABLE:
X;+ ---
X;
X; SPECIFY LEGAL FUNCTION CODES
X;
X;- ---
X    FUNCTAB ,           -;LEGAL FUNCTION CODE ENTRY
X        <           -;
X         READVBLK,     -;READ VIRTUAL BLOCK
X         READLBLK,     -;READ LOGICAL BLOCK
X         READPBLK,     -;READ PHYSICAL BLOCK
X         WRITEVBLK,    -;WRITE VIRTUAL BLOCK
X         WRITELBLK,    -;WRITE LOGICAL BLOCK
X         WRITEPBLK,    -;WRITE PHYSICAL BLOCK
X        >
X;+ ---
X;
X; SPECIFY BUFFERED I/O FUNCTION CODES
X;
X;- ---
X    FUNCTAB ,           -;BUFFERED FUNCTION CODE ENTRY
X        <>        ;NONE
X;+ ---
X;
X; SPECIFY 1ST FDT ROUTINE
X;
X;- ---
X    FUNCTAB GET_LOAD_AVE,  -;GET THE CURRENT LOAD AVERAGES
X        <           -;USED BY:
X         READVBLK,     -;READ VIRTUAL BLOCK
X         READLBLK,     -;READ LOGICAL BLOCK
X         READPBLK      -;READ PHYSICAL BLOCK
X        >        ;
X;+ ---
X;
X; SPECIFY 2ND FDT ROUTINE
X;
X;- ---
X    FUNCTAB SET_PRIORITIES, -;SET WHICH PRIORITIES ARE SCANNED
X        <        -;USED BY:
X         WRITEVBLK,    -;WRITE VIRTUAL BLOCK
X         WRITELBLK,    -;WRITE LOGICAL BLOCK
X         WRITEPBLK    -;WRITE PHYSICAL BLOCK
X        >        ;
X;
X`032
X    .SBTTL    READ FDT ROUTINE
X;+ ---
X;
X; GET_LOAD_AVE        READ FDT ROUTINE
X;
X; FUNCTIONAL DESCRIPTION:
X;
X;    All this routine does is verify the read arguments and return M1->M15
X;
X; INPUTS:
X;
X;    R3 = I/O Packet address
X;    R4 = Current Process Control Block address
X;    R5 = Unit Control Block Address
X;    R6 = Channel Control Block Address
X;    R7 = Function Code
X;    R8 = Scratch
X;    R9 = Scratch
X;
X;    0(AP) --> Read Size
X;    4(AP) --> Read Buffer
X;
X; OUTPUTS:
X;
X;    none
X;
X;- ---
XGET_LOAD_AVE:
X`032
X;+ ---
X; Get Read Size (limited to 36 bytes)
X;- ---
X    MOVZWL    4(AP),R0            ;Get Read Size
X    CMPL    R0,#36                ;Bigger than 36??
X    BLEQU    10$                ;No:
X    MOVL    #36,R0                ;Yes: Truncate to 36 bytes
X10$:
X;+ ---
X; Make sure that the buffer is writeable
X;- ---
X    IFNOWRT R0,@(AP),ACCVIO            ;Return SS$_ACCVIO if no write
X;+ ---
X; Move the data
X;- ---
X    PUSHR    #`094M<R0,R1,R2,R3,R4,R5>        ;Be conservative!!!
X    MOVC3    R0,M1,@(AP)            ;Move the Data
X    POPR    #`094M<R0,R1,R2,R3,R4,R5>        ;Restore registers
X;+ ---
X; Complete the I/O request
X;- ---
X    ASHL    #16,R0,R0            ;Set transfer size
X    BISW2    #SS$_NORMAL,R0            ;Set Completion code
X    JMP    G`094EXE$FINISHIOC            ;Complete the request
X`032
X`032
X;+ ---
X; Return an access violation
X;- ---
XACCVIO:
X    MOVZWL    #SS$_ACCVIO,R0            ;Set return code
X    CLRL    R1
X    JMP    G`094EXE$ABORTIO            ;Abort the I/O request
X`032
X`032
X    .SBTTL    WRITE FDT ROUTINE
X;+ ---
X;
X; SET_PRIORITIES    WRITE FDT ROUTINE
X;
X; FUNCTIONAL DESCRIPTION:
X;
X;    All this routine does is verify the write arguments and change the
X;    priorities mask.
X;
X; INPUTS:
X;
X;    R3 = I/O Packet address
X;    R4 = Current Process Control Block address
X;    R5 = Unit Control Block Address
X;    R6 = Channel Control Block Address
X;    R7 = Function Code
X;    R8 = Scratch
X;    R9 = Scratch
X;
X;    0(AP) --> Write Size
X;    4(AP) --> Write Buffer
X;
X; OUTPUTS:
X;
X;    none
X;
X;- ---
XSET_PRIORITIES:
X;+ ---
X; Check privs (must have CMKRNL)
X;- ---
X`032
X    ASSUME    PHD$Q_PRIVMSK EQ 0
X    BBC    #PRV$V_CMKRNL,@PCB$L_PHD(R4),NOPRIV
X`032
X;+ ---
X; Get Write Size (limited to 4 bytes)
X;- ---
X    MOVZWL    4(AP),R0            ;Get Write Size
X    CMPL    R0,#4                ;Bigger than 4??
X    BLEQU    10$                ;No:
X    MOVL    #4,R0                ;Yes: Truncate to 4 bytes
X10$:
X;+ ---
X; Make sure that the buffer is readable
X;- ---
X    IFNORD    R0,@(AP),ACCVIO            ;Return SS$_ACCVIO if no write
X;+ ---
X; Move the data
X;- ---
X    MOVL    @(AP),PRIORITY_MASK
X;+ ---
X; Complete the I/O request
X;- ---
X    ASHL    #16,R0,R0            ;Set transfer size
X    BISW2    #SS$_NORMAL,R0            ;Set Completion code
X    JMP    G`094EXE$FINISHIOC            ;Complete the request
X`032
X;+ ---
X; Return and access violation
X;- ---
XNOPRIV:
X    MOVZWL    #SS$_NOPRIV,R0            ;Set return code
X    CLRL    R1
X    JMP    G`094EXE$ABORTIO            ;Abort the I/O request
X`032
X`032
X    .SBTTL    CONTROLLER INITIALIZATION ROUTINE
X;+ ---
X;
X; ROUTINE CALLED WHEN THE LOADING PROCEDURE SETS UP THE CONTROLLER
X;
X; INPUT REGISTERS:
X;    R0 = SCRATCH
X;    R5 = ADDRESS OF UNIT CONTROL BLOCK
X;
X; REGISTERS MODIFIED:
X;    R0 = SCRATCH
X;
X; SIDE EFFECTS:
X;    LOAD AVERAGE WATCHER IS SET UP
X;
X;- ---
XLAV_CONTROLLER_INIT:
X    TSTL    HAVEINITED        ; If power failure recovery,
X    BEQL    1$               ; don't reenter the TQE block.
X    RSB
X1$:    MOVL    #1,HAVEINITED
X`032
X; SET LOAD AVES TO ZERO
X`032
X    CLRF    M1
X    CLRF    M5
X    CLRF    M15
X    CLRF    P1
X    CLRF    P5
X    CLRF    P15
X    CLRF    Q1
X    CLRF    Q5
X    CLRF    Q15
X`032
X; SET UP THE LOAD AVERAGE WATCHING CODE (INSERT THE TIMER QUEUE ENTRY)
X;
X; Fork to a lower IPL
X;
X    MOVQ    R4,-(SP)        ; Not allowed to modify R4 or R5
X    MOVAQ    FKB,R5
X    PUSHAB    10$            ; Trick EXE$FORK into returning to us.
X    PUSHAB    20$            ; Address to fork to
X    JMP    G`094EXE$FORK
X10$:
X    MOVQ    (SP)+,R4        ; Restore R4, R5
X15$:    RSB                ; Return from unit init routine
X;
X; Now running at IPL 6
X;
X20$:    MOVAB    UPDATE_LOAD_AVERAGE,TQE_PC
X    MOVAL    TQE,R5
X    MOVB    #1,RUNNING        ; CURRENTLY RUNNING
X    CLRB    STOPPING        ; AND NOT STOPPING
XIF    NDF,VMS_V5
X    MOVQ    @#EXE$GQ_SYSTIME,TQE_DUE
X    INSQUE    TQE,@#EXE$GL_TQFL
XIFF
X    READ_SYSTIME R0
X    JSB    G`094EXE$INSTIMQ
XENDC
X30$:    RSB                    ;AND RETURN
X;
X`032
X    .SBTTL    CONTROLLER UNLOAD ROUTINE
X;+ ---
X;
X; ROUTINE CALLED WHEN THE DRIVER IS RELOADED
X;
X; INPUT REGISTERS:
X;    R0 = SCRATCH
X;    R5 = ADDRESS OF UNIT CONTROL BLOCK
X;
X; REGISTERS MODIFIED:
X;    R0 = SCRATCH
X;
X; SIDE EFFECTS:
X;    1st call TQE entry is removed
X;    2nd call driver is unloaded
X;- ---
XLAV_UNLOAD:
X    TSTB    RUNNING            ; If not running, unload
X    BNEQ    10$
X    MOVL    #SS$_NORMAL,R0        ; If not running, ok to unload driver
X    RSB
X10$:    MOVB    #1,STOPPING        ; SET THE STOPPING FLAG
X    CLRL    R0
X    RSB
X;
X`032
X    .SBTTL    UNIT INITIALIZATION ROUTINE
X;+ ---
X;
X; ROUTINE CALLED WHEN THE LOADING PROCEDURE SETS UP THE UNIT.
X;  THE DEVICE ONLINE BIT IS SET IN THE UCB.
X;
X; INPUT REGISTERS:
X;    R0 = SCRATCH
X;    R5 = ADDRESS OF UNIT CONTROL BLOCK
X;
X; REGISTERS MODIFIED:
X;    R0 = SCRATCH
X;
X; SIDE EFFECTS:
X;    UNIT ONLINE BIT IS SET IN UCB
X;
X;- ---
XLAV_UNIT_INIT:
X    BISW    #UCB$M_ONLINE,UCB$W_STS(R5)    ;SET STATUS = ONLINE
X    RSB
X;
X`032
X    .SBTTL    LOCAL DATA
X;+ ---
X; Local Data for the Load Average Watcher
X;- ---
XM1:    .FLOAT    0.0                ;1  Min. Load Ave.
XM5:    .FLOAT    0.0                ;5  Min. Load Ave.
XM15:    .FLOAT    0.0                ;15 Min. Load Ave.
X`032
XP1:    .FLOAT    0.0                ;1  Min. Priority Ave.
XP5:    .FLOAT    0.0                ;5  Min. Priority Ave.
XP15:    .FLOAT    0.0                ;15 Min. Priority Ave.
X`032
XQ1:    .FLOAT    0.0                ;1  Min. Ave disk queue len
XQ5:    .FLOAT    0.0                ;5  Min. Ave disk queue len
XQ15:    .FLOAT    0.0                ;15 Min. Ave disk queue len
X`032
XF1:    .FLOAT    0.983471453            ;1 min. load ave. constants
XF11:    .FLOAT    0.016528547
X`032
XF2:    .FLOAT    0.996672213            ;5 min. load ave. constants
XF12:    .FLOAT    0.003327787
X`032
XF3:    .FLOAT    0.998889506            ;15 min. load ave. constants
XF13:    .FLOAT    0.001110494
X`032
X`032
XTQE:    .LONG    0                ;TIMER QUEUE ELEMENT (FLINK)
X    .LONG    0                ;(BLINK)
X    .WORD    TQE_LEN                ;SIZE
X    .BYTE    DYN$C_TQE            ;TYPE
X    .BYTE    TQE$C_SSREPT            ;REQUEST == REPEAT
XTQE_PC: .LONG    0                ;PC TO CALL
X    .LONG    0                ;N/A
X    .LONG    0                ;N/A
XTQE_DUE:.LONG    0                ;DUE TIME
X    .LONG    0
X    .LONG    100000*100            ;Repeat time (1 Sec.)
X    .LONG    0
XTQE_LEN = .-TQE
X`032
XHAVEINITED:
X    .LONG    0                ; Set if alread initied
XRUNNING:
X    .BYTE    0                ; True if TQE entry is in queue.
XSTOPPING:
X    .BYTE    0                ; SET TO REQUEST TQE TO ABORT
XPRIORITY_MASK:
X    .LONG    0                ; Check all priorities
X`032
XFKB:    .LONG    0                ; FQFL
X    .LONG    0                ; FQBL
X    .WORD    0                ; SIZE
X    .BYTE    DYN$C_FRK            ; TYPE
X    .BYTE    IPL$_TIMER            ; IPL LOW ENOUGH TO LOCK TIMER
XFKB_PC: .LONG    0                ; PC
X    .LONG    0                ; R3
X    .LONG    0                ; R4
X`032
X    .SBTTL    Load Average Watching Code
X`032
XUPDATE_LOAD_AVERAGE:                ;We link into the
X                        ;VMS kernel via the timer q
X                        ;and is entered by JSB when
X                        ;each 1 sec. interval ends.
X                        ;R0-R4 are available
X`032
X;---
X; See if we are supposed to abort
X;---
X    TSTB    STOPPING
X    BEQL    10$
XIF    NDF,VMS_V5
X    MOVAL    @#EXE$AL_TQENOREPT,R5
XIFF
X    MOVL    G`094EXE$AR_TQENOREPT,R5
XENDC
X    CLRB    RUNNING
X    RSB
X10$:
X`032
X    CLRL    R2                ;Initialize the run count=0
X;+ ---
X; Check the run queues for the number of processes in 'COM' state
X;- ---
X    CLRL    R1                ;Initialize summary word pos=0
X`032
XIF    NDF,VMS_V5
X    DSBINT    #IPL$_SYNCH
XIFF
X    LOCK    SCHED
XENDC
X    BICL3    PRIORITY_MASK,@#SCH$GL_Comqs,R4 ;Get masked queues
XFind_Comq:                    ;Find a run queue with entries
X    SUBL3    R1,#32,R0            ;Calculate #bits left (32-R1)
X    FFS    R1,R0,R4,R1            ;Look for an active queue
X    BEQL    Ncomo                ;None: look for procs waiting
X                        ;    for inswap
X    MOVAQ    @#SCH$AQ_Comh`091R1`093,R0        ;Got one: get its queue heade
Vr
X    MOVL    R0,R3                ;Save terminating address
X`032
X10$:    MOVL    (R0),R0                ;Get the next process in the q
X    CMPL    R0,R3                ;End of queue?
X    BEQL    20$                ;Yes: look for next queue
X    INCL    R2                ;No: count this process
X    BRB    10$                ;and try the next one
X`032
X20$:    INCL    R1                ;Queue done, look for next one
X    BRB    Find_Comq
X`032
X;+ ---
X; Check the COMO queues for the number of processes in 'COM' state (outswap)
X;- ---
XNcomo:    CLRL    R1                ;Initialize summary word pos=0
X    BICL3    PRIORITY_MASK,@#SCH$GL_Comoqs,R4 ;Get masked queues
XFind_Comoq:                    ;Find a run queue with entries
X    SUBL3    R1,#32,R0            ;Calculate #bits left (32-R1)
X    FFS    R1,R0,R4,R1            ;Look for an active queue
X    BEQL    Nwait                ;None: look for procs waiting
X                        ;    for resources
X    MOVAQ    @#SCH$AQ_Comoh`091R1`093,R0        ;Got one: get its queue head
Ver
X    MOVL    R0,R3                ;Save terminating address
X`032
X10$:    MOVL    (R0),R0                ;Get the next process in the q
X    CMPL    R0,R3                ;End of queue?
X    BEQL    20$                ;Yes: look for next queue
X    INCL    R2                ;No: count this process
X    BRB    10$                ;and try the next one
X`032
X20$:    INCL    R1                ;Queue done, look for next one
X    BRB    Find_Comoq
X`032
X;+ ---
X; Count processes in collided page wait
X;- ---
XNwait:
X    MOVAQ    @#SCH$GQ_Colpgwq,R0        ;Get the collided page wait q
X`032
X10$:    MOVL    (R0),R0                ;Get the next process in the q
X    CMPL    R0,#SCH$GQ_Colpgwq        ;End of queue?
X    BEQL    Npfw                ;Yes: look at page fault waits
X    INCL    R2                ;No: count this process
X    BRB    10$                ;and try the next one
X`032
X;+ ---
X; Count processes in page fault wait
X;- ---
XNpfw:
X    MOVAQ    @#SCH$GQ_PfwQ,R0        ;Get the page fault wait q
X`032
X10$:    MOVL    (R0),R0                ;Get the next process in the q
X    CMPL    R0,#SCH$GQ_Pfwq            ;End of queue?
X    BEQL    Nfpw                ;Yes: look at free page waits
X    INCL    R2                ;No: count this process
X    BRB    10$                ;and try the next one
X`032
X;+ ---
X; Count processes in free page wait
X;- ---
XNfpw:
X    MOVAQ    @#SCH$GQ_FpgwQ,R0        ;Get the free page wait q
X`032
X10$:    MOVL    (R0),R0                ;Get the next process in the q
X    CMPL    R0,#SCH$GQ_Fpgwq        ;End of queue?
X    BEQL    Count_Done            ;Yes: all done
X    INCL    R2                ;No: count this process
X    BRB    10$                ;and try the next one
X`032
XCount_Done:
XIF    NDF,VMS_V5
X    ENBINT
XIFF
X    UNLOCK    SCHED
XENDC
XIF    NDF,VMS_V5
X;
X;   Adjust for the NULL job, which might be missing if the mask
X;   exclused the priority 0 queue.
X;
X    BBS    #31,PRIORITY_MASK,10$
X    DECL    R2                ; SUBTRACT THE NULL JOB
X10$:
X;
X;   Adjust for the CURrent job if the priority is high enough.
X;
X    BBS    @#SCH$GB_PRI,PRIORITY_MASK,20$
X    INCL    R2                ; ADD THE CURRENT JOB
X20$:
XENDC
XIF    NDF,VMS_V5
X    MOVL    G`094SCH$GB_PRI,R3
XIFF
X;
X;   Count done, now scan through each CPU. Store the LOWEST priority
X;   found and the number of executing CPUs.
X;
X    CLRL    R3                ; Lowest priority
X    CLRL    R4                ; Number of CPUs active
X    CLRL    R1                ; Current CPU index
X11$:    SUBL3    R1,#32,R0            ;Calculate #bits left (32-R1)
X    FFS    R1,R0,@#SMP$GL_ACTIVE_CPUS,R1    ;Look for an active CPU
X    BEQL    35$
+-+-+-+-+-+-+-+-  END  OF PART 8 +-+-+-+-+-+-+-+-

