.title LCKACT ;; ;; List all the active lock trees on this node ;; ;; We define "active" lock trees as ones where the "Old activity" field ;; in the root RSB (which contains the average lock count per 8-second ;; interval) is non-zero. ; K.Parris 11/98 ;; Author: Keith Parris parris@encompasserve.org or keithparris@yahoo.com ;; http://www.geocities.com/keithparris/ or http://encompasserve.org/~parris/ ; ; Comment out the following line to compile for 7.1-2 and previous versions ; Uncomment the following line to compile for 7.2 and following versions ;;;V72_OR_LATER = 1 ; KP May 2000 .library 'sys$library:lib.mlb' .library 'sys$library:starlet.mlb' $rsbdef ;Includ Resource Block definitions $syidef ;Include definitions used for $GETSYI ;; ;; Status-check macro ;; .MACRO CHECK_STATUS, LOC=R0, ?NO_ERROR1$ BLBS LOC, NO_ERROR1$ ;Branch if no error .IF DIFFERENT LOC, R0 MOVZWL LOC, R0 ;Move error into R0 .ENDC $EXIT_S R0 ;Exit with error NO_ERROR1$: ;Return to program flow .ENDM CHECK_STATUS ;------------------------------------------------------------------------------ .PSECT RO_DATA QUAD,RD,noWRT,noEXE ;; ;; Read-only data area ;; ; ; Item List for the $GETSYI call. ; .ALIGN LONG SYI_ITMLST: .WORD 4 ;buffer length (1 longword) .WORD SYI$_NODE_CSID ;Return CSID of node .ADDRESS NODE_CSID ;buffer address .LONG 0 ;returned length address [null, ; ;since it will always be 4...] .LONG 0 ;end of item list. ; Output format strings FAOCTL1: ;CSID of this node .ASCID /CSID: !8XL/ FAOCTL2: ;OACT CSID ResLen ResNam .ASCID /!5ZW !8XL !2ZB !8XL!8XL!8XL!8XL!8XL!8XL!8XL!8XL/ DONEMSG: ;Completion confirmation .ASCID /Done./ ;------------------------------------------------------------------------------ .PSECT RW_DATA QUAD,RD,WRT,noEXE ;; ;; Read-write data area ;; .ALIGN QUAD IOSB: .BLKL 2 ;IOSB for $GETSYI ; ; Buffer referenced in the $GETSYI item list ; .ALIGN LONG NODE_CSID: .BLKL ;CSID of the node we're running on ; Data items about each active root resource .ALIGN LONG OACT: .BLKL ; "Old activity" field -- average req's per 8 seconds .ALIGN LONG CSID: .BLKL ; Master node CSID .ALIGN LONG RSNLEN: .BLKL ; Resource name length in bytes .ALIGN LONG RESNAM: .BLKB 32 ; Resource name itself ; ; Stuff for $FAO call. ; MAXFAO = 132 ;Maximum $FAO buffer length .ALIGN QUAD FAODESC: ;$FAO descriptor FAOLEN: .BLKL ;$FAO output buffer length .ADDRESS FAOBUF ;address of buffer FAOBUF: .BLKB MAXFAO ;132-character buffer ;------------------------------------------------------------------------------ .PSECT CODE QUAD,RD,noWRT,EXE ;; ;; Begin code ;; ;;;;=========================================================================== ;;;; ;;;; Main program ;;;; ;;;;=========================================================================== .ENTRY START,^M<> ; Lock manager data structures were moved into S2 space for V7.2. This means ; several field widths had to be changed for 64-bit addressing. ; ; Check to ensure the version of code we're running matches the running system, ; and exit with an error if not: ; %SYSTEM-F-SYSVERDIF, system version mismatch; please relink ; They need to actually edit this (for the V72_OR_LATER symbol), recompile, and ; relink, but hopefully the error message will be enough of a clue to get the ; job done. ; ; Check for a matching version of lock manager code .IIF NDF,SS$_SYSVERDIF, $SSDEF .IIF NDF,SYS$K_BASE_IMAGE, $SYSVERSIONDEF MOVAL G^SYS$VERSION_BEGIN,R0 MOVZBL #SYS$K_CLUSTERS_LOCKMGR,R1 .IF NDF V72_OR_LATER lckmgr_version = ^x00010080 ;V7.1-2 .IFF ;NDF V72_OR_LATER lckmgr_version = ^x00010100 ;V7.2 .ENDC ;NDF V72_OR_LATER CMPL #lckmgr_version,4(R0)[R1] BEQL 1$ MOVL #SS$_SYSVERDIF,R0 ; Must recompile/relink $EXIT_S R0 1$: ; ; Find out the CSID of the node we're running on ; $GETSYIW_S - ITMLST=SYI_ITMLST,- ;item list IOSB=IOSB ;IOSB CHECK_STATUS ;Check status in R0 CHECK_STATUS IOSB ;Check status in IOSB ; Output this node's CSID in hexadecimal MOVZBL #MAXFAO,FAOLEN $FAO_S - CTRSTR=FAOCTL1,- OUTLEN=FAOLEN,- OUTBUF=FAODESC,- P1=NODE_CSID CHECK_STATUS ;Check status in R0 ; Output the message to SYS$OUTPUT PUSHAL FAODESC CALLS #1, G^LIB$PUT_OUTPUT ;Output the message CHECK_STATUS ;Check status in R0 ; Because the RSBs are protected from user-mode access (and are readable only ; from Kernel mode), gather data from Root RSB chain while in Kernel mode .IF NDF V72_OR_LATER ;V7.1-2 $CMEXEC_S ROUTIN=WORK ; Call serious-work routine in Exec mode .IFF ;NDF V72_OR_LATER ;V7.2 $CMKRNL_S ROUTIN=WORK ; Call serious-work routine in Kernel mode .ENDC ;NDF V72_OR_LATER ; Indicate that we've successfully completed (and the process hasn't been ; blown away by an ACCVIO in Kernel mode) by putting out a 'Done' message PUSHAL DONEMSG CALLS #1, G^LIB$PUT_OUTPUT ;Output the message ;; CHECK_STATUS ;Check status in R0 $EXIT_S R0 ; RET ; So Alpha macro compiler knows this routine has ended ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; .ENTRY WORK,^M ; Look through the chain of root RSBs, grabbing info about each one that ; has a non-zero "old activity" accumulator. ; ; (For simplicity here, we dump them in arbitrary order and use $SORT/MERGE ; later for the work of sorting by resource name and identifying the busiest ; ones.) ; ; We can only read the data we need from Kernel mode under V7.2 and later, ; since it's no longer readable from Exec mode. (We are able to read it ; from Exec mode in 7.1-2 and earlier versions.) ; ; We don't bother to synchronize with spinlocks because we're only reading, ; and don't want to add to MP_Synch time. ; But that implies that we might end up off in the weeds sometime if the data ; structures change underneath us. While the odds of a root RSB going away ; isn't high, it is still possible, so we put in place an exception handler ; to catch an ACCVIO should this occur sometime, and prevent the system from ; crashing. This way, worst case, we may blow away our own process. ; Worst case, we'd temporarily be off in our rate calculations by not having ; data for a node in the cluster. Perhaps we can evem re-try up at the DCL ; level if this process dies (???)@@@@@@ ; ; Establish an exception handler to catch inadvertent ACCVIOs and prevent a ; system crash. It will simply return to the caller, signalling the error. .IF DF V72_OR_LATER ;V7.2 or later MOVAB G^EXE$SIGTORET,(FP) ; Establish exception handler .ENDC ;DF V72_OR_LATER .IF NDF V72_OR_LATER ;V7.1-2 or earlier MOVAL g^LCK$GL_RRSFL,R7 ; Address of Root RSB listhead MOVL R7,R8 ; Make a note of listhead address .IFF ;NDF V72_OR_LATER ;V7.2 or later MOVAQ g^LCK$GQ_RRSFL,R7 ; Address of Root RSB listhead evax_or r31,R7,R8 ; Make a note of listhead address .ENDC ;NDF V72_OR_LATER 10$: .IF NDF V72_OR_LATER ;V7.1-2 or earlier MOVL (R7),R7 ; Next RSB in Root RSB list CMPL R7,R8 ; Back to starting point? (circular queue) .branch_unlikely BEQL 20$ ; Yes --> done MOVAB <-RSB$L_RRSFL>(R7),R9 ; Address of base of RSB .IFF ;NDF V72_OR_LATER ;V7.2 or later evax_ldq R7,(R7) ; Next RSB in Root RSB list evax_cmpeq R7,R8,r24 ; Back to starting point? (circular queue) .branch_unlikely blbs r24,20$ ; Yes --> done evax_ldaq R9,<-rsb$q_rrsfl>(R7); Address of base of RSB .ENDC ;NDF V72_OR_LATER MOVZWL (R9),OACT ; Old Activity field BEQL 10$ ; No activity --> try next RSB MOVL (R9),CSID ; Master node CSID BNEQ 15$ ; Non-zero --> another node is master ; ; Zero: (that means this node) MOVL NODE_CSID,CSID ; Plug in this node's own CSID 15$: MOVZBL (R9),R10 ; Resource name length MOVL R10,RSNLEN ; Resource name length MOVC3 R10,(R9),RESNAM ; Resource name text ; Output the info about this resource MOVZBL #MAXFAO,FAOLEN $FAO_S - CTRSTR=FAOCTL2,- OUTLEN=FAOLEN,- OUTBUF=FAODESC,- P1=OACT,- P2=CSID,- P3=RSNLEN,- P4=RESNAM+28,- P5=RESNAM+24,- P6=RESNAM+20,- P7=RESNAM+16,- P8=RESNAM+12,- P9=RESNAM+8,- P10=RESNAM+4,- P11=RESNAM CHECK_STATUS ;Check status in R0 ; Output the message to SYS$OUTPUT PUSHAL FAODESC CALLS #1, G^LIB$PUT_OUTPUT ;Output the message CHECK_STATUS ;Check status in R0 BRW 10$ ; Get next entry in Root RSB list --> 20$: ; MOVZWL #SS$_NORMAL,R0 ; Return normal status RET ; Return to user mode .end start ;Possible screen layouts for a MONITOR MLOCK display: ; ; Total Remote Master Busiest and ; Master Lock Lock Lock Remote its ;Resource name Node Rate Rate Rate Node rate ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxx xxxx xxxx xxxx xxxxxx xxxx ; 2nd-busiest?x ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxx xxxx xxxx xxxx xxxxxx xxxx ; 2nd-busiest?x ; ;and display the top 7 to 10 of these in descending order by total lock rate ; ;or, for the /ALL option: ; CUR AVE MIN MAX ;Resource name Node Rate Rate Rate Rate ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Total: xxxx.xx xxxx.xx xxxx.xx xxxx.xx ; xxxxxx xxxx.xx xxxx.xx xxxx.xx xxxx.xx ; xxxxxx* xxxx.xx xxxx.xx xxxx.xx xxxx.xx ; xxxxxx xxxx.xx xxxx.xx xxxx.xx xxxx.xx ; * indicates master node ; ;Sort resources vertically by descending average total lock rate, (displaying ;the top 3-6 on a screen); and within each resource, list the total and all ;nodes with over some percentage of the total (i.e. more than their "share") of ;lock requests, based on their average rate