hp.com home products and services support and drivers solutions how to buy
cd-rom home
End of Jump to page title
HP OpenVMS systems

Jump to content

HP OpenVMS Programming Concepts Manual

HP OpenVMS Programming Concepts Manual

Previous Contents Index

In the previous example, if the structures foo and foo64 will be used interchangeably within the same source module, you can eliminate the symbol FOODEF64. The routine foo_print would then be defined as follows:

int foo_print (void * foo_ptr); 

Eliminating the FOODEF64 symbol allows 32-bit and 64-bit callers to use the same function prototype; however less strict type checking is then available during the C source compilation.

11.4.2 OpenVMS Alpha, OpenVMS VAX, and OpenVMS I64 Guidelines

The following sections provide guidelines about using arguments on OpenVMS Alpha, OpenVMS VAX, and OpenVMS I64 systems.

Only address, size, and length arguments should be passed as quadwords by value.

Arguments passed by value are restricted to longwords on VAX. To be compatible with VAX APIs, quadword arguments should be passed by reference instead of by value. However, addresses, sizes and lengths are examples of arguments which, because of the architecture, could logically be longwords on OpenVMS VAX and quadwords on OpenVMS Alpha and OpenVMS I64.

Even if the API will not be available on OpenVMS VAX, this guideline should still be followed for consistency across all APIs.

Avoid page size dependent units.

Arguments such as lengths and offsets should be represented in units that are page size independent, such as bytes.

A pagelet is an awkward unit. It was invented for compatibility with VAX and is used on OpenVMS Alpha and OpenVMS I64 within OpenVMS VAX compatible interfaces. A pagelet is equivalent in size to a VAX page and should not be considered a page size independent unit because it is often confused with a CPU-specific page on Alpha and OpenVMS I64.

Example: Length_64 argument in EXPREG_64 is passed as a quadword byte count by value.

Naturally align all data passed by reference.

The called routine should specify to the compiler that arguments are aligned, and the compiler can perform more efficient load and store sequences. If the data is not naturally aligned, users will experience performance penalties.

If the called routine can execute incorrectly because the data passed by reference is not naturally aligned, the called routine should do explicit checking and return an error if not aligned. For example, if a load/locked, store/conditional is being done internally in the routine on the data, and the data is not aligned, the load/locked, store/conditional will not work properly.

11.4.3 Promoting an API from a 32-Bit API to a 64-Bit API

For ease of use, it is best to separate promoting an API from improving the 32-bit design or adding new functionality. Calling a routine within the new 64-bit API should be an easy programming task.

64-bit routines should accept 32-bit forms of structures as well as 64-bit forms.

To make it easy to modify calls to an API, the 32-bit form of a structure should be accepted by the interface as well as the 64-bit form.

Example: If the 32-bit API passed information by descriptor, the new interface should pass the same information by descriptor.

64-bit routines should provide the same functionality as the 32-bit routines.

An application currently calling the 32-bit API should be able to completely upgrade to calling the 64-bit API without having to preserve some of the old calls to the old 32-bit API just because the new 64-bit API is not a functional superset of the old API.

Example: SYS$EXPREG_64 works for P0, P1 and P2 process space. Callers can replace all calls to SYS$EXPREG since SYS$EXPREG_64 is a functional superset of $EXPREG.

Use the suffix "_64" when appropriate.

For system services, this suffix is used for routines that accept 64-bit addresses by reference. For promoted routines, this distinguishes the 64-bit capable version from its 32-bit counterpart. For new routines, it is a visible reminder that a 64-bit wide address cell will be read/written. This is also used when a structure is passed that contains an embedded 64-bit address, if the structure is not self-identifying as a 64-bit structure. Hence, a routine name need not include "_64" simply because it receives a 64-bit descriptor. Remember that passing an arbitrary value by reference does not mean the suffix is required, passing a 64-bit address by reference does.

This practice is recommended for other routines as well.


SYS$EXPREG_64 (region_id_64, length_64, acmode, return_va_64, return_length_64)
SYS$CMKRNL_64 (routine_64, quad_arglst_64)

11.4.4 Example of a 32-Bit Routine and a 64-Bit Routine

The following example illustrates a 32-bit routine interface that has been promoted to support 64-bit addressing. It handles several of the issues addressed in the guidelines.

The C function declaration for an old system service SYS$CRETVA looks like the following:

#pragma required_pointer_size save 
#pragma required_pointer_size 32 
int sys$cretva ( 
        struct _va_range * inadr, 
        struct _va_range * retadr, 
        unsigned int       acmode); 
#pragma required_pointer_size restore 

The C function declaration for a new system service SYS$CRETVA_64 looks like the following:

#pragma required_pointer_size save 
#pragma required_pointer_size 64 
int sys$cretva_64 ( 
        struct _generic_64 * region_id_64, 
        void *               start_va_64, 
        unsigned __int64     length_64, 
        unsigned int         acmode, 
        void **              return_va_64, 
        unsigned __int64 *   return_length_64); 
#pragma required_pointer_size restore 

The new routine interface for SYS$CRETVA_64 corrects the embedded pointers within the _va_range structure, passes the 64-bit region_id_64 argument by reference and passes the 64-bit length_64 argument by value.

11.5 OpenVMS Alpha and OpenVMS I64 Tools and Utilities That Support 64-Bit Addressing

This section briefly describes the following OpenVMS Alpha and OpenVMS I64 tools that support 64-bit virtual addressing:

11.5.1 OpenVMS Debugger

On OpenVMS Alpha and OpenVMS I64 systems, the Debugger can access the extended memory made available by 64-bit addressing support. You can examine and manipulate data in the complete 64-bit address space.

You can examine a variable as a quadword by using the option Quad, which is on the Typecast menu of both the Monitor pull-down menu and the Examine dialog box.

The default type for the debugger is longword, which is appropriate for debugging 32-bit applications. You should change the default type to quadword for debugging applications that use the 64-bit address space. To do this, use the SET TYPE QUADWORD command.

Note that hexadecimal addresses are 16-digit numbers on Alpha and OpenVMS I64. For example,


The debugger supports 32-bit and 64-bit pointers.

For more information about using the OpenVMS Debugger, see the HP OpenVMS Debugger Manual.

11.5.2 OpenVMS Alpha System-Code Debugger

The OpenVMS Alpha system-code debugger accepts 64-bit addresses and uses full 64-bit addresses to retrieve information.

11.5.3 Delta/XDelta

XDELTA supports 64-bit addressing on OpenVMS Alpha and OpenVMS I64. Quadword display mode displays full quadwords of information. 64-bit address display mode accepts and displays all addresses as 64-bit quantities.

XDELTA has predefined command strings for displaying the contents of the PFN database.

For more information about Delta/XDelta, see the HP OpenVMS Delta/XDelta Debugger Manual.

11.5.4 LIB$ and CVT$ Facilities of the OpenVMS Run-Time Library

For more information about 64-bit addressing support for the LIB$ and CVT$ facilities of the OpenVMS RTL library, refer to the OpenVMS RTL Library (LIB$) Manual.

11.5.5 Watchpoint Utility

The Watchpoint utility is a debugging tool that maintains a history of modifications that are made to a particular location in shared system space by setting watchpoints on 64-bit addresses. It watches any system address, whether in S0, S1, or S2 space.

A $QIO interface to the Watchpoint utility supports 64-bit addresses. The WATCHPOINT command interpreter (WP) issues $QIO requests to the WATCHPOINT driver (WPDRIVER) from commands that follow the standard rules of DCL grammar.

Enter commands at the WATCHPOINT> prompt to set, delete, and obtain information from watchpoints. Before invoking the WATCHPOINT command interpreter (WP) or loading the WATCHPOINT driver, you must set the SYSGEN MAXBUF dynamic parameter to 64000, as follows:


Before invoking WP, you must install the WPDRIVER with SYSMAN, as follows:


You can then invoke WP with the following command:


Now you can enter commands at the WATCHPOINT> prompt to set, delete, and obtain information from watchpoints.

You can best view the WP help screens as well as the output to the Watchpoint utility using a terminal set to 132 characters, as follows:


11.5.6 SDA

SDA allows a user to specify 64-bit addresses and 64-bit values in expressions. It also displays full 64-bit values where appropriate.

The following commands have been enhanced or are new in OpenVMS Version 8.2 for I64 use.

For more information about using SDA 64-bit addressing support, see the HP OpenVMS System Analysis Tools Manual.

11.6 Language and Pointer Support for 64-Bit Addressing

Full support in HP C and the HP C Run-Time Library (RTL) for 64-bit addressing make C the preferred language for programming 64-bit applications, libraries, and system code for OpenVMS Alpha and OpenVMS I64. The 64-bit pointers can be seamlessly integrated into existing C code, and new 64-bit applications can be developed, with natural C coding styles, that take advantage of the 64-bit address space provided by OpenVMS Alpha and OpenVMS I64.

Support for all 32-bit pointer sizes (the default), all 64-bit pointer sizes, and the mixed 32-bit and 64-bit pointer size environment provide compatibility as well as flexibility for programming 64-bit OpenVMS applications in HP C.

The ANSI-compliant, #pragma approach for supporting the mixed 32-bit and 64-bit pointer environment is common to Tru64 UNIX. Features of 64-bit C support include memory allocation routine name mapping (transparent support for _malloc64 and _malloc32) and C-type checking for 32-bit versus 64-bit pointer types.

The OpenVMS Calling Standard describes the techniques used by all OpenVMS languages for invoking routines and passing data between them. The standard also defines the mechanisms that ensure consistency in error and exception handling routines.

The OpenVMS Calling Standard provides the following support for 64-bit addresses:

OpenVMS Alpha and OpenVMS I64 64-bit addressing support for mixed pointers also includes the following features:

11.7 HP C RTL Support for 64-Bit Addressing

OpenVMS Alpha and I64 64-bit virtual addressing support makes the 64-bit virtual address space defined by the Alpha and Itanium architectures available to both the OpenVMS operating system and its users. It also allows per-process virtual addressing for accessing dynamically mapped data beyond traditional 32-bit limits.

The HP C Run-Time Library on OpenVMS Alpha and OpenVMS I64 systems includes the following features in support of 64-bit pointers:

See the HP C Run-Time Library Reference Manual for OpenVMS Systems for a description of the 64-bit addressing support provided by the HP C Run-Time Library.

Chapter 12
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64

This chapter describes the use of memory management system services and run-time routines on Alpha and I64 systems. Although the operating system's memory management concepts are much the same on VAX, Alpha, and I64 systems, details of the memory management system are different. These details may be critical to certain uses of the operating system's memory management system services and routines on an Alpha and I64 system.

This chapter contains the following sections:

Section 12.1 describes the page sizes of Alpha and I64 systems.

Section 12.2 describes the three levels of the operating system's memory allocation routines.

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

Section 12.4 describes large page-file sections.

12.1 Virtual Page Sizes

On Alpha systems, in order to facilitate memory protection and mapping, the virtual address space is subdivided into segments of 8 KB, 16 KB, 32 KB, or 64 KB sizes called CPU-specific pages. On VAX systems, the page sizes are 512 bytes. Intel Itanium processors support a range of page sizes to assist operating systems to virtually map system resources. All Intel Itanium processors support page sizes of 4 KB, 8 KB, 16 KB, 64 KB, 256 KB, 1 MB, 4 MB, 16 MB, 64 MB, and 256 MB. For compatibility with OpenVMS Alpha systems, OpenVMS I64 uses the 8 KB page size by default. (Larger default page sizes may be used in future versions of OpenVMS.)

Wherever possible, the Alpha and I64 system's versions of the system services and run-time library routines that manipulate memory attempt to preserve compatibility with the VAX system's services and routines. The Alpha and I64 system's versions of the routines that accept page count values as arguments still interpret these arguments in 512-byte quantities, which are called pagelets to distinguish them from CPU-specific page sizes. The routines convert pagelet values into CPU-specific pages. The routines that return page count values convert from CPU-specific pages to pagelets, so that return values expected by applications are still measured in the same 512-byte units.

This difference in page size does not affect memory allocation using higher-level routines, such as run-time library routines that manipulate virtual memory zones or language-specific memory allocation routines such as the malloc and free routines in C.

To determine system page size, you make a call to the SYS$GETSYI system service, specifying the SYI$_PAGE_SIZE item code. See the description of SYS$GETSYI and SYI$_PAGE_SIZE in the HP OpenVMS System Services Reference Manual for details.

12.2 Levels of Memory Allocation Routines

Sophisticated software systems must often create and manage complex data structures. In these systems, the size and number of elements are not always known in advance. You can tailor the memory allocation for these elements by using dynamic memory allocation. By managing the memory allocation, you can avoid allocating fixed tables that may be too large or too small for your program. Managing memory directly can improve program efficiency. By allowing you to allocate specific amounts of memory, the operating system provides a hierarchy of routines and services for memory management. Memory allocation and deallocation routines allow you to allocate and free storage within the virtual address space available to your process.

There are three levels of memory allocation routines:

  1. Memory management system services
    The memory management system services comprise the lowest level of memory allocation routines. 64-bit services include, but are not limited to, the following:
    32-bit services include, but are not limited to, the following:
    For most cases in which a system service is used for memory allocation, the Expand Region (SYS$EXPREG or SYS$EXPREG_64) system service is used to create pages of virtual memory.
    Because system services provide more control over allocation procedures than RTL routines, you must manage the allocation precisely. System services provide extensive control over address space allocation by allowing you to do the following types of tasks:
  2. RTL page management routines
    The RTL routines exist for creating, deleting, and accessing information about virtual address space. You can either allocate a specified number of contiguous pages or create a zone of virtual address space. A zone is a logical unit of the memory pool or subheap that you can control as an independent area. It can be any size required by your program. Refer to Chapter 14 for more information about zones.
    The RTL page management routines LIB$GET_VM_PAGE, LIB$GET_VM_PAGE_64, LIB$FREE_VM_PAGE, and LIB$FREE_VM_PAGE_64 provide a convenient mechanism for allocating and freeing pages of memory.
    These routines maintain a processwide pool of free pages. If unallocated pages are not available when LIB$GET_VM_PAGE is called, it calls SYS$EXPREG to create the required pages in the program region (P0 space). For LIB$GET_VM_PAGE_64, if there are not enough contiguous free pagelets to satisfy an allocation request, additional pagelets are created by calling the system service SYS$EXPREG_64.

  3. RTL heap management routines
    The RTL heap management routines LIB$GET_VM, LIB$GET_VM_64, LIB$FREE_VM, and LIB$FREE_VM_64 provide a mechanism for allocating and freeing blocks of memory of arbitrary size.
    The following are heap management routines based on the concept of zones:

Modular application programs can call routines in any or all levels of the hierarchy, depending on the kinds of services the application program needs. You must observe the following basic rule when using multiple levels of the hierarchy:

Memory that is allocated by an allocation routine at one level of the hierarchy must be freed by calling a deallocation routine at the same level of the hierarchy. For example, if you allocated a page of memory by calling LIB$GET_VM_PAGE, you can free it only by calling LIB$FREE_VM_PAGE.

For information about using memory management RTLs, see Chapter 14.

Previous Next Contents Index