 |
HP OpenVMS Programming Concepts Manual
8.7.3.2 Inner Mode (Executive and Kernel) AST Delivery
Before kernel threads, OpenVMS implemented AST preemptions in inner
modes as follows:
- An executive mode AST can preempt non-AST executive mode processing.
- A kernel mode AST can preempt non-AST kernel mode processing, or
any executive mode processing.
- A special kernel mode AST can preempt a normal kernel mode AST,
non-AST kernel mode, or any executive mode.
- No ASTs can be delivered when interrupt priority level (IPL) is
raised to 2 or above. Special kernel mode ASTs execute entirely at IPL
2 or above, which is what prevents other kernel mode ASTs from
executing while the special kernel mode AST is active.
After kernel threads, in contrast to the preceeding list, kernel
threads deliver any non thread-safe inner mode ASTs to the kernel
thread that already owns the semaphore. If no thread currently owns the
semaphore when the AST is queued, then the semaphore is acquired in
SCH$QAST, and the owner is set to the target kernel thread for that
AST. Subsequently queued ASTs see that thread as the semaphore owner
and are delivered to that thread. This allows the PALcode and the
hardware architecture to process all the AST preemption and ordering
rules.
8.8 ASTs and Process Wait States
A process in a wait state can be interrupted for the delivery of an AST
and the execution of an AST service routine. When the AST service
routine completes execution, the process is returned to the wait state,
if the condition that caused the wait is still in effect.
With the exception of suspended waits (SUSP) and suspended outswapped
waits (SUSPO), any wait states can be interrupted.
8.8.1 Event Flag Waits
If a process is waiting for an event flag and is interrupted by an AST,
the wait state is restored following execution of the AST service
routine. If the flag is set at completion of the AST service routine
(for example, by completion of an I/O operation), then the process
continues execution when the AST service routine completes.
Event flags are described in Section 6.8 of Chapter 6.
8.8.2 Hibernation
A process can place itself in a wait state with the Hibernate
(SYS$HIBER) system service. This state can be interrupted for the
delivery of an AST. When the AST service routine completes execution,
the process continues hibernation. The process can, however,
"wake" itself in the AST service routine or be awakened
either by another process or as the result of a timer-scheduled wakeup
request. Then, it continues execution when the AST service routine
completes.
Process suspension is another form of wait; however, a suspended
process cannot be interrupted by an AST. Process hibernation and
suspension are described in Chapter 4.
8.8.3 Resource Waits and Page Faults
When a process is executing an image, the system can place the process
in a wait state until a required resource becomes available, or until a
page in its virtual address space is paged into memory. These waits,
which are generally transparent to the process, can also be interrupted
for the delivery of an AST.
8.9 Examples of Using AST Services
The following is an example of an HP Fortran program that finds the
process identification (PID) number of any user working on a particular
disk and delivers an AST to a local routine that notifies the user that
the disk is coming down:
PROGRAM DISK_DOWN
! Implicit none
! Status variable
INTEGER STATUS
STRUCTURE /ITMLST/
UNION
MAP
INTEGER*2 BUFLEN,
2 CODE
INTEGER*4 BUFADR,
2 RETLENADR
END MAP
MAP
INTEGER*4 END_LIST
END MAP
END UNION
END STRUCTURE
RECORD /ITMLST/ DVILIST(2),
2 JPILIST(2)
! Information for GETDVI call
INTEGER PID_BUF,
2 PID_LEN
! Information for GETJPI call
CHARACTER*7 TERM_NAME
INTEGER TERM_LEN
EXTERNAL DVI$_PID,
2 JPI$_TERMINAL
! AST routine and flag
INTEGER AST_FLAG
PARAMETER (AST_FLAG = 2)
EXTERNAL NOTIFY_USER
INTEGER SYS$GETDVIW,
2 SYS$GETJPI,
2 SYS$WAITFR
! Set up for SYS$GETDVI
DVILIST(1).BUFLEN = 4
DVILIST(1).CODE = %LOC(DVI$_PID)
DVILIST(1).BUFADR = %LOC(PID_BUF)
DVILIST(1).RETLENADR = %LOC(PID_LEN)
DVILIST(2).END_LIST = 0
! Find PID number of process using SYS$DRIVE0
STATUS = SYS$GETDVIW (,
2 ,
2 '_MTA0:', ! device
2 DVILIST, ! item list
2 ,,,)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
! Get terminal name and fire AST
JPILIST(1).CODE = %LOC(JPI$_TERMINAL)
JPILIST(1).BUFLEN = 7
JPILIST(1).BUFADR = %LOC(TERM_NAME)
JPILIST(1).RETLENADR = %LOC(TERM_LEN)
JPILIST(2).END_LIST = 0
STATUS = SYS$GETJPI (,
2 PID_BUF, !process id
2 ,
2 JPILIST, !itemlist
2 ,
2 NOTIFY_USER, !AST
2 TERM_NAME) !AST arg
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Ensure that AST was executed
STATUS = SYS$WAITFR(%VAL(AST_FLAG))
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
END
SUBROUTINE NOTIFY_USER (TERM_STR)
! AST routine that broadcasts a message to TERMINAL
! Dummy argument
CHARACTER*(*) TERM_STR
CHARACTER*8 TERMINAL
INTEGER LENGTH
! Status variable
INTEGER STATUS
CHARACTER*(*) MESSAGE
PARAMETER (MESSAGE =
2 'SYS$TAPE going down in 10 minutes')
! Flag to indicate AST executed
INTEGER AST_FLAG
! Declare system routines
INTRINSIC LEN
INTEGER SYS$BRDCST,
2 SYS$SETEF
EXTERNAL SYS$BRDCST,
2 SYS$SETEF,
2 LIB$SIGNAL
! Add underscore to device name
LENGTH = LEN (TERM_STR)
TERMINAL(2:LENGTH+1) = TERM_STR
TERMINAL(1:1) = '_'
! Send message
STATUS = SYS$BRDCST(MESSAGE,
2 TERMINAL(1:LENGTH+1))
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Set event flag
STATUS = SYS$SETEF (%VAL(AST_FLAG))
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
END
|
The following is an example of a C program setting up an AST:
#module SETAST "SRH X1.0-000"
#pragma builtins
/*
**++
** Facility:
**
** Examples
**
** Version: V1.0
**
** Abstract:
**
** Example of working with the $SETAST call and ASTs.
**
** Author:
** Steve Hoffman
**
** Creation Date: 1-Jan-1990
**
** Modification History:
**--
*/
/*
* AST and $SETAST demo
* raise the AST shields
* request an AST, parameter is 1
* request an AST, parameter is 2
* lower the shields
* <bing1><bing2>
*/
main()
{
int retstat = 0;
int bogus();
int SYS$SETAST();
int SYS$DCLAST();
printf("\ndisabling\n");
/*
* $SETAST() returns SS$_WASSET and SS$_WASCLR depending
* on the previous setting of the AST shield. Watch out,
* SS$_WASSET looks like a SUCCESSFUL SS$_ACCVIO. (ie:
* a debug EXAMINE/COND shows SS$_WASSET as the error
* %SYSTEM-S-ACCVIO. *Real* ACCVIO's never have the "-S-"
* code!)
*/
retstat = SYS$SETAST( 0 );
printf("\n disable/ was: %d\n", retstat );
retstat = SYS$DCLAST( bogus, 1, 0 );
retstat = SYS$DCLAST( bogus, 2, 0 );
printf("\ndclast %x\n", retstat );
printf("\nenabling\n" );
retstat = SYS$SETAST( 1 );
/*
* and, since we just lowered the shields, the ASTs should hit
* in here somewhere....
*/
printf("\n enable/ was: %d\n", retstat );
return( 1 );
};
/*
* and, here's the entire, sophisticated, twisted AST code...
*/
bogus( astprm )
int astprm;
{
printf("\nAST tripped. ast parameter was 0x%x\n\n", astprm);
return( 1 );
};
|
Chapter 9 Condition-Handling Routines and Services
This chapter describes the OpenVMS Condition Handling facility and
contains the following sections:
Section 9.1 gives an overview of run-time errors.
Section 9.2 gives an overview of the OpenVMS Condition Handling
facility, presenting condition-handling terminology and functionality.
Section 9.3 describes VAX, Alpha, and I64 system exceptions,
arithmetic exceptions, and unaligned access traps on Alpha and I64
systems.
Section 9.4 describes how run-time library routines handle exceptions.
Section 9.5 describes the condition value field and the testing and
modifying of values.
Section 9.6 describes the exception dispatcher.
Section 9.7 describes the argument list that is passed to a condition
handler.
Section 9.8 describes signaling.
Section 9.9 describes types of condition handlers.
Section 9.10 describes types of actions performed by condition
handlers.
Section 9.11 describes messages and how to use them.
Section 9.12 describes how to write a condition handler.
Section 9.13 describes how to debug a condition handler.
Section 9.14 describes several run-time library routines that can be
established as condition handlers.
Section 9.15 describes how to establish, write, and debug an exit
handler.
9.1 Overview of Run-Time Errors
Run-time errors are hardware- or software-detected events, usually
errors, that alter normal program execution. Examples of run-time
errors are as follows:
- System errors---for example, specifying an invalid argument to a
system-defined procedure
- Language-specific errors---for example, in Fortran, a data type
conversion error during an I/O operation
- Application-specific errors---for example, attempting to use
invalid data
When an error occurs, the operating system either returns a condition
code or value identifying the error to your program or signals the
condition code. If the operating system signals the condition code, an
error message is displayed and program execution continues or
terminates, depending on the severity of the error. See Section 9.5
for details about condition values.
When unexpected errors occur, your program should display a message
identifying the error and then either continue or stop, depending on
the severity of the error. If you know that certain run-time errors
might occur, you should provide special actions in your program to
handle those errors.
Both an error message and its associated condition code identify an
error by the name of the facility that generated it and an abbreviation
of the message text. Therefore, if your program displays an error
message, you can identify the condition code that was signaled. For
example, if your program displays the following error message, you know
that the condition code SS$_NOPRIV was signaled:
%SYSTEM-F-NOPRIV, no privilege for attempted operation
|
9.2 Overview of the OpenVMS Condition Handling Facility
The operating system provides a set of signaling and condition-handling
routines and related system services to handle exception conditions.
This set of services is called the OpenVMS Condition Handling facility
(CHF). The OpenVMS Condition Handling Facility is a part of the common
run-time environment of OpenVMS, which includes run-time library (RTL)
routines and other components of the operating system.
The OpenVMS Condition Handling facility provides a single, unified
method to enable condition handlers, signal conditions, print error
messages, change the error behavior from the system default, and enable
or disable detection of certain hardware errors. The RTL and all
layered products of the operating system use the CHF for condition
handling.
See the HP OpenVMS Calling Standard for a detailed description of OpenVMS condition
handling.
9.2.1 Condition-Handling Terminology
This section defines the terms used to describe condition handling.
exception
An event detected by the hardware or software that changes the normal
flow of instruction execution. An exception is a synchronous event
caused by the execution of an instruction and often means something
generated by hardware. When an exception occurs, the processor
transfers control by forcing a change in the flow of control from that
explicitly indicated in the currently executing process.
Some exceptions are relevant primarily to the current process and
normally invoke software in the context of the current process. An
integer overflow exception detected by the hardware is an example of an
event that is reported to the process. Other exceptions, such as page
faults, are handled by the operating system and are transparent to the
user.
An exception may also be signaled by a routine (software signaling) by
calling the RTL routines LIB$SIGNAL or LIB$STOP.
condition
An informational state that exists when an exception occurs.
Condition is a more general term than exception; a
condition implies either a hardware exception or a software-raised
condition. Often, the term condition is preferred because the term
exception implies an error. Section 9.3.1 further defines the
differences between exceptions and conditions.
condition handling
When a condition is detected during the execution of a routine, a
signal can be raised by the routine. The routine is then permitted to
respond to the condition. The routine's response is called
handling the condition.
On VAX systems, an address of 0 in the first longword of a procedure
call frame or in an exception vector indicates that a condition handler
does not exist for that call frame or vector.
On Alpha systems, the handler valid flag bit in the procedure
descriptor is cleared to indicate that a condition handler does not
exist.
On I64 systems, the handler present flag bit in the frame flags field
of the invocation context block indicates the presence of a condition
handler.
The condition handlers are themselves routines; they have their own
call frames. Because they are routines, condition handlers can have
condition handlers of their own. This allows condition handlers to
field exceptions that might occur within themselves in a modular
fashion.
On VAX systems, a routine can enable a condition handler by placing the
address of the condition handler in the first longword of its stack
frame.
On Alpha and I64 systems, the association of a handler with a procedure
is static and must be specified at the time a procedure is compiled (or
assembled). Some languages that lack their own exception-handling
syntax, however, may support emulation of dynamic specified handlers by
means of built-in routines.
If you determine that a program needs to be informed of particular
exceptions so it can take corrective action, you can write and specify
a condition handler. This condition handler, which receives control
when any exception occurs, can test for specific exceptions.
If an exception occurs and you have not specified a condition handler,
the default condition handler established by the operating system is
given control. If the exception is a fatal error, the default condition
handler issues a descriptive message and causes the image that incurred
the exception to exit.
To declare or enable a condition handler, use the following system
services:
- Set Exception Vector (SYS$SETEXV)
- Unwind from Condition Handler Frame (SYS$UNWIND)
- Declare Change Mode or Compatibility Mode Handler (SYS$DCLCMH)
Parallel mechanisms exist for uniform dispatching of hardware and
software exception conditions. Exceptions that are detected and
signaled by hardware transfer control to an exception service routine
in the executive. Software-detected exception conditions are generated
by calling the run-time library routines LIB$SIGNAL or LIB$STOP.
Hardware- and software-detected exceptions eventually execute the same
exception dispatching code. Therefore, a condition handler may handle
an exception condition generated by hardware or by software identically.
The Set Exception Vector (SYS$SETEXV) system service allows you to
specify addresses for a primary exception handler, a secondary
exception handler, and a last-chance exception handler. You can specify
handlers for each access mode. The primary exception vector is reserved
for the debugger. In general, you should avoid using these vectored
handlers unless absolutely necessary. If you use a vectored handler, it
must be prepared for all exceptions occurring in that access mode.
9.2.2 Functions of the Condition Handling Facility
The OpenVMS Condition Handling facility and the related run-time
library routines and system services perform the following functions:
- Establish and call condition-handler routines
You can establish condition handlers to receive control in the
event of an exception in one of the following ways:
- On VAX systems, by specifying the address of a condition handler in
the first longword of a procedure call frame.
On Alpha and I64
systems, the method for establishing a dynamic (that is, nonvectored)
condition handler is specified by the language.
- By establishing exception handlers with the Set Exception Vector
(SYS$SETEXV) system service.
The first of these methods is the preferred way to specify a
condition handler for a particular image. The use of dynamic handlers
is also the most efficient way in terms of declaration. You should use
vectored handlers for special purposes, such as writing debuggers.
The VAX MACRO programmer can use the following single-move address
instruction to place the address of the condition handler in the
longword pointed to by the current frame pointer (FP):
You can associate a condition handler for the currently executing
routine by specifying an address pointing to the handler, either in the
routine's stack frame on VAX systems or in one of the exception
vectors. (The Macro-32 compilers for OpenVMS Alpha and I64 systems
generate the appropriate code from this VAX instruction to establish a
dynamic condition handler.)
On VAX systems, the high-level language programmer can call the
common run-time library routine LIB$ESTABLISH (see the HP OpenVMS RTL Library (LIB$) Manual),
using the name of the handler as an argument. LIB$ESTABLISH returns as
a function value either the address of the former handler established
for the routine or 0 if no handler existed.
On VAX systems, the new condition handler remains in effect for your
routine until you call LIB$REVERT or control returns to the caller of
the caller of LIB$ESTABLISH. Once this happens, you must call
LIB$ESTABLISH again if the same (or a new) condition handler is to be
associated with the caller of LIB$ESTABLISH. On VAX systems, some
languages provide access to condition handling as part of the language.
You can use the ON ERROR GOTO statement in BASIC and the ON statement
in PL/I to define condition handlers. If you are using a language that
does provide access to condition handling, use its language mechanism
rather than LIB$ESTABLISH. Each procedure can declare a condition
handler. When the routine signals an exception, the OpenVMS
Condition Handling facility calls the condition handler associated with
the routine. See Section 9.8 for more information about exception
vectors. Figure 9-5 shows a sample stack scan for a condition
handler. The following HP Fortran program segment establishes the
condition handler ERRLOG. Because the condition handler is used as an
actual argument, it must be declared in an EXTERNAL statement.
INTEGER*4 OLD_HANDLER
EXTERNAL ERRLOG
.
.
.
OLD_HANDLER = LIB$ESTABLISH (ERRLOG)
|
LIB$ESTABLISH returns the address of the previous handler as its
function value. If only part of a program unit requires a special
condition handler, you can reestablish the original handler by invoking
LIB$ESTABLISH and specifying the saved handler address as follows:
CALL LIB$ESTABLISH (OLD_HANDLER)
|
The run-time library provides several condition handlers and
routines that a condition handler can call. These routines take care of
several common exception conditions. Section 9.14 describes these
routines. On Alpha and I64 systems, LIB$ESTABLISH and LIB$REVERT
are not supported, though a high-level language may support them for
compatibility. (Table 9-5 lists other run-time library routines
supported and not supported on Alpha systems.)
- On VAX systems, remove an established condition-handler routine
On VAX systems using LIB$REVERT, you can remove a condition handler
from a routine's stack frame by setting the frame's handler address to
0. If your high-level language provides condition-handling statements,
you should use them rather than LIB$REVERT.
- On VAX systems, enable or disable the detection of arithmetic
hardware exceptions
On VAX systems, using run-time library
routines, you can enable or disable the signaling of floating point
underflow, integer overflow, and decimal overflow, which are detected
by the VAX hardware.
- On I64 systems, allows access to the Floating Point Status
Register, which contains dynamic control and status information for
floating-point operations.
On I64 systems, the services
SYS$IEEE_SET_FP_CONTROL, SYS$IEEE_SET_ROUNDING_MODE, and
SYS$IEEE_SET_PRECISION_MODE provide the supported mechanisms to access
and modify the Floating Point Status Register, and to modify the
floating point rounding and precision modes respectively. Volume 1 of
the Intel® Itanium® Architecture Software Developer's
Manual contains a thorough description of the Floating Point
Status Register.
- Signal a condition
When the hardware detects an exception, such as an integer
overflow, a signal is raised at that instruction. A routine may also
raise a signal by calling LIB$SIGNAL or LIB$STOP. Signals raised by
LIB$SIGNAL allow the condition handler either to terminate or to resume
the normal flow of the routine. Signals raised by LIB$STOP require
termination of the operation that raises the condition. The condition
handler will not be allowed to continue from the point of call to
LIB$STOP.
- Display an informational message
The system establishes default condition handlers before it calls
the main program. Because these default condition handlers provide
access to the system's standard error messages, the standard method for
displaying a message is by signaling the severity of the condition:
informational, warning, or error. See Section 9.5 for the definition
of the severity field of a condition vector. The system default
condition handlers resume execution of the instruction after displaying
the messages associated with the signal. If the condition value
indicates a severe condition, then the image exits after the message is
displayed.
- Display a stack traceback on errors
The default operations of the LINK and RUN commands provide a
system-supplied handler (the traceback handler) to print a symbolic
stack traceback. The traceback shows the state of the routine stack at
the point where the condition occurred. The traceback information is
displayed along with the messages associated with the signaled
condition.
- Compile customer-defined messages
The Message utility allows you to define your own exception
conditions and the associated messages. Message source files contain
the condition values and their associated messages. See Section 9.11.3
for a complete description of how to define your own messages.
- Unwind the stack
A condition handler can cause a signal to be dismissed and the
stack to be unwound to the establisher or caller of the establisher of
the condition handler when it returns control to the OpenVMS Condition
Handling facility (CHF). During the unwinding operation, the CHF scans
the stack. If a condition handler is associated with a frame, the
system calls that handler before removing the frame. Calling the
condition handlers during the unwind allows a routine to perform
cleanup operations specific to a particular application, such as
recovering from noncontinuable errors or deallocating resources that
were allocated by the routine (such as virtual memory, event flags, and
so forth). See Section 9.12.3 for a description of the SYS$UNWIND system
service.
- Log error messages to a file
The Put Message (SYS$PUTMSG) system service permits any
user-written handler to include a message in a listing file. Such
message logging can be separate from the default messages the user
receives. See Section 9.11 for a detailed description of the
SYS$PUTMSG system service.
- On Alpha or I64 systems, perform a nonlocal GOTO unwind.
A
GOTO unwind operation is a transfer of control that leaves one
procedure invocation and continues execution in a prior (currently
active) procedure. This unified GOTO operation gives unterminated
procedure invocations the opportunity to clean up in an orderly way.
|