TOC PREV NEXT INDEX DOC LIST MASTER INDEX



Interrupt Handlers

This chapter provides an overview of handling UNIX interrupts in Ada and describes how the Ada runtime system processes interrupts received by an Ada program. It also provides guidelines for writing Ada interrupt-entry tasks, Ada procedural signal handlers, and non-Ada signal handlers to handle the interrupts.

Topics covered in this chapter include:

This chapter applies to all native UNIX based products and to Apex Embedded for LynxOS. Other Embedded products provide more direct access to hardware interrupts. See "Interrupts" in the Rational Apex Embedded Programming Guide for Rational Exec or the Rational Apex Embedded Programming Guide for Tornado.


Overview of UNIX Interrupt (Signal) Handling

This overview provides background for the following explanation of how the Rational Ada runtime system processes interrupts in UNIX. You can find platform-specific and more detailed information in the platform vendor's documentation.

To allow processes to communicate asynchronously, an operating system must provide a method for the processes to notify each other when a significant event occurs. Interrupts provide this functionality. In UNIX, interrupts are called signals.

Signals can be generated deliberately by a program or they can arrive unexpectedly. For example:

When a program receives a signal:

To be able to catch and respond to a signal, the program must install a signal handler, which is software that defines the action to take place when a specified signal occurs. UNIX allows a program to install no more than one signal handler for each signal.

Installing a signal handler notifies UNIX that, whenever the program receives a specific signal, the signal handler must be called instead of using default signal handling. The arrival of a signal causes UNIX to switch context to signal context and then invoke the signal handler, usually at an elevated priority.

An Ada program can handle UNIX signals as described in the next section.


Apex Ada Signal Handling

You can define signal handling for your Ada program by doing one of the following for each signal that you need to process:

Note: You can use both of the above methods for a single signal only if the Posix_Compliant argument on pragma Main is False.

When you link your Ada program in Apex, the Rational Ada runtime system is automatically linked with it. When the program executes, the runtime system installs signal handlers for all UNIX signals that either the runtime system or your program uses. All other signals are handled by the default UNIX signal handlers. See Restrictions on UNIX Signals in the Ada Compiler Reference.

The signal handlers installed by the runtime system perform various operations required to process signals from the Ada language. This intervention must happen even for program-specified signal handling because:

When a signal occurs while your program is executing, the signal handler installed by the runtime system is invoked by UNIX. The signal handler, in order:

1 . Performs various setup and initialization tasks.

2 . Calls a signal-handling procedure when one exists either because the runtime system includes one to handle signals that it uses or because your program includes one. This procedure executes in signal context.

3 . Queues an interrupt entry at interrupt priority if your program declares an interrupt-entry task.

4 . Dismisses the signal.

The actual rendezvous occurs at the next context switch for nonpreemptive scheduling or immediately for preemptive scheduling. This guarantees that an Ada interrupt-entry task does not execute until the signal is dismissed, thereby ensuring that no Ada task executes in UNIX signal context.

Note: Steps 2 and 3 can both occur only when the Posix_Compliant argument on pragma Main is False; otherwise, the Program_Error exception is raised.


Interrupt-Entry Tasks

The Rational Ada compiler allows an Ada program to handle UNIX signals with interrupt entries as described in Ada83 LRM 13.5.1, Ada95 LRM J.7.1.

Declaring an Interrupt-Entry Task

An interrupt entry is a simple, parameterless task entry to which an address clause has been applied. Your program can use interrupt entries as shown in this code fragment:

The address clause must give the UNIX signal number for the signal to be handled by the interrupt entry; this binds the signal to the interrupt entry. The address clause can be a nonstatic expression.

In addition to the standard Apex UNIX restrictions, an interrupt-entry task must:

Installing the Interrupt Entry

The interrupt entry is said to be installed when its task specification is elaborated successfully. During elaboration of the task, the following events will cause the installation to fail:

Note: If an interrupt entry fails to install, any occurrences of the specified signal will be processed as if the interrupt-entry task never existed.

Invoking the Interrupt Entry

An installed interrupt entry can be invoked in two ways:

Interrupt-Entry Signal Handling

After an interrupt entry is installed for a specific signal, even if the task is not yet activated, the runtime system handles any occurrences of the signal as it is delivered to the program as described in Apex Ada Signal Handling.

In more detail, the runtime system queues the interrupt entry at interrupt priority, which is defined as being higher than System.Priority'Last, as specified in Ada83 LRM 13.5.1, Ada95 LRM J.7.1.

Entry calls are queued in the order of arrival of the corresponding signals (Ada83 LRM 9.5(15), Ada95 LRM 9.5.3), and the Count attribute for an interrupt entry can be used to determine the number of pending signals. Signals are not lost unless the heap becomes full, preventing the runtime system from allocating entry queue elements.

Once an interrupt entry is queued, the task is scheduled according to normal Ada tasking rules; that is, the task's priority is compared with other tasks eligible for execution to determine which task runs next.

When the task accepts an interrupt-entry call, it is elevated to interrupt priority for the duration of the rendezvous.

Note: Upon termination of a task containing interrupt entries, any queued calls for its interrupt entries are discarded and no further interrupt-entry calls are queued.

Advantages and Disadvantages of Interrupt Entries

Interrupt entries provide signal handlers that are more platform-independent than signal handlers written in other languages. Each platform vendor has its own mechanism for generating and catching signals. With the interrupt entries defined by the LRM, a software designer can write signal handlers in Ada at a high level of abstraction, hiding most of the architectural and operating-system detail.

The disadvantage is that, because of the controls and limits implicit in rendezvous, interrupt entries provide a potentially delayed response to signals. To provide more immediate response, you can:


Ada Procedural Signal Handlers

You can write Ada procedures to handle UNIX signals. This is a Rational implementation-specific feature.

Declaring a Procedural Signal Handler

A procedural signal handler is an Ada procedure that is assigned to execute when a UNIX signal occurs. Pragma Signal_Handler, described in the Ada Compiler Reference, identifies which signal(s) you want to handle with which Ada procedure.

For example, for a single procedure that will handle two different UNIX signals:

The procedure must be parameterless

The procedure can perform dynamic storage allocation on the stack, if needed. In addition to the standard Apex UNIX restrictions, the procedure must:

Note: Failure to observe these restrictions can result in a program that operates unpredictably or not at all.

Installing the Procedural Signal Handler

The procedural signal handler is said to be installed when specification is elaborated successfully. During elaboration of the procedure, the following events will cause the installation to fail:

Note: If a signal handler fails to install, any occurrences of the specified signal will be processed as if the signal handler procedure never existed.

After the procedure is installed, it remains in effect until your program terminates.

Invoking the Procedural Signal Handler

An installed procedural handler can be invoked in two ways:

Procedural Signal Handling

After the procedural handler is installed, the runtime system handles any occurrences of the signal as it is delivered to the program as described in Apex Ada Signal Handling.

In more detail, the runtime system invokes the procedure in UNIX signal context on a separate signal stack.

All asynchronous signals are blocked during the execution of the handler. Synchronized access to shared variables in the main program, however, is your program's responsibility.


Non-Ada Signal Handlers

Mixed-language programs, especially those using Ada tasking constructs, must comply with the following restrictions if they install a non-Ada signal handler:


Rational Software Corporation 
http://www.rational.com
support@rational.com
techpubs@rational.com
Copyright © 1993-2002, Rational Software Corporation. All rights reserved.
TOC PREV NEXT INDEX DOC LIST MASTER INDEX TECHNOTES APEX TIPS