From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 27-SEP-1990 04:30:48.79
To:	MRGATE::"ARISIA::EVERHART"
CC:	
Subj:	Sizing memory on VMS (source code)

Received:  by crdgw1.ge.com (5.57/GE 1.73)
	 id AA04381; Thu, 27 Sep 90 04:08:43 EDT
Message-Id:  <9009270808.AA04381@crdgw1.ge.com>
Received: From SUN2.NSFNET-RELAY.AC.UK by CRVAX.SRI.COM with TCP; Thu, 27 SEP 90 00:57:04 PDT
Received: from vax.nsfnet-relay.ac.uk by sun2.nsfnet-relay.ac.uk 
          with SMTP inbound id aa00845; Thu, 27 Sep 90 7:44:10 +0000
Received: from sun.nsfnet-relay.ac.uk by vax.NSFnet-Relay.AC.UK via Janet 
          with NIFTP id aa01048; 27 Sep 90 7:51 BST
Date: Thu, 27 Sep 90 8:42 BST
From: Nick de Smith <NICK@ncdlab.ulcc.ac.uk>
To: INFO-VAX <@nsfnet-relay.ac.uk:INFO-VAX@crvax.sri.com>
Subject: Sizing memory on VMS (source code)

Hi,

Loads of requests for it, its small, so here it is...

This code, I believe, is definitive. That is to say that it implements the same
algorithms as used by SHOW MEMORY (as of VMS V5.3-1), which I presume to be
correct. Hopefully my implementation of these algorithms is correct, and so this
will kill another one of the perenial Info-VAX woolly arguments.

I might point out that the VMS SHOW MEMORY code is on a fiche number > 999,
which means that the fiche index shows it a being on page "***" (thanks guys!).
Because of this, I had to go through the index of each sheet over 1000 (the
sheet index is in the bottom right hand corner of each page), and aren't there
just a lot of interesting, unsupported, utilities there! Not exactly bedtime
reading, but a *real load* of good ideas.

SHOW_MEMORY part 1 of 1 follows at the end of this message.
The XFREEMEM.C code is largish (about 55 blocks), so I don't intend to repost
it. It is a fairly trivial exercise to extract the SIZE_MEMORY routine from the
code below, and to replace the equivalent code in XFREEMEM with it (should take
about 5 minutes).

regards,

nick	NICK@NCDLAB.ULCC.AC.UK (comments etc. are generally welcome)

$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-007  22-FEB-1990
$!   On 28-SEP-1990 08:26:48.82   By user NICK 
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$!+ THIS PACKAGE DISTRIBUTED IN 1 PART, TO KEEP EACH PART
$!  BELOW 30 BLOCKS
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. SHOW_MEMORY.C;1
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ if f$search(P1) .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped."
$ delete 'f'*
$ exit
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
X/***************************************************************************
V**********************************************
X
X Program`09: SHOW_MEMORY.EXE
X Author`09`09: Nick de Smith`09`09NICK@NCDLAB.ULCC.AC.UK
X Creation date`09: 23-Aug-90
X
X `A9 1990 Nick de Smith and Applied Telematics Group Ltd.
X This software is supplied for information only. No guarantee is supplied fo
Vr this software, and no liability
X will be accepted for any action resulting from the use of this software or
V the information contained herein.
X Under no circumstances may this software be used for commercial gain, inclu
Vding its sale, lease or loan.
X This software may be copied only with the inclusion of this copyright notic
Ve.
X The author is prepared to enter into correspondance with interested parties
V, but will not necessarily
X maintain this software. Having said all that, enjoy it!
X
X Edit`09Edit date`09By`09Why
X  02`0925-Sep-90`09NMdS`09Add in percentage rounding fiddle factor.
X  01`0923-Aug-90`09NMdS`09New
X
X Show system memory usage. Requires CMEXEC privilege.
X This code, I believe, is definitive. That is to say that it implements the
V same algorithms as used by SHOW MEMORY (as
X of VMS V5.3-1), which I presume to be correct. Hopefully my implementation
V of these algorithms is correct, and so this
X will kill another one of the perenial Info-VAX woolly arguments.
X
X Build with:`09$ CC SHOW_MEMORY
X`09`09$ LINK SHOW_MEMORY,SYS$SYSTEM:SYS.STB/SELECT
X`09`09$ RUN SHOW_MEMORY
X
X****************************************************************************
V*********************************************/
X
X#module`09SHOW_MEMORY`09"V01.02"
X
X#include`09descrip`09`09`09`09`09`09`09/* Define DSC$xxx - VAX descriptors`0
V9`09*/
X#include`09psldef`09`09`09`09`09`09`09/* Define PSL$xxx - Access mode symbol
Vs`09`09*/
X#include`09ssdef`09`09`09`09`09`09`09/* Define SS$xxxx - System status codes
V`09`09*/
X#include`09stsdef`09`09`09`09`09`09`09/* Define STS$M_xxxx - VMS status bits
V`09`09*/
X
X/* Useful macro to check returned status of a system routine */
X#define`09ss_check( command ) `7B`09`09`09\
X`09long ss_status = (command);`09`09\
X`09if ( (ss_status & STS$M_SUCCESS) == 0 ) `7B \
X`09`09return ss_status;`09`09\
X`09`7D`09`09`09`09`09\
X`7D
X
X/***************************************************************************
V**********************************************
X
X`09`09`09`09`09S H O W _ M E M O R Y
X
X Show the memory usage by this VMS system.
X All displayed percentages are with respect to the ENABLED memory, not the t
Votal on the system.
X
X****************************************************************************
V*********************************************/
X
XSHOW_MEMORY()
X`7B
X`09static $DESCRIPTOR( x_format_1, "There are !UL physical page!%S (!UL.!AD
V Mb) on this system" );
X`09static $DESCRIPTOR( x_format_10,"!_all of which is enabled" );
X`09static $DESCRIPTOR( x_format_11,"!_of which only !UL page!%S (!UL.!AD Mb)
V are enabled" );
X`09static $DESCRIPTOR( x_format_2, "Pages Inuse: !UL (!UL%)  Free: !UL (!UL%
V)  Modified: !UL (!UL%)  Bad: !UL" );
X`09static $DESCRIPTOR( x_format_3, "Of the pages in use, !UL (!UL%) are perm
Vanently allocated to VMS" );
X`09static struct dsc$descriptor_d x_output = `7B
X`09`090, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0 `7D;
X`09unsigned long l_physical_pages;`09`09`09`09`09/* Physical pages in enable
Vd for use`09`09*/
X`09unsigned long l_free_pages;`09`09`09`09`09/* Pages on free list`09`09`09`
V09*/`20
X`09unsigned long l_modified_pages;`09`09`09`09`09/* Pages on modified list`0
V9`09`09*/
X`09unsigned long l_vms_pages;`09`09`09`09`09/* Pages in use by VMS`09`09`09`
V09*/
X`09unsigned long l_bad_pages;`09`09`09`09`09/* Pages marked "bad"`09`09`09`0
V9*/
X`09unsigned long l_real_physical_pages;`09`09`09`09/* Physical pages connect
Ved to system`09`09*/
X`09unsigned long args`5B`5D = `7B 6,
X`09`09&l_physical_pages, &l_free_pages, &l_modified_pages, &l_vms_pages, &l_
Vbad_pages, &l_real_physical_pages `7D;
X`09static int SIZE_MEMORY();`09`09`09`09`09/* CMEXEC routine to get memory s
Vize.`09`09*/
X
X`09ss_check( SYS$CMEXEC( SIZE_MEMORY, args ) )`09`09`09/* Call the data coll
Vector`09`09`09*/
X
X`09ss_check( LIB$SYS_FAO(
X`09`09&x_format_1`09`09,`09`09`09`09/* Format control string`09`09`09*/
X`09`090`09`09`09,`09`09`09`09/* No resultant length`09`09`09`09*/
X`09`09&x_output`09`09,`09`09`09`09/* Output string`09`09`09`09*/
X`09`09l_real_physical_pages`09,`09`09`09`09/* Number of physical pages`09`09
V`09*/
X`09`09l_real_physical_pages >> 11,`09`09`09`09/* Number of megabytes of phys
Vical memory`09*/
X`09`092, &"00255075"`5B ((l_real_physical_pages >> 9) & 3) * 2 `5D ) ) /* Fr
Vactional part of Mb`09`09`09*/
X`09ss_check( LIB$PUT_OUTPUT( &x_output ) )
X
X`09if ( l_real_physical_pages == l_physical_pages ) `7B`09`09/* If all memor
Vy is enabled...`09`09`09*/
X`09`09ss_check( LIB$SYS_FAO(`09`09`09`09`09/* ...say all memory is enabled`0
V9`09`09*/
X`09`09`09&x_format_10`09`09,`09`09`09/* Format control string`09`09`09*/
X`09`09`090`09`09`09,`09`09`09/* No resultant length`09`09`09`09*/
X`09`09`09&x_output`09`09) )`09`09`09/* Output string`09`09`09`09*/
X`09`7D else `7B
X`09`09ss_check( LIB$SYS_FAO(`09`09`09`09`09/* Say how much memory is enabled
V`09`09*/
X`09`09`09&x_format_11`09`09,`09`09`09/* Format control string`09`09`09*/
X`09`09`090`09`09`09,`09`09`09/* No resultant length`09`09`09`09*/
X`09`09`09&x_output`09`09,`09`09`09/* Output string`09`09`09`09*/
X`09`09`09l_physical_pages`09,`09`09`09/* Number of enabled physical pages`09
V`09*/
X`09`09`09l_physical_pages >> 11`09,`09`09`09/* Enabled megabytes of physical
V memory `09*/
X`09`09`092, &"00255075"`5B ((l_physical_pages >> 9) & 3) * 2 `5D ) )`09/* Fr
Vactional part of Mb`09`09*/
X`09`7D
X`09ss_check( LIB$PUT_OUTPUT( &x_output ) )
X
X#define`09DIVISOR`09`09l_physical_pages`09`09`09`09/* percentages are WRT "p
Vhysical_pages"`09`09*/
X#define`09FIDDLE_FACTOR`09(DIVISOR / 2)`09`09`09`09`09/* Fiddle factor to ro
Vund up/down the %tages`09*/
X#define PERCENTAGE( value ) (((value) * 100 + FIDDLE_FACTOR) / DIVISOR)`09/*
V Return percentage of "value" WRT "physical_pages" */
X
X`09ss_check( LIB$SYS_FAO(
X`09`09&x_format_2`09,`09`09`09`09`09/* Format control string`09`09`09*/
X`09`090`09`09,`09`09`09`09`09/* No resultant length`09`09`09`09*/
X`09`09&x_output`09,`09`09`09`09`09/* Output string`09`09`09`09*/
X`09`09l_physical_pages - l_free_pages - l_modified_pages,`09/* Inuse page co
Vunt`09`09`09`09*/
X`09`09PERCENTAGE( l_physical_pages - l_free_pages - l_modified_pages ),
X`09`09l_free_pages`09,`09`09`09`09`09/* Free page count`09`09`09`09*/
X`09`09PERCENTAGE( l_free_pages ),
X`09`09l_modified_pages,`09`09`09`09`09/* Modified page count`09`09`09`09*/
X`09`09PERCENTAGE( l_modified_pages ),
X`09`09l_bad_pages`09) )`09`09`09`09`09/* Count of bad pages`09`09`09`09*/
X`09ss_check( LIB$PUT_OUTPUT( &x_output ) )
X
X`09ss_check( LIB$SYS_FAO(
X`09`09&x_format_3`09,`09`09`09`09`09/* Format control string`09`09`09*/
X`09`090`09`09,`09`09`09`09`09/* No resultant length`09`09`09`09*/
X`09`09&x_output`09,`09`09`09`09`09/* Output string`09`09`09`09*/
X`09`09l_vms_pages`09,`09`09`09`09`09/* Pages in use by VMS`09`09`09`09*/
X`09`09PERCENTAGE( l_vms_pages ) ) )
X`09ss_check( LIB$PUT_OUTPUT( &x_output ) )
X
X`09return SS$_NORMAL;
X`7D
X`0C
X
X/***************************************************************************
V**********************************************
X
X`09`09`09`09`09S I Z E _ M E M O R Y
X
X Calculate the amount of memory in use by this VMS system.
X
X `A9 1990 Nick de Smith and Applied Telematics Group Ltd.
X This software is supplied for information only. No guarantee is supplied fo
Vr this software, and no liability
X will be accepted for any action resulting from the use of this software or
V the information contained herein.
X Under no circumstances may this software be used for commercial gain, inclu
Vding its sale, lease or loan.
X This software may be copied only with the inclusion of this copyright notic
Ve.
X The author is prepared to enter into correspondance with interested parties
V, but will not necessarily
X maintain this software. Having said all that, enjoy it!
X
X This code, I believe, is definitive. That is to say that it implements the
V same algorithms as used by SHOW MEMORY,
X which I presume to be correct. Hopefully my implementation of these algorit
Vhms is correct, and so this will kill
X another one of the perenial Info-VAX woolly arguments 8-).
X
X This is a "stand-alone" routine that can be called from any VMS language. I
Vt must be called at EXEC mode or via a
X SYS$CMEXEC call with an argument list.
X The code in the routine is effectively a C representation of the DCL SHOW M
VEMORY command. I acknowledge the use of
X the VMS V5.3-1 fiche in determining the algorithms to use.
X No scan is done of the bad page list as we do not need to differentiate bet
Vween soft and hard memory errors - we just
X take the total bad count.
X A interesting feature of this routine is that it returns the "real_physical
V_pages" (the number of pages of memory
X physically in the machine) as well as "physical_pages" (the number of pages
V that are enabled). This latter number will
X always be less than or equal to the former. The reason for this is that the
V SYSGEN parameter PHYSICALPAGES can be used
X to artificially constrain a system to use less memory than there really is,
V in order to test systems with differing
X memory sizes without having to put in or haul out physical boards. As the r
Voutine returns both values, it is possible
X to check a) how much "real physical" memory there is actually on the system
V, and b) how much of it VMS is allowed
X to use. The DCL command SHOW MEMORY only displays the enabled memory.
X This routine must be linked with SYS$SYSTEM:SYS.STB/Selective_Search.
X
X Edit`09Edit date`09By`09`09Why
X  01`0920-Sep-90`09Nick de Smith`09First attempt - with thanks to the SHOW M
VEMORY code.
X
X****************************************************************************
V*********************************************/
X
Xglobalref unsigned long SCH$GL_FREECNT;`09`09`09`09`09/* Number of free page
Vs`09`09`09`09*/
X#define`09PFN$C_BADPAGLST`090x2`09`09`09`09`09`09/* ...Offset to count of ba
Vd pages in longwords`09*/
Xglobalref unsigned long SCH$GL_MFYCNT;`09`09`09`09`09/* Number of modified p
Vages`09`09`09*/
Xglobalref unsigned long PFN$GL_PHYPGCNT;`09`09`09`09/* Physical pages for pr
Vocess use`09`09*/
Xglobalref unsigned long MMG$GL_PHYPGCNT;`09`09`09`09/* Configured (SYSGEN) l
Vimit on pages`09`09*/
Xglobalref unsigned char *EXE$GL_RPB;`09`09`09`09`09/* => Restart Parameter B
Vlock`09`09`09*/
X
X/* From $NDTDEF`09 - Nexus Device Type codes`09*/
X#define NDT$_MPM0`090x0040`09`09`09`09`09`09/* Multiport Memory 0`09`09`09`0
V9*/
X#define NDT$_MPM3`090x0043`09`09`09`09`09`09/*     ''      ''   3`09`09`09`0
V9*/
X
X/* From $RPBDEF`09- Restart Parameter Block`09*/
X#define RPB$L_MEMDSC`090xBC`09`09`09`09`09`09/* Offset into RPB for memory d
Vescriptors`09*/
X#define RPB$C_NMEMDSC`090x8`09`09`09`09`09`09/* Max. number of memory descri
Vptor.`09`09*/
Xtypedef struct MEMDSC `7B
X`09unsigned page_count`09: 24;`09`09`09`09/* Number of pages in this descrip
Vtor`09*/
X`09unsigned tr_number`09: 8;`09`09`09`09/* Adaptor type number`09`09`09*/
X`09unsigned base_pfn`09: 32;`09`09`09`09/* Base PFN for this memory`09`09*/
X`7D MEMDSC, *MEMDSC_PTR;
X
X#define RPB$L_BOOTR5`090x30`09`09`09`09`09`09/* Offset into RPB copy of boot
V time R5`09`09*/
X#define RPB$M_MPM`090x00000800`09`09`09`09`09/* Use MultiPortMemory only`09`
V09`09*/
X#define RPB$M_USEMPM`090x00001000`09`09`09`09`09/* Use MultiPortMemory as we
Vll as local memory`09*/
X
X#define`09RPB$L_BADPGS`090x104`09`09`09`09`09`09/* Count of bad pages at boo
Vt time`09`09*/
X
Xunsigned long
XSIZE_MEMORY(
X`09unsigned long *`09al_physical_pages`09,`09`09`09/* => Returned physical p
Vage count`09`09*/
X`09unsigned long *`09al_free_pages`09`09,`09`09`09/* =>    ''    free      '
V'   ''`09`09*/
X`09unsigned long *`09al_modified_pages`09,`09`09`09/* =>    ''    modified
V  ''   ''`09`09*/
X`09unsigned long *`09al_vms_pages`09`09,`09`09`09/* Count of pages used by V
VMS`09`09`09*/
X`09unsigned long *`09al_bad_pages`09`09,`09`09`09/* Count of bad pages`09`09
V`09`09*/
X`09unsigned long *`09al_real_physical_pages`09)`09`09`09/* "real" count of p
Vhysical pages`09`09*/
X`7B
X`09int`09`09l_local_pages, l_multiport_pages;
X`09unsigned long`09l_nmemdsc = RPB$C_NMEMDSC;`09`09`09/* Maximum number of m
Vemory descriptors`09`09*/
X`09MEMDSC_PTR`09ar_memdsc = EXE$GL_RPB + RPB$L_MEMDSC;`09`09/* => first memo
Vry descriptor in RPB`09`09*/
X`09unsigned long`09l_boot_r5 = *((unsigned long *)(EXE$GL_RPB + RPB$L_BOOTR5
V)); /* Copy of system boot R5 value`09*/
X
X`09*al_free_pages`09`09= SCH$GL_FREECNT;`09`09`09/* Return number of pages o
Vn free list`09`09*/
X`09*al_modified_pages`09= SCH$GL_MFYCNT;`09`09`09/*   ''     ''   ''   ''  '
V' modified list`09*/
X
X`09l_local_pages = l_multiport_pages = 0;
X
X`09for ( ; ar_memdsc->page_count && l_nmemdsc-- ; ar_memdsc++ ) `7B`09/* Sca
Vn each memory descriptor`09`09`09*/
X
X`09`09/* If adapter is within MPM range, then its multiport memory. An assum
Vption is made here that all memory
X`09`09   with adaptor numbers in the range NDT$_MPM0 to NDT$_MPM3 is multipo
Vrt memory, and that no multiport
X`09`09   memory has an adaptor number outside of this range.`09`09`09`09`09`
V09 `09*/
X
X`09`09if ( ar_memdsc->tr_number >= NDT$_MPM0 && ar_memdsc->tr_number <= NDT$
V_MPM3 ) `7B
X`09`09`09l_multiport_pages += ar_memdsc->page_count;`09/* Its a multiport me
Vmory descriptor`09`09*/
X`09`09`7D else `7B
X`09`09`09l_local_pages += ar_memdsc->page_count;`09`09/* Its local memory on
Vly`09`09`09*/
X`09`09`7D
X`09`7D
X
X`09/* Check the boot flags (/R5:xxxxxxxx) for the memory configuration (real
Vly for 11/782s only)`09`09`09*/
X
X`09if ( l_boot_r5 & RPB$M_MPM ) `7B`09`09`09`09`09/* If this is a multiproce
Vssor configuration...`09*/
X`09`09*al_real_physical_pages = l_multiport_pages;`09`09/* ...then we are on
Vly using shared memory`09*/
X`09`7D else `7B
X`09`09*al_real_physical_pages = l_local_pages;`09`09/* The system is using t
Vhe local memory.`09*/
X`09`09if ( l_boot_r5 & RPB$M_USEMPM ) `7B`09`09`09/* If USEMPM is set, we ar
Ve using MPM as well... */
X`09`09`09*al_real_physical_pages += l_multiport_pages;`09/* ...so add in the
V multiport memory pages`09*/
X`09`09`7D
X`09`7D
X
X`09/* Check to see if the SYSGEN PHYSICALPAGES parameter has been used to li
Vmit the usable number of pages`09`09*/
X
X`09if ( *al_real_physical_pages <= MMG$GL_PHYPGCNT ) `7B`09`09/* If the phys
Vical memory count is lower...`09*/
X`09`09*al_physical_pages = *al_real_physical_pages;`09`09/* ...than the maxi
Vmum allowed by SYSGEN, use it */
X`09`7D else `7B
X`09`09*al_physical_pages = MMG$GL_PHYPGCNT;`09`09`09/* Usable pages have bee
Vn limited by SYSGEN`09*/
X`09`7D
X`09*al_vms_pages = *al_physical_pages - PFN$GL_PHYPGCNT;`09`09/* Get pages u
Vsed by VMS`09`09`09*/
X
X`09*al_bad_pages = *((unsigned long *)(EXE$GL_RPB + RPB$L_BADPGS)); /* # of
V bad pages at boot`09`09`09*/
X`09*al_bad_pages += *((unsigned long *)(&SCH$GL_FREECNT + PFN$C_BADPAGLST));
V /* # of bad pages since boot`09`09*/
X
X`09*al_vms_pages -= *al_bad_pages;`09`09`09`09`09/* Don't count bad pages to
V VMS`09`09`09*/
X
X`09return SS$_NORMAL;
X`7D
$ CALL UNPACK SHOW_MEMORY.C;1 1195669633
$ v=f$verify(v)
$ EXIT

