At VMS Version 5 the Executive has been reorganised in a major way (see previous articles in Global Pages & Pageswapper). This article discusses the various system data areas: their locations and contents. Data is user-mode-readable unless marked "(E-R)", in which case an Executive mode routine is needed to read it ($CMEXEC or a user-written system service). A small amount of this information is guesswork/deduction as my VMS V5.0 microfiche hasn't arrived yet. 1) System vector data cells. These are in the main system vector, mapped by SYS$SYSTEM:SYS.MAP (symbols in SYS$SYSTEM:SYS.STB). Not all of the cells are described here. EXE$AR_EWDATA EXE$AR_SYSTEM_PRIMITIVES_DATA SCS$GL_MSCP EXE$GL_RPB These cells contain addresses of separate data areas (described further on). EXE$GL_ABSTIM EXE$GL_ABSTIM_TICS EXE$GQ_SYSTIME ABSTIM is the system uptime in seconds, ABSTIM_TICS the uptime in centisecs. SYSTIME is the system time (in 100 nanosecond units), as read by SYS$GETTIM or the READ_SYSTIME macro. (See the "Device Support Manual".) PMS$GL_IOPFMPDB PMS$GL_IOPFMSEQ IOPFMSEQ is a count of all $QIO operations started. Its real purpose is as a sequence number for the I/O performance monitoring subsystem, controlled by IOPFMPDB. Briefly, this is the undocumented system for logging all or selected I/O operations and which is used by SPM or can be used by third-party software. SCH$GL_PCBVEC -- address of array of PCB addresses (E-R) SCH$GL_MAXPIX -- highest process index PMS$GL_PROCCNTMAX -- highest (peak) number of processes (NULL & SWAPPER omitted) SCH$GW_PROCCNT -- current number of processes (NULL & SWAPPER omitted) SWP$GW_BALCNT -- current number of balance set slots in use (NULL & SWAPPER omitted) PFN$AL_COUNT SCH$GL_FREECNT SCH$GL_MFYCNT COUNT is an array of sizes of the three page cache lists: free, modified & bad. FREECNT is COUNT+0 and MFYCOUNT is COUNT+4. There is no symbol for the count of bad pages, COUNT+8. PFN$GL_PHYPGCNT This is the total size of dynamic memory in pages. This is the difference between the total size of memory and the number of pages reserved to VMS (as shown by "$ SHOW MEMORY"). PMS$GL_FAULTS -- total number of page faults PMS$GL_PREADS -- pages read from disk due to page faults PMS$GL_PREADIO -- hard page faults (number of page read I/Os) PMS$GL_PWRITES -- pages written PMS$GL_PWRITIO -- number of page write I/Os PMS$GL_DZROFLTS -- demand-zero page faults PMS$GL_GVALID -- global-valid page faults PMS$GL_DPTSCN Dead page table scans. This is a little-known area of VMS that can be an performance problem. A dead page table is one which does not refer to any valid pages (it may refer to transition pages such as ones on the modified list). A dead page table scan occurs during processing of a page fault on finding that too high a proportion of the working set is locked. If a dead page table references a page on the modified list, the entire modified page list is flushed to disk (SCH$GL_MFYLIM & SCH$GL_MFYLOLIM are temporarily set to zero). Thus working sets that have insufficient unlocked (aka fluid or dynamic) pages can lead to excessive writing of the modified page list. PMS$AL_TRANSFLT Array of page faults of pages in transition, indexed by page state. The $PFNDEF macro in SYS$LIBRARY:LIB defines the possible page states: PFN$C_FREPAGLST 0 -- free page list PFN$C_MFYPAGLST 1 -- modified page list PFN$C_RELPEND 3 -- release pending (as page ref. count = 0) PFN$C_WRTINPROG 5 -- write-in-progress by modified-page writer PFN$C_RDINPROG 6 -- read-in-progress PMS$GL_DIRIO -- number of direct I/Os completed PMS$GL_BUFIO -- number of buffered I/Os completed PMS$GL_SPLIT -- number of split transfers due to disk fragmentation (multiple transfers required to satisfy a single request) PMS$GL_LOGNAM -- number of logical name translations PMS$GL_MBREADS -- number of mailbox reads PMS$GL_MBWRITES -- number of mailbox writes PMS$GL_ARRLOCPK -- DECnet arriving local packet count PMS$GL_DEPLOCPK -- DECnet departing local packet count PMS$GL_ARRTRAPK -- DECnet arriving transit packet count PMS$GL_TRCNGLOS -- DECnet transit congestion loss count PMS$GL_RCVBUFFL -- DECnet receive buffer failure count PMS$GL_ENQNEW_LOC PMS$GL_ENQNEW_IN PMS$GL_ENQNEW_OUT Count of $ENQs for new locks (not conversions) ENQNEW_LOC = $ENQs originating and satisfied on the local system ENQNEW_IN = $ENQs originating on another node & satisfied locally ENQNEW_OUT = $ENQs originating locally and satisfied on another node PMS$GL_ENQCVT_LOC PMS$GL_ENQCVT_IN PMS$GL_ENQCVT_OUT -- count of $ENQs for lock conversions PMS$GL_DEQ_LOC PMS$GL_DEQ_IN PMS$GL_DEQ_OUT -- count of $DEQs PMS$GL_ENQWAIT -- count of $ENQs which had to wait PMS$GL_ENQNOTQD -- count of $ENQs which did not wait (LCK$M_NOQUEUE flag) PMS$GL_BLK_LOC PMS$GL_BLK_IN PMS$GL_BLK_OUT -- count of blocking ASTs PMS$GL_DIR_IN -- count of requests for locks mastered on the local node PMS$GL_DIR_OUT -- count of requests for locks mastered other nodes PMS$GL_DLCKMSGS_IN PMS$GL_DLCKMSGS_OUT -- counts of messages for deadlock detection PMS$GL_DLCKSRCH -- count of deadlock searches PMS$GL_DLCKFND -- count of deadlocks found SCH$GB_SIP The bit SCH$V_MPW is set when the modified page writer is writing pages SWP$GL_ISWPPAGES -- count of inswapped pages SWP$GL_ISWPCNT -- count of process inswaps SWP$GL_OSWPCNT -- count of process outswaps SWP$GL_HISWPCNT -- count of process header inswaps SWP$GL_HOSWPCNT -- count of process header outswaps SYS$GW_IJOBCNT -- current number of interactive jobs EXE$GL_MCHKERRS -- count of machine checks EXE$GL_MEMERRS -- count of memory errors EXE$GL_SITESPEC -- a cell reserved for use by customers SMP$GL_FLAGS -- SMP flags, e.g. SMP$V_ENABLED, SMP$V_UNMOD_DRIVER SMP$GL_ACTIVE_CPUS -- bit-mask of active CPUs SMP$GL_CPU_DATA -- array of addresses of per-CPU data, indexed by CPU number (0-31). $CPUDEF maps each CPU's database. (See the "Device Support Manual".) PMS$GL_NPAGDYNEXPS -- nonpaged-pool expansion successes PMS$GL_NPAGDYNEXPF -- nonpaged-pool expansion failures PMS$GL_NPAGDYNREQ -- nonpaged-pool allocation requests PMS$GL_NPAGDYNF -- nonpaged-pool allocation failures PMS$GL_NPAGDYNFPAGES -- nonpaged-pool allocation failures' requested pages PMS$GL_PAGDYNREQ -- paged-pool allocation requests PMS$GL_PAGDYNF -- paged-pool allocation failures PMS$GL_PAGDYNFPAGES -- paged-pool allocation failures' requested pages PMS$GL_XRPFAIL The three longwords starting at XRPFAIL are counts of SRP, IRP & LRP allocation failures. SYS$AR_JOBCTLMB The address of the Job Controller's mailbox UCB (E-R). UCB$W_DEVSTS (= DVI$_DEVSTS) bit UCB$V_TT_NOLOGINS controls whether logins are enabled. If this is set, the terminal driver does not notify the Job Controller to start a login when unsolicited data is detected on an unallocated terminal (with appropriate characteristics). CLU$GL_NISCS_GROUP -- NI cluster group number The following potentially-interesting cells are unused - they are listed here for completeness and to save you wasting time investigating them! PMS$GL_CHMK, PMS$GL_CHME, SYS$GW_NJOBCNT, SYS$GW_BJOBCNT, PMS$GW_BATCH PMS$GW_INTJOBS, PMS$GL_LDPCTX, PMS$GL_SWITCH TTY$GL_JOBCTLMB -- this used to be equivalent to what is now called SYS$AR_JOBCTLMB and was used by TTDRIVER to find the Job Controller mailbox. (A site could diddle this to intercept logins and start something other than LOGINOUT.) This group of cells is for detailed terminal driver statistics which have to be enabled by an assembly-time constant when VMS is compiled: PMS$GL_TREADS, PMS$GL_TWRITES, PMS$GL_READCNT, PMS$GL_WRTCNT, PMS$GL_PASSALL, PMS$GL_RWP, PMS$GL_LRGRWP, PMS$GL_RWPSUM, PMS$GL_NOSTDTRM, PMS$GL_RWPNOSTD These are the pre-SMP CPU mode times: PMS$GL_KERNEL, PMS$GL_EXEC, PMS$GL_SUPER, PMS$GL_USER, PMS$GL_INTER, PMS$GL_COMPAT PMS$GB_PROMPT Any terminal with the undocumented DEVDEPEND bit TT$V_SCRIPT set had this character prefixed to every prompt string. By default it was NUL (0). This feature seemed to be for the situation where terminal sessions were being recorded in some way (via special software, SET HOST/LOG, etc.). All the sessions from a given system had this identifying character at the start of all prompts. [Note: independantly of this, DCL prompts have a leading NUL which is replaced by "_" when DCL prompts for continuation lines.] 2) EXE$AR_EWDATA area. (E-R) The macro $EWDATADEF in SYS$LIBRARY:LIB.MLB and .REQ maps this area. EW_PMS$AL_COUNT array of size EW_PMS$S_COUNT (40) - numbers of operations EW_PMS$AL_MCNT array of size EW_PMS$S_MCNT (40) - numbers of modifiers EW_PMS$AL_READ array of size EW_PMS$S_READ (40) - numbers of disk reads EW_PMS$AL_WRITE array of size EW_PMS$S_WRITE (40) - number of disk writes EW_PMS$AL_CACHE array of size EW_PMS$S_CACHE (40) - number of cache hits EW_PMS$AL_CPU array of size EW_PMS$S_CPU (40) - accumulated cpu times EW_PMS$AL_PFA array of size EW_PMS$S_PFA (40) - accumulated page faults Each array of longwords is indexed by I/O function: index function ---------------------- 0 io$_access 1 io$_create 2 io$_deaccess 3 io$_delete 4 io$_modify 5 io$_acpcontrol (other functions are not counted) EW_PMS$GL_TURN - number of window turns EW_PMS$GL_DIRHIT - count of directory Least-Recently-Used cache hits EW_PMS$GL_DIRMISS - count of directory LRU cache misses EW_PMS$GL_QUOHIT - count of quota cache hits EW_PMS$GL_QUOMISS - count of quota cache misses EW_PMS$GL_FIDHIT - count of file ID cache hits EW_PMS$GL_FIDMISS - count of file ID cache misses EW_PMS$GL_EXTHIT - count of extent cache hits EW_PMS$GL_EXTMISS - count of extent cache misses EW_PMS$GL_FILHDR_HIT - count of file header cache hits EW_PMS$GL_FILHDR_MISS - count of file header cache misses EW_PMS$GL_DIRDATA_HIT - count of directory data block hits EW_PMS$GL_DIRDATA_MISS - count of directory data block misses EW_PMS$GL_STORAGMAP_HIT - count of storage bit map cache hits EW_PMS$GL_STORAGMAP_MISS - count of storage bit map cache misses EW_PMS$GL_OPEN - number of currently open files EW_PMS$GL_OPENS - total count of opens EW_PMS$GL_ERASEIO - total count of erase QIOs issued EW_PMS$GL_VOLLCK - count of XQP volume synch locks EW_PMS$GL_VOLWAIT - number of times XQP had to wait for a volume synch lock EW_PMS$GL_SYNCHLCK - count of XQP directory and file synch locks EW_PMS$GL_SYNCHWAIT - number of times XQP had to wait for a directory or file synch lock EW_PMS$GL_ACCLCK - count of XQP access locks EW_PMS$GL_XQPCACHEWAIT - number of times XQP had to wait for free space in a cache EW$R_RMSEWDATA subarea of size EW_RMS$S_RMSEWDATA (2) EW_RMS$GW_GBLBUFQUO - current global buffer quota remaining 3) EXE$AR_SYSTEM_PRIMITIVES_DATA. (E-R) The macro $$SYSTEM_PRIM_DATADEF in SYS$LIBRARY:LIB.MLB and .REQ maps this area. IOC_GL_SRPMIN - minimum number of free SRPs IOC_GL_SRPCNT - current number of SRPs (free + in use) IOC_GL_IRPMIN - minimum number of free IRPs IOC_GL_IRPCNT - current number of IRPs (free + in use) IOC_GL_LRPMIN - minimum number of free LRPs IOC_GL_LRPCNT - current number of LRPs (free + in use) 4) SCS$GL_MSCP area. (E-R) MSCP server data area. This includes more statistics than MONITOR MSCP displays. The macro $DSRVDEF in SYS$LIBRARY:LIB.MLB and .REQ maps this area. DSRV$W_BUFWAIT - I/Os that had to wait DSRV$L_SPLITXFER - fragmented I/O count DSRV$L_MEMW_TOT - number of I/Os that had to wait for system memory DSRV$W_MEMW_MAX - most concurrent requests waiting for memory DSRV$L_OPCOUNT - total operations count DSRV$L_READ_CNT - number of read operations DSRV$L_WRITE_CNT - number of write operations (There are many other counters - one per MSCP internal opcode.) DSRV$L_BLKCOUNT A longword array of size DSRV$S_BLKCOUNT (516) - counts of transfer sizes. The index seems to be derived by converting the transfer size (in blocks) to F-floating format and extracting 7 bits of the exponent: cvtlf blocks,r0 extzv #7,#7,r0,r0 movl dsrv$l_blkcount(rn)[r0],r0 5) EXE$GL_RPB restart parameter block. The macro $RPBDEF in SYS$LIBRARY:LIB maps this area. RPB$L_BOOTR5 Register R5 at boot time - VMS boot flags. The RPB$V_xxx symbols define the various flags. RPB$L_MEMDSC Array of size RPB$S_MEMDSC of quadword memory descriptors, one descriptor for each controller. Within each descriptor the field RPB$V_PAGCNT (of size RPB$S_PAGCNT) is the number of pages of memory on each controller. Example Macro code fragment to find the total available memory: movl g^exe$gl_rpb,r5 ; get address of area moval rpb$l_memdsc(r5),r5 ; first memory descriptor addl3 #rpb$s_memdsc,r5,r4 ; end of last memory descriptor clrl r3 ; initialise running count 10$: extzv #rpb$v_pagcnt,#rpb$s_pagcnt,(r5),r0 ; size addl2 r0,r3 ; add to running count addl2 #8,r5 ; move on to next memory descriptor cmpl r5,r4 ; finished? blssu 10$