HP OpenVMS Systems Documentation
OpenVMS Programming Concepts Manual
19.4 Calling a Library Routine in BLISS
This section describes how to code BLISS calls to library routines. A called routine can return only one of the following:
19.4.1 BLISS Calling Sequence
Scalar arguments are usually passed to run-time library routines by reference. Thus, when a BLISS program passes a variable, the variable appears with no preceding period in the procedure-call actual argument list. A constant value can be easily passed by using the %REF built-in function.
The following example shows how a BLISS program calls LIB$PUT_OUTPUT. This routine writes a record at the user's terminal.
19.4.2 Accessing a Return Status in BLISS
BLISS accesses a function return value or condition value returned in R0 as follows:
19.4.3 Calling JSB Entry Points from BLISS
Many of the library mathematics routines have JSB entry points. You can invoke these routines efficiently from a BLISS procedure using LINKAGE and EXTERNAL ROUTINE declarations, as in the following example:
The symbolic names are defined by the symbolic definition macro SYS$PSLDEF.
System services that permit an access mode argument allow callers to specify only an access mode of equal or lesser privilege than the access mode from which the service was called. If the specified access mode is more privileged than the access mode from which the service was called, the less privileged access mode is always used.
To determine the mode to use, the operating system compares the specified access mode with the access mode from which the service was called. Because this operation results in an access mode with a higher numeric value (when the access mode of the caller is different from the specified access mode), the access mode is said to be maximized.
Because much of the code you write executes in user mode, you can omit
the access mode argument. The argument value defaults to 0 (kernel
mode), and when this value is compared with the value of the current
execution mode (3, user mode), the higher value (3) is used.
20.3 System Service Call Entry
The Format section of each system service description in the OpenVMS System Services Reference Manual indicates the positional dependencies and keyword names of each argument, as shown in the following format:
$SERVICE arga ,argb ,argc ,argd
This format indicates that the macro name of the service is $SERVICE and that it requires four arguments, ordered as shown and with keyword names arga, argb, argc, and argd.
Arguments passed to a service must be listed in your call entry in the order shown in the Format section of the service description. Each argument has four characteristics: OpenVMS usage, data type, access type, and passing mechanism. These characteristics are described in Chapter 17.
The OpenVMS Alpha SYS$LIBRARY:SYS$LIB_C.TLB file contains C function prototypes for system services. These prototypes are documented in OpenVMS System Services Reference Manual: A--GETUAI and and OpenVMS System Services Reference Manual: GETUTC--Z. For each prototype, the manuals provide the correct syntax (which shows the arguments the function accepts in the order in which it expects them), a description of each argument, and the type of data returned by the function.
Some arguments are optional. Optional arguments are indicated by brackets in the service descriptions. When your program invokes a system service by using a CALL entry point, you can omit optional arguments at the end of the argument list. If the optional argument is not the last argument in the list, you must either pass a zero by value or use a comma to indicate the place of the omitted argument. Some languages, such as C, require that you pass a zero by value for all trailing optional arguments. See your language processor documentation for further information.
In the call statement of a high-level language program, you must prefix the macro function service name with SYS (the system service facility prefix). For example, the call statement in a C program procedure that calls the SYS$GETDVI system service with four arguments is as follows:
return_status = sys$getdvi( event_flagnum, channel, &devnam, &item_list,0,0,0);
Note that in C, you must not omit the optional trailing arguments and should pass a zero by value for these unused parameters. See your language processor documentation for further information.
The OpenVMS System Services Reference Manual provides a description of each service that indicates how each argument is to be passed. Phrases such as "an address" and "address of a character string descriptor" identify reference and descriptor arguments, respectively. Terms like "Boolean value," "number," "value," or "mask" indicate an argument that is passed by value.
In the Alpha and VAX environments, the called routine interprets each argument using one of three standard passing mechanisms: by value, by reference, or by descriptor.
On VAX systems, the calling program passes an argument list of longwords to a called service; each longword in the argument list specifies a single argument.
On Alpha systems, the calling program passes arguments in an argument item sequence; each quadword in the sequence specifies a single argument item. Note that the argument item sequence is formed using R16--R21 or F16--F21 (a register for each argument).
Some services also require service-specific data structures that either
indicate functions to be performed or hold information to be returned.
The OpenVMS System Services Reference Manual includes descriptions of these service-specific data
structures. You can use this information and information from your
programming language manuals to define such service-specific item lists.
20.4 System Service Completion
When a system service completes, control is returned to your program. You can specify how and when control is returned to your program by choosing synchronous or asynchronous forms of system services and by enabling process execution modes.
The following sections describe:
You can execute a number of system services either asynchronously or synchronously (such as, SYS$GETJPI and SYS$GETJPIW or SYS$ENQ and SYS$ENQW). The W at the end of the system service name indicates the synchronous version of the system service.
The asynchronous version of a system service queues a request and returns control to your program. You can perform operations while the system service executes; however, you should not attempt to access information returned by the service until you check for the system service completion.
Typically, you pass to an asynchronous system service an event flag and an I/O status block or a lock status block. When the system service completes, it sets the event flag and places the final status of the request in the status block. You use the SYS$SYNCH system service to ensure that the system service has completed. You pass SYS$SYNCH the event flag and the status block that you passed to the asynchronous system service; SYS$SYNCH waits for the event flag to be set, then ensures that the system service (rather than some other program) sets the event flag by checking the status block. If the status block is still zero, SYS$SYNCH waits until the status block is filled.
The synchronous version of a system service acts exactly as if you had used the asynchronous version followed immediately by a call to SYS$SYNCH. If you omit the efn argument, the service uses event flag number 0 whether you use the synchronous or asynchronous version of a system service.
Example 20-1 illustrates the use of the SYS$SYNCH system service to check the completion status of the asynchronous service SYS$GETJPI.
|Example 20-1 Example of SYS$SYNCH System Service in FORTRAN|
! Data structure for SYS$GETJPI . . . INTEGER*4 STATUS, 2 FLAG, 2 PID_VALUE ! I/O status block INTEGER*2 JPISTATUS, 2 LEN INTEGER*4 ZERO /0/ COMMON /IO_BLOCK/ JPISTATUS, 2 LEN, 2 ZERO . . . ! Call SYS$GETJPI and wait for information STATUS = LIB$GET_EF (FLAG) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) STATUS = SYS$GETJPI (%VAL(FLAG), 2 PID_VALUE, 2 , 2 NAME_BUF_LEN, 2 JPISTATUS, 2 ,) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) . . . STATUS = SYS$SYNCH (%VAL(FLAG), 2 JPISTATUS) IF (.NOT. JPISTATUS) THEN CALL LIB$SIGNAL (%VAL(JPISTATUS)) END IF END
Normally, when a system service is called and a required resource is not available, the process is placed in a wait state until the resource becomes available. Then the service completes execution. This mode is called resource wait mode.
In a real-time environment, however, it may not be practical or desirable for a program to wait. In these cases, you can choose to disable resource wait mode so that when a required resource is unavailable, control returns immediately to the calling program with an error condition value. You can disable (and reenable) resource wait mode with the Set Resource Wait Mode (SYS$SETRWM) system service.
If resource wait mode is disabled, it remains disabled until it is explicitly reenabled or until your process is deleted. For example, if your program has disabled resource wait mode and has exited to the DCL prompt, subsequent programs or utilities invoked by this process continue to run with resource wait mode disabled and might not perform properly because they are not prepared to handle a failure to obtain a resource. In this case, you should reenable the wait mode before your program exits to the DCL prompt.
How a program responds to the unavailability of a resource depends
primarily on the application and the particular service being called.
In some instances, the program may be able to continue execution and
retry the service call later. In other instances, it may be necessary
for the program to wait for the resource and the system service to
20.4.3 Condition Values Returned from System Services
When a service returns control to your program, it places a return status value in the general register R0. The value in the low-order word indicates either that the service completed successfully or that some specific error prevented the service from performing some or all of its functions. After each call to a system service, you must check whether it completed successfully. You can also test for specific errors in the condition value.
Depending on your specific needs, you can test just the low-order bit, the low-order 3 bits, or the entire condition value, as follows:
|4||Severe or fatal error||STS$K_SEVERR|
Each numeric condition value has a unique symbolic name in the following format:
where code is a mnemonic describing the return condition.
For example, the following symbol usually indicates a successful return:
An example of an error return condition value is as follows:
This condition value indicates that an access violation occurred because a service could not read an input field or write an output field.
The symbolic definitions for condition values are included in the default system library SYS$LIBRARY:STARLET.OLB. You can obtain a listing of these symbolic codes at assembly time by invoking the system macro SYS$SSDEF. To check return conditions, use the symbolic names for system condition values.
The OpenVMS operating system does not automatically handle system service failure or warning conditions; you must test for them and handle them yourself. This contrasts with the operating system's handling of exception conditions detected by the hardware or software; the system handles these exceptions by default, although you can intervene in or override the default handling by declaring a condition handler.