|Document revision date: 30 March 2001|
Event flags allow modular procedures to communicate with each other and to synchronize their operations. Because they can be allocated at run time, event flags allow one procedure to run independently of other procedures existing in the same process.
Event flags are allocated and deallocated by the run-time library
procedures LIB$GET_EF and LIB$FREE_EF. (For more information, see the
descriptions of the LIB$GET_EF and LIB$FREE_EF procedures in the
OpenVMS Programming Concepts Manual and the OpenVMS RTL Library (LIB$) Manual.)
2.4.3 Using Logical Unit Numbers
A logical unit number is used to define either the device or file a program uses to perform input and output. Modular procedures do not need to know the unit numbers of other procedures running at the same time.
Logical unit numbers are used only in BASIC and FORTRAN.
Logical unit numbers should be allocated and deallocated using the
LIB$GET_LUN and LIB$FREE_LUN RTL procedures. (For more information
about using logical unit numbers, see the descriptions of the
LIB$GET_LUN and LIB$FREE_LUN procedures in the OpenVMS Programming Concepts Manual and the
OpenVMS RTL Library (LIB$) Manual.)
2.5 Using Input/Output
In general, your procedure's input/output (I/O) is directed to either the terminal or a file. (In some cases, you may need to use mailbox I/O and network operations. For information about these areas, see the DECnet for OpenVMS Networking Manual.) Regardless of whether you are directing input/output to the terminal screen or to a file, you must follow two rules to maintain modularity:
The methods available for performing input/output to the terminal include the following:
During I/O to the terminal, it is important that the procedure and the main program cooperate in controlling the terminal screen. For example, an I/O procedure may write something to the terminal screen that the calling program wants to erase. To erase it, the calling program must know both what and where that information is. The calling program and the called procedure must communicate by passing arguments that define which part of the screen will be accessed by each. The run-time library contains Screen Management (SMG$) procedures for this purpose.
Do not combine different methods of I/O within your application.
Problems can arise if the calling program and the called procedure use
different methods of I/O. Each method of performing input/output
maintains some knowledge of what is on the terminal screen. At the very
least, the current cursor position is remembered. If another type of
I/O is performed, that information is not updated and, therefore,
becomes incorrect. The results of any subsequent I/O would be
unpredictable. If you must combine other methods with uses of SMG$
procedures, use the SMG$ procedures that aid such an integration.
2.5.2 File Input/Output
File I/O can be performed by the following methods:
You should document every module you create so that you and others know what the procedure does. Each module should include:
In most cases, a module should contain only one procedure.
2.6.1 Writing a Module Preface
At the beginning of every module, include a preface that contains the following information:
|Title:||Module name followed by a one-line functional description.|
|Version:||Version and a three-digit edit number. Generally 1-001 is the original version.|
|Facility:||Description of the library facility, such as general utility library (LIB).|
|Abstract:||Short (three to six lines) functional description of the module.|
Describe any special environmental assumptions that the module can
make. These include assumptions made at both compilation and execution
time that could affect either the hardware or software environments.
Describes situations that the module assumes during execution time and optional modular programming elements that your module does not follow.
Indicates the reentrancy characteristics of the procedures in this module. Each procedure is either fully reentrant, AST reentrant, or nonreentrant.
|Author:||Your name and date the module was created.|
|Modified by:||Modification number, name of modifying programmer, modification date, and a list of the modifications.|
End the preface with a page delimiter. After the preface, include the code for the procedure.
Example 2-4 shows a sample module description.
|Example 2-4 Sample Module Description|
PROGRAM GRA_CUBE ! Create representation of a cube !+ ! VERSION: 1-002 ! ! FACILITY: User Graphics Computation Library ! ! ABSTRACT: This module contains a procedure to create a mathematical ! representation of a cube, GRA_CUBE. ! ! ENVIRONMENT: User Mode, AST-reentrant ! ! AUTHOR: John Smith CREATION DATE: 14-Sep-1993 ! ! MODIFIED BY: ! 1-001 - Original. DWS 14-Sep-1993 ! 1-002 - Fix a minor bug in cube volume computation. MDL 15-Mar-1993 !-
At the beginning of every procedure in a module, describe the procedure by including the information in this section. Include all the description elements, even if they are not in the procedure. For example, if a procedure has no implicit inputs, write the following:
! ! Implicit Inputs: ! ! NONE !
Every procedure description should include the following information:
Describes a procedure's purpose and completely documents its interfaces.
Includes the basis for any critical algorithms used, including literature references where applicable, and explains why a particular algorithm was chosen.
Indicates the reentrancy characteristics of this procedure if they differ from those given in the module description.
Includes these elements in the following order:
In VAX MACRO, each argument is symbolically defined as the offset relative to the argument pointer (AP).
Lists the arguments in the order they will appear in a high-level language. Each argument characteristic should also be included, using the procedure argument notation described in OpenVMS Programming Interfaces: Calling a System Routine. Note that this manual has been archived but is available on the OpenVMS Documentation CD-ROM.
|Formal arguments:||Lists any explicit input, input/output, or output arguments. Includes a qualifying description with each argument. The arguments should be listed in the order they are listed in the calling sequence.|
|Implicit inputs:||Lists any inputs from storage, internal or external to the module, that are not specified in the argument list. Usually all that will appear here is NONE. See Section 2.2.2.|
|Implicit outputs:||Lists any outputs to internal or external storage that are not specified in the argument list.|
Completion status or
|Lists the success or failure condition value symbols that could be returned. If your procedure returns a function value other than a condition value, change the heading to "Routine value."|
|Side effects:||Describes any functional side effects not evident from a procedure's calling sequence. This includes changes in storage allocation, process status, file operations, and possible signaled conditions. In general, you should document anything out of the ordinary that the procedure does to the environment. If a side effect modifies local or global storage locations, document it in the implicit output description instead.|
Example 2-5 shows a sample procedure description.
|Example 2-5 Sample Procedure Description|
!++ ! FUNCTIONAL DESCRIPTION: ! ! Return the system date and time, using the caller's ! semantics for his/her string. ! ! Non-reentrant; uses static storage. ! ! FORMAL ARGUMENT(S): ! ! RESULT_ADDR ! VMS USAGE : char_string ! TYPE : character string ! ACCESS : write only ! MECHANISM : by descriptor ! ! Address of the descriptor into which the ! system date and time is written. ! ! IMPLICIT INPUTS: ! ! NONE ! ! IMPLICIT OUTPUTS: ! ! NONE ! ! COMPLETION CODES: ! ! SS$_NORMAL Procedure successfully completed ! LIB$_STRTRU Success, but source string truncated ! ! SIDE EFFECTS: ! ! Requests the current date and time from OpenVMS. ! !--
Two methods are available to a procedure for indicating to its caller whether it completed successfully. One method is to return a condition value. The other method is to signal an error condition.
To provide a better user interface, all procedures in a facility should
either return condition values or signal error conditions. Regardless
of which method you choose, you should be consistent within the
facility to make the procedures easier for the user to call.
2.7.1 Guidelines for Signaling Error Conditions
The signaling of an error condition is, in some instances, mandatory.
Procedures that return a function value cannot also return a condition value and therefore must signal any error conditions encountered.
However, to maintain efficiency, you might want other procedures to signal error conditions also. Checking the return status of a called procedure for repetitive calls can be time consuming and adversely affect the performance of the calling program. For example, if you are going to call a procedure 100 times within a loop and the chances of that procedure's failure are small, you may not want to take the time to check the return status after each call to make sure that the condition value returned was SS$_NORMAL. Signaling error conditions is far more efficient in this type of application.
From the point of view of the calling program, handling a signaled condition is slightly more difficult than checking a returned condition value because it involves writing a condition handler to be invoked in the event that an error condition is signaled. However, handling a signaled condition allows the calling program to execute more efficiently.
To signal an error condition, your procedure uses either a
condition-handling mechanism provided by the source language, or it
calls the Run-Time Library procedure LIB$SIGNAL. To use LIB$SIGNAL,
your procedure calls LIB$SIGNAL and specifies the condition code and
zero or more arguments specifying the environment of the condition. For
more information about using LIB$SIGNAL, see the OpenVMS RTL Library (LIB$) Manual.
2.7.2 Guidelines for Returning Condition Values
From the point of view of the calling program, it is much easier to check returned condition values than to handle signaled error conditions. When the condition value is being returned, the calling program does not need to include a condition handler. The calling program needs only to check the status of the returned value.
However, if you return condition values rather than signal error conditions, you return less information about the error condition to the calling program. Compaq recommends that you return condition values when the explanation of the error condition is simple and self-contained. For example, LIB$GET_VM returns a condition value, because the possible status conditions are self-contained and simple (for example, insufficient virtual memory).
According to the OpenVMS Calling Standard, the status returned must be a condition
value. (For more information, see OpenVMS Programming Interfaces: Calling a System Routine1.
2.7.3 When to Signal or Return Condition Values
To some degree, whether you decide to signal an error condition or return a condition value depends on the language you are using for your procedure. In some high-level languages, it is difficult to write a condition handler to be invoked in the event that an error condition is signaled. (For more information about condition handling in your language, consult the appropriate language reference manual.)
Regardless of which language you are using, there are general guidelines for when to return a condition value and when to signal an error condition.
You should signal an error condition in the following situations:
You should return a condition value in the following situations:
1 This manual has been archived but is available on the OpenVMS Documentation CD-ROM.
|privacy and legal statement|