.title PFRAG .ident 'X01-000' ;++ ; ; Facility: PFRAG - Page file fragmentation analyzer ; ; Abstract: ; This is the main routine for the PFRAG utility. This file ; also contains subroutine GETPAGNAM, which returns file names ; of page files. ; ; Author: ; Lee K. Gleason 1-FEB-1987 ; Control-G Consultants ; 2416 Branard #D ; Houston TX 77098 ; Phone 713/528-1859 ; ;-- .SBTTL PFRAG ;++ ; Functional Description: ; ; This module calls other modules to gather fragmentation ; information, then formats it attractively and displays it. ;-- .library "sys$library:lib.mlb" $pfldef ;page file control block definitions $fcbdef ;file control block definitions $wcbdef ;window control block offsets $ucbdef ;unit control block offsets $ddbdef ;driver data block offsets $fibdef ;define fib block offsets $lnmdef ;logical name translation definitions numholes = 16 ;number of holes to report on .psect frapur pic,quad,usr,con,rel,gbl,shr,noexe,rd,nowrt,novec faoctr: .ascid - ~File !AS!/Size: !10 Total Free: !10~- ~ Allocation Size: !4 Holes: !10!/~- ~ Sixteen Largest Holes!/~- ~-------- -------- -------- -------- ~- ~-------- -------- -------- --------!/~- ~!8UL !8UL !8UL !8UL !8UL !8UL !8UL !8UL!/~- ~!8UL !8UL !8UL !8UL !8UL !8UL !8UL !8UL!/~ logtab: .ascid /LNM$FILE_DEV/ ;logical name table roolog: .ascid /SYS$SYSROOT/ ;we'll need the translation... ;...of this in getpagnam ; Item list for $TRNLNM roolst: .word 128 ;return buffer length .word lnm$_string ;return logical name translation item code .address root+8 ;address of buffer for return string .address root ;where the returned length goes .long 0 ;end of the item list .psect fradat pic,quad,usr,con,rel,gbl,noshr,noexe,rd,wrt,novec root: .long 128 ;descriptor and buffer for logical name... .address .+4 ;...translation .blkb 128 .psect fracod pic,quad,usr,con,rel,gbl,shr,exe,rd,nowrt,novec .entry pfrag,^m<> $trnlnm_s attr = #lnm$m_case_blind,- ;ignore case tabnam = logtab,- ;use this table lognam = roolog,- ;use this name itmlst = roolst ;use this item list $cmexec_s routin = dopfrag ;do work in EXEC mode $exit_s r0 ;going to leave this brokedown palace... ; stack offsets to variables pagdesc = -8-512 ;string for page/swap filenames outdesc = pagdesc-8-512 ;string for the output line retarr = outdesc- ;place to store top numhole hole sizes holes = retarr-4 ;total number of holes asiz = holes-4 ;allocation size totfree = asiz-4 ;total free pages totsiz = totfree-4 ;total pages in file pagadr = totsiz-4 ;address of pagdesc goes here for FAO to use .entry dopfrag,^m subl #2048,sp ;get some room for space movc5 #0,#0,#0,#2048,-2048(fp) ;clear space just allocated movl mmg$gl_pagswpvc,r7 ;address of table of vectors clrl r8 ;clear high (and low) word of r8 addw3 sgn$gw_pagfilct,sgn$gw_swpfilct,r8 ;get total # of files next: movl (r7)+,r9 ;move an address to r9 cmpl r9,#mmg$gl_nullpfl ;is it in use? bneq 1$ ;yes, go go analyze it brw 2$ ;if not, long branch 1$: movl #512,pagdesc(fp) ;len moval pagdesc+8(fp),pagdesc+4(fp) ;and address moval pagdesc(fp),pagadr(fp) ;copy of addr for FAO to use pushal pagdesc(fp) ;place for GETPAGNAM to store name pushl r9 ;address of current PFL calls #2,getpagnam ;get its name blbs r0,10$ ;if ok, proceed brw end ;if not, you've bought it, mate 10$: movc5 #0,#0,#0,#numholes*4,retarr(fp) ;zero array of holes pushal retarr(fp) ;push addr of hole array pushal #numholes ;push # of longwords in hole array pushal totfree(fp) ;longword for total free pushal holes(fp) ;longword for number of holes pushl (r9) ;address of start of bitmap pushal 20(r9) ;address of length of bitmap calls #6,count ;count em up movl #512,outdesc(fp) ;put length in descriptor moval outdesc+8(fp),outdesc+4(fp) ;put address in descriptor movzbl pfl$b_allocsiz(r9),asiz(fp) ;get allocation size mull3 #8,pfl$l_bitmapsiz(r9),totsiz(fp) ;get bitmap (in bytes) $faol_s ctrstr = faoctr,- ;format the results attractively outbuf = outdesc(fp),- outlen = outdesc(fp),- prmlst = pagadr(fp) ;items are on the stack blbc r0,end ;how'd it go, mate? pushal outdesc(fp) ;push addr of output string calls #1,g^lib$put_output ;and write it 2$: decl r8 ;this one's done bleq end ;any left? brw next ;and when you get to the end,... ;...you want to start all over again end: ret ;++ ; Routine GETPAGNAM returns the name of the page/swap file ; specified by the address of the PFL block. If the file ; was opened by the XQP, its name is retrieved by a call to ; GETFILNAM, which uses XQP QIOs. If the file was opened at ; system startup, by the non-XQP routines (FIL$etc), then its ; name cannot be retrieved by QIOs, and must be inferred from ; its location in the page file indices. ; ; 4(AP) address of the PFL block ; 8(AP) address of a descriptor for a string that ; contains the name of the device the file is on, and ; will have the resultant file name appended to it ;-- .psect frapur pic,quad,usr,con,rel,gbl,shr,noexe,rd,nowrt,novec faonam: .ascid /!AD!ZW/ ;fao format string for dev+unit perpag: .ascid /SYSEXE]PAGEFILE.SYS/ ;page file name fragment perswp: .ascid /SYSEXE]SWAPFILE.SYS/ ;swap file name fragment ; stack offset to a work string tmpstr = -128 .psect fracod pic,quad,usr,con,rel,gbl,shr,exe,rd,nowrt,novec .entry getpagnam,^m subl #128,sp ;room for space... movl 4(ap),r6 ;addr of the PFL block to r6 movl pfl$l_window(r6),r7 ;addr of the WCB to r7 movl wcb$l_orgucb(r7),r10 ;addr of the UCB to r10 movl ucb$l_ddb(r10),r11 ;get DDB addr from UCB movl ddb$l_sb(r11),r0 ;get address of system block from ddb movzbl sb$t_nodename(r0),r1 ;get scs nodename this device movl r1,tmpstr(fp) ;length of string moval tmpstr+8(fp),tmpstr+4(fp) ;addr of string movc3 r1,sb$t_nodename+1(r0),tmpstr+8(fp) ;copy string body cmpl r3,tmpstr+4(fp) ;anything happen here? beql 11$ ;nope, so get on with it... movb #^A/$/,(r3)+ ;append a $ sign incl tmpstr(fp) ;and count it 11$: movzbl ddb$t_name(r11),r0 ;get count of device type name addl r0,tmpstr(fp) ;add length to tmpstr movc3 r0,ddb$t_name+1(r11),(r3) ;move body of string $fao_s ctrstr = faonam,- ;format device name... outbuf = @8(ap),- ;...for call to getpagnam outlen = @8(ap),- p1 = tmpstr(fp),- ;len of dev+control... p2 = tmpstr+4(fp),- ;..and addr p3 = ucb$w_unit(r10) ;unit number. movl wcb$l_fcb(r7),r9 ;put fcb addr in r9 beql notxqp ;if not opend by xqp, go fake it pushal @8(ap) ;output string... pushal fcb$w_fid(r9) ;addr of fid calls #2,getfilnam ;get the filename ret ;got whole filename, so get back, JoJo notxqp: movq @8(ap),r2 ;output string desc to r2/r3 movl r3,r7 ;save starting addr, to calc len movc3 root,root+8,(r3) ;translated logical name decl r3 ;backup over ] movzwl mmg$gw_minpfidx,r0 ;get lowest possible page file index # cmpl r6,@mmg$gl_pagswpvc[r0] ;is current file a page file? bneq swp ;if not, treat it like a swap file movc3 perpag,perpag+8,(r3) ;append fixed page file name brb gotfil ;then go on swp: movc3 perswp,perswp+8,(r3) ;append fixed swap file name gotfil: subl3 r7,r3,@8(ap) ;calculate final length movl #1,r0 ;let's call it a success ret ;and get back to work .end pfrag