HP OpenVMS systems
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.
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.
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.
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.
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.
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.
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)
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
structure, passes the 64-bit
argument by reference and passes the 64-bit
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:
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,
DBG> EVALUATE/ADDRESS/HEX %hex 000004A0 00000000000004A0 DBG>
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.
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:
$ RUN SYS$SYSTEM:SYSGEN SYSGEN> SET MAXBUF 64000 SYSGEN> WRITE ACTIVE SYSGEN> EXIT
Before invoking WP, you must install the WPDRIVER with SYSMAN, as follows:
$ RUN SYS$SYSTEM:SYSMAN SYSMAN> IO CONNECT WPA0/DRIVER=SYS$WPDRIVER/NOADAPTER SYSMAN> EXIT
You can then invoke WP with the following command:
$ RUN SYS$SYSTEM:WP
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:
$ SET TERM/WIDTH=132
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:
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.
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.
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:
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.