Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Programming Concepts Manual


Previous Contents Index

23.4.2 Default Zone

The run-time library provides a default zone that is used if you do not specify a zone-id argument when you call LIB$GET_VM or LIB$FREE_VM. The default zone provides compatibility with earlier versions of LIB$GET_VM and LIB$FREE_VM, which did not support multiple zones.

Programs that do not place heavy demands on heap storage can simply use the default zone for all heap storage allocation. They do not need to call LIB$CREATE_VM_ZONE and LIB$DELETE_VM_ZONE, and they can omit the zone-id argument when calling LIB$GET_VM and LIB$FREE_VM. The zone-id for the default zone has the value 0.

The default zone has the values shown in Table 23-3.

Table 23-3 Attribute Values for the Default Zone
Attribute Value
Algorithm First Fit
Area extension size 128 pages
Block size 8 bytes
Alignment Quadword boundary
Boundary tags No boundary tags
Page limit No limit
Fill on allocate No fill on allocate
Fill on free No fill on free

23.4.3 Zone Identification

A zone is a logically independent memory pool or subheap. You can create zones by calling LIB$CREATE_VM_ZONE or LIB$CREATE_USER_VM_ZONE. These routines return as an output argument a unique 32-bit zone identifier (zone-id) that is used in subsequent routine calls where a zone identification is needed.

You can specify the zone-id argument as an optional argument when you call LIB$GET_VM to allocate a block of memory. If you do specify zone-id when you allocate memory, you must specify the same zone-id value when you call LIB$FREE_VM to free the memory. LIB$FREE_VM returns an error status if you do not provide the correct value for zone-id.

Modular routines that allocate and free heap storage must use zone identifications in a consistent fashion. You can use one of several approaches in designing a set of modular routines to ensure consistency in using zone identifications:

The zone identifier for the default zone has the value 0 (see Section 23.4.2 for more information on the default zone). You can allocate and free blocks of memory in the default zone by specifying a zone-id value of 0 or by omitting the zone-id argument when you call LIB$GET_VM and LIB$FREE_VM. You cannot use LIB$DELETE_VM_ZONE or LIB$RESET_VM_ZONE on the default zone; these routines return an error status if the value for zone-id is 0.

23.4.4 Creating a Zone

The LIB$CREATE_VM_ZONE routine creates a new zone and sets zone attributes according to arguments that you supply. LIB$CREATE_VM_ZONE returns a zone-id value for the new zone that you use in subsequent calls to LIB$GET_VM, LIB$FREE_VM, and LIB$DELETE_VM_ZONE.

23.4.5 Deleting a Zone

The LIB$DELETE_VM_ZONE routine deletes a zone and returns all pages owned by the zone to the processwide page pool managed by LIB$GET_VM_PAGE. Your program must not perform any more operations on the zone after you call LIB$DELETE_VM_ZONE.

It takes less execution time to free memory in a single operation by calling LIB$DELETE_VM_ZONE than to account individually for and free every block of memory that was allocated by calling LIB$GET_VM. Of course, you must be sure that your program is no longer using the zone or any of the memory in the zone before you call LIB$DELETE_VM_ZONE.

If you have specified deallocation filling, LIB$DELETE_VM_ZONE fills all of the allocated blocks that are freed.

23.4.6 Resetting a Zone

The LIB$RESET_VM_ZONE routine frees all the blocks of memory that were previously allocated from the zone. The memory becomes available to satisfy further allocation requests for the zone; the memory is not returned to the processwide page pool managed by LIB$GET_VM_PAGE. Your program can continue to use the zone after you call LIB$RESET_VM_ZONE.

It takes less execution time to free memory in a single operation by calling LIB$RESET_VM_ZONE than to account individually for and free every block of memory that was allocated by calling LIB$GET_VM. Of course, you must be sure that your program is no longer using any of the memory in the zone before you call LIB$RESET_VM_ZONE.

If you have specified deallocation filling, LIB$RESET_VM_ZONE fills all of the allocated blocks that are freed.

Because LIB$RESET_VM_ZONE does not return any pages to the processwide page pool, you should reset a zone only if you expect to reallocate almost all of the memory that is currently owned by the zone. If the next cycle of reallocation may use much less memory, it is better to delete the zone (with LIB$DELETE_VM_ZONE) and create it again (with LIB$CREATE_VM_ZONE).

23.5 Allocating and Freeing Blocks

The run-time library heap management routines LIB$GET_VM and LIB$FREE_VM provide the mechanism for allocating and freeing blocks of memory.

The LIB$GET_VM and LIB$FREE_VM routines are fully reentrant, so they can be called by code running at AST level or in an Ada multitasking environment. Several threads of execution can be allocating or freeing memory simultaneously in the same zone or in different zones.

All memory allocated by LIB$GET_VM has user-mode read/write access, even if the call to LIB$GET_VM is made from a more privileged access mode.

The rules for using LIB$GET_VM and LIB$FREE_VM are as follows:

23.6 Allocation Algorithms

The run-time library heap management routines provide four algorithms, listed in Table 23-4, that are used to allocate and free memory and that are used to manage blocks of free memory.

Table 23-4 Allocation Algorithms
Code Symbol Description
1 LIB$K_VM_FIRST_FIT First Fit
2 LIB$K_VM_QUICK_FIT Quick Fit (maintains lookaside list)
3 LIB$K_VM_FREQ_SIZES Frequent Sizes (maintains lookaside list)
4 LIB$K_VM_FIXED Fixed Size Blocks

The Quick Fit and Frequent Sizes algorithms use lookaside lists to speed allocation and freeing for certain request sizes. A lookaside list is the software analog of a hardware cache. It takes less time to allocate or free a block that is on a lookaside list.

For each of the algorithms, LIB$GET_VM performs one or more of the following operations:

For each of the algorithms, LIB$FREE_VM performs one or more of the following operations:

23.6.1 First Fit Algorithm

The First Fit algorithm (LIB$K_VM_FIRST_FIT) maintains a linked list of free blocks. If the zone does not have boundary tags, the free list is kept sorted in order of increasing memory address. An allocation request is satisfied by the first block on the free list that is large enough; if the first free block is larger than the request size, it is split and the fragment is kept on the free list. When a block is freed, it is inserted in the free list at the appropriate point; adjacent free blocks are merged to form larger free blocks.

23.6.2 Quick Fit Algorithm

The Quick Fit algorithm (LIB$K_VM_QUICK_FIT) maintains a set of lookaside lists indexed by request size for request sizes in a specified range. For request sizes that are not in the specified range, a First Fit list of free blocks is maintained. An allocation request is satisfied by removing a block from the appropriate lookaside list; if the lookaside list is empty, a First Fit allocation is done. When a block is freed, it is placed on a lookaside list or the First Fit list according to its size.

Free blocks that are placed on a lookaside list are neither merged with adjacent free blocks nor split to satisfy a request for a smaller block.

23.6.3 Frequent Sizes Algorithm

The Frequent Sizes algorithm (LIB$K_VM_FREQ_SIZES) is similar to the Quick Fit algorithm in that it maintains a set of lookaside lists for some block sizes. You specify the number of lookaside lists when you create the zone; the sizes associated with those lists are determined by the actual sizes of blocks that are freed. An allocation request is satisfied by searching the lookaside lists for a matching size; if no match is found, a First Fit allocation is done. When a block is freed, the block is placed on a lookaside list with a matching size, on an empty lookaside list, or on the First Fit list if no lookaside list is available. As with the Quick Fit algorithm, free blocks on lookaside lists are not merged or split.

23.6.4 Fixed Size Algorithm

The Fixed Size algorithm (LIB$K_VM_FIXED) maintains a single queue of free blocks. There is no First Fit free list, and splitting or merging of blocks does not occur.

23.7 User-Defined Zones

When you create a zone by calling LIB$CREATE_VM_ZONE, you must select an allocation algorithm from the fixed set provided by the run-time library. You can tailor the characteristics of the zone by specifying various zone attributes. User-defined zones provide additional flexibility and control by letting you supply routines for the allocation and deallocation algorithms.

You create a user-defined zone by calling LIB$CREATE_USER_VM_ZONE. Instead of supplying values for a fixed set of zone attributes, you provide routines that perform the following operations for the zone:

Each time that one of the run-time library heap management routines (LIB$GET_VM, LIB$FREE_VM, LIB$RESET_VM_ZONE, LIB$DELETE_VM_ZONE) is called to perform an operation on a user-defined zone, the corresponding routine that you specified is called to perform the actual operation. You need not make any changes in the calling program to use user-defined zones; their use is transparent.

You do not need to provide routines for all four of the preceding operations if you know that your program will not perform certain operations. If you omit some of the operations and your program attempts to use them, an error status is returned.

Applications of user-defined zones include the following:

Example 23-1 Monitoring Heap Operations with a User-Defined Zone

C+ 
C This is the main program that creates a zone and exercises it. 
C 
C Note that the main program simply calls LIB$GET_VM and LIB$FREE_VM. 
C It contains no special coding for user-defined zones. 
C- 
 
        PROGRAM MAIN 
        IMPLICIT INTEGER(A-Z) 
 
        CALL MAKE_ZONE(ZONE) 
 
        CALL LIB$GET_VM(10, I1, ZONE) 
        CALL LIB$GET_VM(20, I2, ZONE) 
        CALL LIB$FREE_VM(10, I1, ZONE) 
        CALL LIB$RESET_VM_ZONE(ZONE) 
        CALL LIB$DELETE_VM_ZONE(ZONE) 
        END 
 
C+ 
C This is the subroutine that creates a user-defined zone for monitoring. 
C Each GET, FREE, or RESET prints a line of output on the terminal. 
C Errors are signaled. 
C- 
 
        SUBROUTINE MAKE_ZONE(ZONE) 
        IMPLICIT INTEGER (A-Z) 
        EXTERNAL GET_RTN, FREE_RTN, RESET_RTN, LIB$DELETE_VM_ZONE 
 
C+ 
C Create the primary zone.  The primary zone supports 
C the actual allocation and freeing of memory. 
C- 
 
        STATUS = LIB$CREATE_VM_ZONE(REAL_ZONE) 
        IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) 
 
C+ 
C Create a user-defined zone that monitors operations on REAL_ZONE. 
C- 
 
        STATUS = LIB$CREATE_USER_VM_ZONE(USER_ZONE, REAL_ZONE, 
        1       GET_RTN, 
        1       FREE_RTN, 
        1       RESET_RTN, 
        1       LIB$DELETE_VM_ZONE) 
        IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) 
 
C+ 
C Return the zone-id of the user-defined zone to the caller to use. 
C- 
 
        ZONE = USER_ZONE 
        END 
 
C+ 
C GET routine for user-defined zone. 
C- 
 
        FUNCTION GET_RTN(SIZE, ADDR, ZONE) 
        IMPLICIT INTEGER(A-Z) 
 
        STATUS = LIB$GET_VM(SIZE, ADDR, ZONE) 
 
        IF (.NOT. STATUS) THEN 
                CALL LIB$SIGNAL(%VAL(STATUS)) 
        ELSE 
                TYPE 10, SIZE, ADDR 
10              FORMAT(' Allocated ',I4,' bytes at ',Z8) 
        ENDIF 
        GET_RTN = STATUS 
        END 
 
C+ 
C FREE routine for user-defined zone. 
C- 
 
        FUNCTION FREE_RTN(SIZE, ADDR, ZONE) 
        IMPLICIT INTEGER(A-Z) 
 
        STATUS = LIB$FREE_VM(SIZE, ADDR, ZONE) 
 
        IF (.NOT. STATUS) THEN 
                CALL LIB$SIGNAL(%VAL(STATUS)) 
        ELSE 
                TYPE 20, SIZE, ADDR 
20              FORMAT(' Freed ',I4,' bytes at ',Z8) 
        ENDIF 
        FREE_RTN = STATUS 
        END 
 
C+ 
C RESET routine for user-defined zone. 
C- 
 
        FUNCTION RESET_RTN(ZONE) 
        IMPLICIT INTEGER(A-Z) 
 
        STATUS = LIB$RESET_VM_ZONE(ZONE) 
        IF (.NOT. STATUS) THEN 
                CALL LIB$SIGNAL(%VAL(STATUS)) 
        ELSE 
                TYPE 30, ZONE 
30              FORMAT(' Reset zone at ', Z8) 
        ENDIF 
 
        RESET_RTN = STATUS 
        END 

23.8 Debugging Programs That Use Virtual Memory Zones

This section discusses some methods and aids for debugging programs that use virtual memory zones. Note that this information is implementation dependent and may change at any time.

The following list offers some suggestions for discovering and tracking problems with memory zone usage:


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
5841PRO_062.HTML