Document revision date: 30 March 2001

## OpenVMS Programming Concepts Manual

Previous | Contents | Index

1. The processes ORION and CYGNUS are in the same group. Each process first associates with a common event flag cluster named FLAG_CLUSTER to use common event flags to synchronize its use of the section.
2. The process ORION creates the global section named GLOBAL_SECTION, specifying section flags that indicate that it is a global section (SEC$M_GBL) and has read/write access. Input and output address arrays, the page count parameter, and the channel number arguments are not shown; procedures for specifying them are the same, as shown in this example.
3. The process CYGNUS associates with the common event flag cluster and waits for the flag defined as FLGSET; ORION sets this flag when it has finished creating the section. To map the section, CYGNUS specifies the input and output address arrays, the flag indicating that it is a global section, and the global section name. The number of pages mapped is the same as that specified by the creator of the section.

#### 12.4.7.13 Reading and Writing Data Sections

Read/write sections provide a way for a process or cooperating processes to share data files in virtual memory.

The sharing of global sections may involve application-dependent synchronization techniques. For example, one process can create and map to a global section in read/write fashion; other processes can map to it in read-only fashion and interpret data written by the first process. Alternatively, two or more processes can write to the section concurrently. (In this case, the application must provide the necessary synchronization and protection.)

After data in a process private section is modified, the process can release (or unmap) the section. The modified pages are then written back into the disk file defined as a section.

After data in a global section is modified, the process or processes can release (or unmap) the section. The modified pages are still maintained in memory until the section is deleted. The data is then written back into the disk file defined as a section. Applications relying on modified data to be in the file at a specific point in time must use the SYS$UPDSEC(W) system service to force the write action. See Section 12.4.7.15.

When the section is deleted, the revision number of the file is incremented, and the version number of the file remains unchanged. A full directory listing indicates the revision number of the file and the date and time that the file was last updated.

#### 12.4.7.14 Releasing and Deleting Sections

A process unmaps a section by deleting the virtual addresses in its own virtual address space to which it has mapped the section. If a return address range was specified to receive the virtual addresses of the mapped pages, this address range can be used as input to the Delete Virtual Address Space (SYS$DELTVA) system service, as follows:

    $DELTVA_S INADR=RETRANGE

When a process unmaps a private section, the section is deleted; that is, all control information maintained by the system is deleted. A temporary global section is deleted when all processes that have mapped to it have unmapped it. Permanent global sections are not deleted until they are specifically marked for deletion with the Delete Global Section (SYS$DGBLSC) system service; they are then deleted when no more processes are mapped.

Note that deleting the pages occupied by a section does not delete the section file, but rather cancels the process's association with the file. Moreover, when a process deletes pages mapped to a process private read/write section, all modified pages are written back into the section file. For global sections, the system's modified page writer starts writing back modified pages when the section is deleted and all mapping processes have deleted their associated virtual address space. Applications relying on modified data to be in the file at a specific point in time must use the SYS$UPDSEC(W) system service to force the write action. See Section 12.4.7.15.

After a process private section is deleted, the channel assigned to it can be deassigned. The process that created the section can deassign the channel with the Deassign I/O Channel (SYS$DASSGN) system service, as follows:

    $DASSGN_S CHAN=GBLFAB+FAB$L_STV

For global sections, the channel is only used to identify the file to the system. The system then assigns a different channel to use for future paging I/O to the file. The used assigned channel can be deleted immediately after the global section is created.

#### 12.4.7.15 Writing Back Sections

Because read/write sections are not normally updated on disk until either the physical pages they occupy are paged out, or until the section is deleted, a process should ensure that all modified pages are successfully written back into the section file at regular intervals.

The Update Section File on Disk (SYS$UPDSEC) system service writes the modified pages in a section into the disk file. The SYS$UPDSEC system service is described in the OpenVMS System Services Reference Manual.

#### 12.4.7.16 Memory-Resident Global Sections

Memory-resident global sections allow a database server to keep larger amounts of currently used data cached in physical memory. The database server then accesses the data directly from physical memory without performing I/O read operations from the database files on disk. With faster access to the data in physical memory, runtime performance increases dramatically.

Memory-resident global sections are non-file-backed global sections. Pages within a memory-resident global section are not backed by the pagefile or by any other file on disk. Thus, no pagefile quota is charged to any process or to the system. When a process maps to a memory-resident global section and references the pages, working set list entries are not created for the pages. No working set quota is charged to the process.

For further information about memory-resident global sections, see Chapter 16.

#### 12.4.7.17 Image Sections

Global sections can contain shareable code. The operating system uses global sections to implement shareable code, as follows:

1. The object module containing code to be shared is linked to produce a shareable image. The shareable image is not, in itself, executable. It contains a series of sections, called image sections.
2. You link private object modules with the shareable image to produce an executable image. No code or data from the shareable image is put into the executable image.
3. The system manager uses the INSTALL command to create a permanent global section from the shareable image file, making the image sections available for sharing.
4. When you run the executable image, the operating system automatically maps the global sections created by the INSTALL command into the virtual address space of your process.

For details on how to create and identify shareable images and how to link them with private object modules, see the OpenVMS Linker Utility Manual. For information about how to install shareable images and make them available for sharing as global sections, see the OpenVMS System Manager's Manual.

#### 12.4.7.18 Page Frame Sections

A page frame section is one or more contiguous pages of physical memory or I/O space that have been mapped as a section. One use of page frame sections is to map to an I/O page, thus allowing a process to read device registers.

A page frame section differs from a disk file section in that it is not associated with a particular disk file and is not paged. However, it is similar to a disk file section in most other respects: you create, map, and define the extent and characteristics of a page frame section in essentially the same manner as you do for a disk file section.

To create a page frame section, you must specify page frame number (PFN) mapping by setting the SEC$M_PFNMAP flag bit in the flags argument to the Create and Map Section (SYS$CRMPSC) system service. The vbn argument is now used to specify that the first page frame is to be mapped instead of the first virtual block. You must have the user privilege PFNMAP to either create or delete a page frame section but not to map to an existing one.

Because a page frame section is not associated with a disk file, you do not use the chan, and pfc arguments to the SYS$CRMPSC service to create or map this type of section. For the same reason, the SEC$M_CRF (copy-on-reference) and SEC$M_DZRO (demand-zero) bit settings in the flags argument do not apply. Pages in page frame sections are not written back to any disk file (including the paging file). The pagcnt and relpag arguments are in units of CPU-specific pages for page frame sections.

Caution You must use caution when working with page frame sections. If you permit write access to the section, each process that writes to it does so at its own risk. Serious errors can occur if a process writes incorrect data or writes to the wrong page, especially if the page is also mapped by the system or by another process. Thus, any user who has the PFNMAP privilege can damage or violate the security of a system.

#### 12.4.7.19 Partial Sections (Alpha Only)

On Alpha systems, a partial section is one where not all of the defined section, whether private or global, is entirely backed up by disk blocks. In other words, a partial section is where a disk file does not map completely onto an Alpha system page.

For example, suppose a file for which you wish to create a section consists of 17 virtual blocks on disk. To map this section, you would need two whole Alpha 8 KB pages, the smallest size Alpha page available. The first Alpha page would map the first 16 blocks of the section, and the second Alpha page would map the 17th block of the section. (A block on disk is 512 bytes, same as on OpenVMS VAX.) This results in 15/16ths of the second Alpha page not being backed up by the section file. This is called a partial section because the second Alpha page of the section is only partially backed up.

When the partial page is faulted in, a disk read is issued for only as many blocks as actually back up that page, which in this case is 1. When that page is written back, only the one block is actually written.

If the upper portion of the second Alpha page is used, it is done so at some risk, because only the first block of that page is saved on a write-back operation. This upper portion of the second Alpha page is not really useful space to the programmer, because it is discarded during page faulting.

### 12.4.8 Example of Using Memory Management System Services (Alpha Only)

In the following example, two programs are communicating through a global section. The first program creates and maps a global section (by using SYS$CRMPSC) and then writes a device name to the section. This program also defines the device terminal and process names and sets the event flags that synchronize the processes.

The second program maps the section (by using SYS$MGBLSC) and then reads the device name and the process that allocated the device and any terminal allocated to that process. This program also writes the process named to the terminal global section where the process name can be read by the first program.

The common event cluster is used to synchronize access to the global section. The first program sets REQ_FLAG to indicate that the device name is in the section. The second program sets INFO_FLAG to indicate that the process and terminal names are available.

Data in a section must be page aligned. The following is the option file used at link time that causes the data in the common area named DATA to be page aligned: PSECT_ATTR = DATA, PAGE

For high-level language usage, use the solitary attribute of the linker. See the OpenVMS Linker Utility Manual for an explanation of how to use the solitary attribute. The address range requested for a section must end on a page boundary, so SYS$GETSYI is used to obtain the system page size.

Before executing the first program, you need to write a user-open routine that sets the user-open bit (FAB$V_UFO) of the FAB options longword (FAB$L_FOP). Because the Fortran OPEN statement specifies that the file is new, you should use $CREATE to open it rather than $OPEN. No $CONNECT should be issued. The user-open routine reads the channel number that the file is opened on from the status longword (FAB$L_STV) and returns that channel number to the main program by using a common block (CHANNEL in this example).

    !This is the program that creates the global section.

    ! Define global section flags
    INCLUDE '($SECDEF)'
    ! Mask for section flags
    INTEGER SEC_MASK

    ! Logical unit number for section file
    INTEGER INFO_LUN
    ! Channel number for section file
    ! (returned from useropen routine)
    INTEGER SEC_CHAN
    COMMON /CHANNEL/ SEC_CHAN
    ! Length for the section file
    INTEGER SEC_LEN
    ! Data for the section file
    CHARACTER*12 DEVICE,
    2            PROCESS
    CHARACTER*6 TERMINAL
    COMMON /DATA/ DEVICE,
    2             PROCESS,
    2             TERMINAL
    ! Location of data
    INTEGER PASS_ADDR (2),
    2       RET_ADDR (2)

    ! Two common event flags
    INTEGER REQUEST_FLAG,
    2       INFO_FLAG
    DATA REQUEST_FLAG /70/
    DATA INFO_FLAG /71/

    ! Data for SYS$GETSYI
    INTEGER   PAGE_SIZE
    INTEGER*2 BUFF_LEN, ITEM_CODE
    INTEGER   BUFF_ADDR, LENGTH, TERMINATOR
    EXTERNAL  SYI$_PAGE_SIZE
    COMMON /GETSYI_ITEMLST/ BUFF_LEN,
    2                       ITEM_CODE,
    2                       BUFF_ADDR,
    2                       LENGTH,
    2                       TERMINATOR

    ! User-open routines
    INTEGER UFO_CREATE
    EXTERNAL UFO_CREATE
    .
    .
    .
    ! Open the section file
    STATUS = LIB$GET_LUN (INFO_LUN)
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
    SEC_MASK = SEC$M_WRT .OR. SEC$M_DZRO .OR. SEC$M_GBL
    ! (Last element - first element + size of last element + 511)/512
    SEC_LEN = ( (%LOC(TERMINAL) - %LOC(DEVICE) + 6 + 511)/512 )
    OPEN (UNIT=INFO_LUN,
    2     FILE='INFO.TMP',
    2     STATUS='NEW',
    2     INITIALSIZE = SEC_LEN,
    2     USEROPEN = UFO_CREATE)
    ! Free logical unit number and map section
    CLOSE (INFO_LUN)

    ! Get the system page size
    BUFF_LEN = 4
    ITEM_CODE = %LOC(SYI$_PAGE_SIZE)
    BUFF_ADDR = %LOC(PAGE_SIZE)
    LENGTH = 0
    TERMINATOR = 0

    STATUS = SYS$GETSYI(,,,BUFF_LEN,,,)

    ! Get location of data
    PASS_ADDR (1) = %LOC (DEVICE)
    PASS_ADDR (2) = PASS_ADDR(1) + PAGE_SIZE - 1

    STATUS = SYS$CRMPSC (PASS_ADDR,   ! Address of section
    2                    RET_ADDR,    ! Addresses mapped
    2                    ,
    2                    %VAL(SEC_MASK), ! Section mask
    2                    'GLOBAL_SEC',   ! Section name
    2                    ,,
    2                    %VAL(SEC_CHAN), ! I/O channel
    2                    ,,,)
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))

    ! Create the subprocess
    STATUS = SYS$CREPRC (,
    2                    'GETDEVINF',  ! Image
    2                    ,,,,,
    2                    'GET_DEVICE', ! Process name
    2                    %VAL(4),,,)   ! Priority
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))

    ! Write data to section
    DEVICE = '$DISK1'

    ! Get common event flag cluster and set flag
    STATUS = SYS$ASCEFC (%VAL(REQUEST_FLAG),
    2                    'CLUSTER',,)
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
    STATUS = SYS$SETEF (%VAL(REQUEST_FLAG))
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))

    ! When GETDEVINF has the information, INFO_FLAG is set
    STATUS = SYS$WAITFR (%VAL(INFO_FLAG))
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
    .
    .
    .

    ! This is the program that maps to the global section
    ! created by the previous program.

    ! Define section flags
    INCLUDE '($SECDEF)'
    ! Mask for section flags
    INTEGER SEC_MASK
    ! Data for the section file
    CHARACTER*12 DEVICE,
    2            PROCESS
    CHARACTER*6  TERMINAL
    COMMON /DATA/ DEVICE,
    2             PROCESS,
    2             TERMINAL

    ! Location of data
    INTEGER PASS_ADDR (2),
    2       RET_ADDR (2)

    ! Two common event flags
    INTEGER REQUEST_FLAG,
    2       INFO_FLAG
    DATA REQUEST_FLAG /70/
    DATA INFO_FLAG /71/

    ! Data for SYS$GETSYI
    INTEGER   PAGE_SIZE
    INTEGER*2 BUFF_LEN, ITEM_CODE
    INTEGER   BUFF_ADDR, LENGTH, TERMINATOR
    EXTERNAL  SYI$_PAGE_SIZE
    COMMON /GETSYI_ITEMLST/ BUFF_LEN,
    2                       ITEM_CODE,
    2                       BUFF_ADDR,
    2                       LENGTH,
    2                       TERMINATOR
    .
    .
    .
    ! Get the system page size
    BUFF_LEN = 4
    ITEM_CODE = %LOC(SYI$_PAGE_SIZE)
    BUFF_ADDR = %LOC(PAGE_SIZE)
    LENGTH = 0
    TERMINATOR = 0

    STATUS = SYS$GETSYI(,,,BUFF_LEN,,,)

    ! Get common event flag cluster and wait
    ! for GBL1.FOR to set REQUEST_FLAG
    STATUS = SYS$ASCEFC (%VAL(REQUEST_FLAG),
    2                    'CLUSTER',,)
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
    STATUS = SYS$WAITFR (%VAL(REQUEST_FLAG))
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))

    ! Get location of data
    PASS_ADDR (1) = %LOC (DEVICE)
    PASS_ADDR (2) = PASS_ADDR(1) + PAGE_SIZE - 1

    ! Set write flag
    SEC_MASK = SEC$M_WRT

    ! Map the section
    STATUS = SYS$MGBLSC (PASS_ADDR, ! Address of section
    2                    RET_ADDR,  ! Address mapped
    2                    ,
    2                    %VAL(SEC_MASK), ! Section mask
    2                    'GLOBAL_SEC',,) ! Section name
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))

    ! Call GETDVI to get the process ID of the
    ! process that allocated the device, then
    ! call GETJPI to get the process name and terminal
    ! name associated with that process ID.
    ! Set PROCESS equal to the process name and
    ! set TERMINAL equal to the terminal name.
    .
    .
    .
    ! After information is in GLOBAL_SEC
    STATUS = SYS$SETEF (%VAL(INFO_FLAG))
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))

    END

## Chapter 13
Memory Management Services and Routines on OpenVMS VAX

This chapter describes the use of system services and run-time routines that VAX systems use to manage memory. It contains the following sections:

Section 13.1 describes the page size on VAX systems.

Section 13.2 describes the layout of virtual address space.

Section 13.3 describes extended addressing enhancements on selected VAX systems.

Section 13.4 describes the three levels of memory allocation routines.

Section 13.5 discusses how to use system services to add virtual address space, adjust working sets, control process swapping, and create and manage sections.

## 13.1 Virtual Page Size

To facilitate memory protection and mapping, the virtual addresss space on VAX systems is subdivided into segments of 512-byte sizes called pages. (On Alpha systems, memory page sizes are much larger and vary from system to system. See Chapter 12 for information about Alpha page sizes.) Versions of system services and run-time library routines that accept page-count values as arguments interpret these arguments in 512-byte quantities. Services and routines automatically round the specified addresses to page boundaries.

## 13.2 Virtual Address Space

The initial size of a process's virtual address space depends on the size of the image being executed. The virtual address space of an executing program consists of the following three regions:

- Process program region (P0)
  The process program region is also referred to as P0 space. P0 space contains the instructions and data for the current image.
  Your program can dynamically allocate storage in the process program region by calling run-time library (RTL) dynamic memory allocation routines or system services.
- Process control region (P1)
  The process control region is also referred to as P1 space. P1 space contains system control information and the user-mode process stack. The user mode stack expands as necessary toward the lower-addressed end of P1 space.

- Common system region (S0)
  The common system region is also referred to as S0 space. S0 space contains the operating system. Your program cannot allocate or free memory within the common system region from the user access mode.
  This common system region (S0) of system virtual address space can have appended to it additional virtual address space, known as a reserved region, or S1 space, that creates a single region of system space. As a result, the system virtual address space increases from 1 GB to 2 GB.

A summary of these regions appears in Figure 13-1.

Figure 13-1 Virtual Address Overview on VAX Systems

The memory management routines map and control the relationship between physical memory and the virtual address space of a process. These activities are, for the most part, transparent to you and your programs. In some cases, however, you can make a program more efficient by explicitly controlling its virtual memory usage.

The maximum size to which a process can increase its address space is controlled by the system parameter VIRTUALPAGECNT.

Using memory management system services, a process can add a specified number of pages to the end of either the program region or the control region. Adding pages to the program region provides the process with additional space for image execution, for example, for the dynamic creation of tables or data areas. Adding pages to the control region increases the size of the user stack. As new pages are referenced, the stack is automatically expanded, as shown in Figure 13-2. (By using the STACK= option in a linker options file, you can also expand the user stack when you link the image.)

Figure 13-2 illustrates the layout of a process's virtual memory. The initial size of a process's virtual address space depends on the size of the image being executed.

Figure 13-2 Layout of VAX Process Virtual Address Space

## 13.3 Extended Addressing Enhancements on Selected VAX Systems

Selected VAX systems have extended addressing (XA) as part of the memory management subsystem. Extended addressing enhancement is supported on the VAX 6000 Model 600, VAX 7000 Model 600, and VAX 10000 Model 600 systems. Extended addressing contains the following two major enhancements that affect system images, system integrated products (SIPs), privileged layered products (LPs), and device drivers:

- Extended physical addressing (XPA)
- Extended virtual addressing (XVA)

Extended physical addressing increases the size of a physical address from 30 bits to 32 bits. This increases the capacity for physical memory from 512 MB to 3.5 GB as shown in Figure 13-3. The 512 MB is still reserved for I/O and adapter space.

Figure 13-3 Physical Address Space for VAX Systems with XPA

Extended virtual addressing (XVA) increases the size of the virtual page number field in the format of a system space address from 21 bits to 22 bits. The region of system virtual address space, known as the reserved region or S1 space, is appended to the existing region of system virtual address space known as S0 space, thereby creating a single region of system space. As a result, the system virtual address space increases from 1 GB to 2 GB as shown in Figure 13-4.

Figure 13-4 Virtual Address Space for VAX Systems with XVA

Previous | Next | Contents | Index

| privacy and legal statement |
5841PRO_041.HTML