From:	MERC::"uunet!WKUVX1.BITNET!MacroMan" 22-JUL-1992 10:10:29.74
To:	MACRO32@WKUVX1.BITNET
CC:	
Subj:	RE: VMS Memory Management/PGFLQUOTA question

> What I would like to do is reserve a large (VERY large) segment of virtual
> address space for my exclusive use in an image.  We're talking a quarter of a
> gigabyte or so here.
>
> If possible, I would like to simply reserve this address range without
 actually
> creating pages in it, since then I won't need to have a humongous page file
> quota.  I will have to jack VIRTUALPAGECNT way up since my page tables will
> have to be large enough so that I can create pages within the range as I wish,
> but I can live with that.

[Rest of question deleted]

I don't really understand the rationale behind the details of the question.
Why is it desired to greate a quarter-Gbyte address space that is reserved
against use by system routines, but not associated with backing store? The
only thing I can think of is come sort of very sparsely populated matrix,
but there are better ways to code these as linked lists...

What I think might be wanted, and which is generally useful, is the way
to associate your own private quarter-gigabyte file with a quarter-gigabyte
VM address space, so as not to clobber the system page file. This can be
done using SYS$CRMPSC. Attached to this message is a code fragment to do
this (hacked out of a big program, so pardon loose ends which will be my
fault. The coding looks great, I can't take credit for that though!)

Suggestion for DEC: It would be very nice indeed if a user could attach a
private pagefile to a process from DCL, which would then be used instead
of (or rather, in preference to) the system pagefile, until the process
is deleted. Would it be very hard to do? Certainly, it's a real hassle
when you buy binary code that needs lots of VM and know that if three or
so users happen to run it simultaneously, your pagefile will be full...
Allocating two or three disk drives per cluster node for paging isn't
really an answer.

        Yours,

                Nigel Arnot

                NRA%ipg.ph.kcl.ac.uk@nsfnet-relay.ac.uk   (internet)
                NRA%uk.ac.kcl.ph.ipg@ukacrl.bitnet        (bitnet)

----------------------------------------------------------------------------

        options /extend_source

        program bp

        integer*4       sys$crmpsc
        integer*4       sys$deltva
        integer*4       sys$dassgn
        integer*4       lib$get_lun

C_______Address ranges and misc. flags for $CRMPSC
        character*80    pagefilename
        integer*4       inadr(2), retadr(2)
        logical*4       secflags
        integer*2       chan
        integer*2       rmsjunk
        common /rmschannel/ chan, rmsjunk
        integer*4       pagecnt
        integer*4       vblock
        integer*4       secprot
        integer*4       pfcsize

C_______User file open definitions and declarations
        integer*4       pfunit                  ! FORTRAN I/O unit for pagefile
        integer*4       ufo_open, ufo_create
        external        ufo_open, ufo_create

        integer         imgbytes, imgpages
        integer         PAGESIZE
        parameter       (PAGESIZE = 512)

C_______Get image geometry and calculate storage requirements.
        imcols = intin('Image x-size', imcols, 1, MAXIMSIZE)
        imrows = intin('Image y-size', imcols, 1, MAXIMSIZE)
        imgbytes = imcols*imrows*sizeof(pixel)
        imgpages = (imgbytes+PAGESIZE-1) / PAGESIZE

C_______Get name of pagefile to use for mapped section
        if (cli$present('PAGEFILE') .eq. %loc(CLI$_PRESENT)) then
           call cli$get_value('PAGEFILE',pagefilename)
        else
           pagefilename = 'BP_PAGEFILE'
        endif

C_______Now try to expand the virtual memory region (using the specified
*       pagefile in place of the system one) to accomodate the data arrays.
        istat = lib$get_lun(pfunit)
        if (istat .ne. SS$_NORMAL) call lib$signal(%val(istat))
        open (unit=pfunit, file=pagefilename, status='OLD', useropen=ufo_open)

C_______The available section flags are as follow:
*       SEC$M_GBL        - Global instead of private section
*       SEC$M_CRF        - Copy on reference
*       SEC$M_DZRO       - Demand-zero
*       SEC$M_EXPREG     - Expand region
*       SEC$M_WRT        - Read/write instead of read-only section
*       SEC$M_PERM       - Pages are permanent
*       SEC$M_PFNMAP     - Page-frame instead of disk-file section
*       SEC$M_SYSGBL     - System global instead of group global section
*       SEC$M_PAGFIL     - Global page file instead of disk-file section
*       SEC$M_EXECUTE    - Map pages only if caller has execute access
*       SEC$M_NO_OVERMAP - Overmap existing address space
        secflags = (SEC$M_EXPREG .or. SEC$M_WRT .or. SEC$M_DZRO)
        pagecnt = imgpages*4
        vblock = 0
        pfcsize = 4
        secprot = 0
        istat = sys$crmpsc(inadr,retadr,        ! Section address ranges
        1               %val(PSL$C_USER),       ! Access mode
        2               %val(secflags),         ! Flags
        3               %val(0),                ! Global section name
        4               %val(0),                ! Version number of section
        5               %val(0),                ! Relative page n0. in GBLSEC
        6               %val(chan),             ! RMS channel for file
        7               %val(pagecnt),          ! Number of pages in section
        8               %val(vblock),           ! Starting virtual block in file
        9               %val(secprot),          ! Protection mask for section
        1               %val(pfcsize))          ! Page fault cluster size
        if (istat .ne. SS$_NORMAL) call lib$signal(%val(istat))

C       ...etc. RETADR now contais the address range of the pages mapped onto
C       the file.

        end

C==================================================
        integer*4 function ufo_open(fab, rab, lun)
C==================================================
c_______Use RMS directly to open channel, using User File Open option
        implicit none
        include '($fabdef)/nolist'
        include '($rabdef)/nolist'
        record /fabdef/ fab
        record /rabdef/ rab
        integer*4       lun

        integer*4       channel
        common /rmschannel/ channel

        integer*4       istat
        integer*4       sys$open

        fab.fab$l_fop = fab.fab$l_fop .or. FAB$M_UFO
        istat = sys$open(fab)
        channel = fab.fab$l_stv
        ufo_open = istat
        end

