[Home] [Prev] [Next] [Index]

C.3 Interrupt Support

C.3 Interrupt Support

1
[This clause specifies the language-defined model for hardware interrupts in addition to mechanisms for handling interrupts.]

Dynamic Semantics

2
[An interrupt represents a class of events that are detected by the hardware or the system software.] Interrupts are said to occur.  An occurrence of an interrupt is separable into generation and delivery. Generation of an interrupt is the event in the underlying hardware or system that makes the interrupt available to the program. Delivery is the action that invokes part of the program as response to the interrupt occurrence. Between generation and delivery, the interrupt occurrence [(or interrupt)] is pending. Some or all interrupts may be blocked.  When an interrupt is blocked, all occurrences of that interrupt are prevented from being delivered. Certain interrupts are reserved.  The set of reserved interrupts is implementation defined.  A reserved interrupt is either an interrupt for which user-defined handlers are not supported, or one which already has an attached handler by some other implementation-defined means. Program units can be connected to non-reserved interrupts.  While connected, the program unit is said to be attached to that interrupt. The execution of that program unit, the interrupt handler, is invoked upon delivery of the interrupt occurrence.

2.a
Implementation defined:  Implementation-defined aspects of interrupts.

2.b
To be honest: As an obsolescent feature, interrupts may be attached to task entries by an address clause. See J.7.1.

3
While a handler is attached to an interrupt, it is called once for each delivered occurrence of that interrupt.  While the handler executes, the corresponding interrupt is blocked.

4
While an interrupt is blocked, all occurrences of that interrupt are prevented from being delivered.  Whether such occurrences remain pending or are lost is implementation defined.

5
Each interrupt has a default treatment which determines the system's response to an occurrence of that interrupt when no user-defined handler is attached.  The set of possible default treatments is implementation defined, as is the method (if one exists) for configuring the default treatments for interrupts.

6
An interrupt is delivered to the handler (or default treatment) that is in effect for that interrupt at the time of delivery.

7
An exception propagated from a handler that is invoked by an interrupt has no effect.

8
[If the Ceiling_Locking policy (see D.3) is in effect, the interrupt handler executes with the active priority that is the ceiling priority of the corresponding protected object.]

Implementation Requirements

9
The implementation shall provide a mechanism to determine the minimum stack space that is needed for each interrupt handler and to reserve that space for the execution of the handler. [This space should accommodate nested invocations of the handler where the system permits this.]

10
If the hardware or the underlying system holds pending interrupt occurrences, the implementation shall provide for later delivery of these occurrences to the program.

11
If the Ceiling_Locking policy is not in effect, the implementation shall provide means for the application to specify whether interrupts are to be blocked during protected actions.

Documentation Requirements

12
The implementation shall document the following items:

12.a
Discussion:  This information may be different for different forms of interrupt handlers.

13 1.
For each interrupt, which interrupts are blocked from delivery when a handler attached to that interrupt executes (either as a result of an interrupt delivery or of an ordinary call on a procedure of the corresponding protected object).

14 2.
Any interrupts that cannot be blocked, and the effect of attaching handlers to such interrupts, if this is permitted.

15 3.
Which run-time stack an interrupt handler uses when it executes as a result of an interrupt delivery; if this is configurable, what is the mechanism to do so; how to specify how much space to reserve on that stack.

16 4.
Any implementation- or hardware-specific activity that happens before a user-defined interrupt handler gets control (e.g., reading device registers, acknowledging devices).

17 5.
Any timing or other limitations imposed on the execution of interrupt handlers.

18 6.
The state (blocked/unblocked) of the non-reserved interrupts when the program starts; if some interrupts are unblocked, what is the mechanism a program can use to protect itself before it can attach the corresponding handlers.

19 7.
Whether the interrupted task is allowed to resume execution before the interrupt handler returns.

20 8.
The treatment of interrupt occurrences that are generated while the interrupt is blocked; i.e., whether one or more occurrences are held for later delivery, or all are lost.

21 9.
Whether predefined or implementation-defined exceptions are raised as a result of the occurrence of any interrupt, and the mapping between the machine interrupts (or traps) and the predefined exceptions.

22 10.
On a multi-processor, the rules governing the delivery of an interrupt to a particular processor.

Implementation Permissions

23
If the underlying system or hardware does not allow interrupts to be blocked, then no blocking is required [as part of the execution of subprograms of a protected object whose one of its subprograms is an interrupt handler].

24
In a multi-processor with more than one interrupt subsystem, it is implementation defined whether (and how) interrupt sources from separate subsystems share the same Interrupt_ID type (see C.3.2).

24.a
Discussion:  This issue is tightly related to the issue of scheduling on a multi-processor.  In a sense, if a particular interrupt source is not available to all processors, the system is not truly homogeneous.

24.b
One way to approach this problem is to assign sub-ranges within Interrupt_ID to each interrupt subsystem, such that "similar" interrupt sources (e.g. a timer) in different subsystems get a distinct id.

In particular, the meaning of a blocked or pending interrupt may then be applicable to one processor only.

25
Implementations are allowed to impose timing or other limitations on the execution of interrupt handlers.

25.a
Reason: These limitations are often necessary to ensure proper behavior of the implementation.

26
Other forms of handlers are allowed to be supported, in which case, the rules of this subclause should be adhered to.

27
The active priority of the execution of an interrupt handler is allowed to vary from one occurrence of the same interrupt to another.

Implementation Advice

28
If the Ceiling_Locking policy is not in effect, the implementation should provide means for the application to specify which interrupts are to be blocked during protected actions, if the underlying system allows for a finer-grain control of interrupt blocking.

NOTES

29 1
The default treatment for an interrupt can be to keep the interrupt pending or to deliver it to an implementation-defined handler.  Examples of actions that an implementation-defined handler is allowed to perform include aborting the partition, ignoring (i.e., discarding occurrences of) the interrupt, or queuing one or more occurrences of the interrupt for possible later delivery when a user-defined handler is attached to that interrupt.

30 2
It is a bounded error to call Task_Identification.Current_Task (see C.7.1) from an interrupt handler.

31 3
The rule that an exception propagated from an interrupt handler has no effect is modeled after the rule about exceptions propagated out of task bodies.

C.3.1 Protected Procedure Handlers

Syntax

1
The form of a pragma Interrupt_Handler is as follows:

2
pragma Interrupt_Handler(handler_name);

3
The form of a pragma Attach_Handler is as follows:

4
pragma Attach_Handler(handler_name, expression);

Name Resolution Rules

5
For the Interrupt_Handler and Attach_Handler pragmas, the handler_name shall resolve to denote a protected procedure with a parameterless profile.

6
For the Attach_Handler pragma, the expected type for the expression is Interrupts.Interrupt_ID (see C.3.2).

Legality Rules

7
The Attach_Handler pragma is only allowed immediately within the protected_definition where the corresponding subprogram is declared. The corresponding protected_type_declaration or single_protected_declaration shall be a library level declaration.

7.a
Discussion:  In the case of a protected_type_declaration, an object_declaration of an object of that type need not be at library level.

8
The Interrupt_Handler pragma is only allowed immediately within a protected_definition. The corresponding protected_type_declaration shall be a library level declaration. In addition, any object_declaration of such a type shall be a library level declaration.

Dynamic Semantics

9
If the pragma Interrupt_Handler appears in a protected_definition, then the corresponding procedure can be attached dynamically, as a handler, to interrupts (see C.3.2). [Such procedures are allowed to be attached to multiple interrupts.]

10
The expression in the Attach_Handler pragma [as evaluated at object creation time] specifies an interrupt.  As part of the initialization of that object, if the Attach_Handler pragma is specified, the handler procedure is attached to the specified interrupt. A check is made that the corresponding interrupt is not reserved. Program_Error is raised if the check fails, and the existing treatment for the interrupt is not affected.

11
If the Ceiling_Locking policy (see D.3) is in effect then upon the initialization of a protected object that either an Attach_Handler or Interrupt_Handler pragma applies to one of its procedures, a check is made that the ceiling priority defined in the protected_definition is in the range of System.Interrupt_Priority. If the check fails, Program_Error is raised.

12
When a protected object is finalized, for any of its procedures that are attached to interrupts, the handler is detached.  If the handler was attached by a procedure in the Interrupts package or if no user handler was previously attached to the interrupt, the default treatment is restored.  Otherwise, [that is, if an Attach_Handler pragma was used, ] the previous handler is restored.

12.a
Discussion:  Since only library-level protected procedures can be attached as handlers using the Interrupts package, the finalization discussed above occurs only as part of the finalization of all library-level packages in a partition.

13
When a handler is attached to an interrupt, the interrupt is blocked [(subject to the Implementation Permission in C.3)] during the execution of every protected action on the protected object containing the handler.

Erroneous Execution

14
If the Ceiling_Locking policy (see D.3) is in effect and an interrupt is delivered to a handler, and the interrupt hardware priority is higher than the ceiling priority of the corresponding protected object, the execution of the program is erroneous.

Metrics

15
The following metric shall be documented by the implementation:

16 1.
The worst case overhead for an interrupt handler that is a parameterless protected procedure, in clock cycles.  This is the execution time not directly attributable to the handler procedure or the interrupted execution. It is estimated as C - (A+B), where A is how long it takes to complete a given sequence of instructions without any interrupt, B is how long it takes to complete a normal call to a given protected procedure, and C is how long it takes to complete the same sequence of instructions when it is interrupted by one execution of the same procedure called via an interrupt.

16.a
Implementation Note: The instruction sequence and interrupt handler used to measure interrupt handling overhead should be chosen so as to maximize the execution time cost due to cache misses.  For example, if the processor has cache memory and the activity of an interrupt handler could invalidate the contents of cache memory, the handler should be written such that it invalidates all of the cache memory.

Implementation Permissions

17
When the pragmas Attach_Handler or Interrupt_Handler apply to a protected procedure, the implementation is allowed to impose implementation-defined restrictions on the corresponding protected_type_declaration and protected_body.

17.a
Ramification: The restrictions may be on the constructs that are allowed within them, and on ordinary calls (i.e. not via interrupts) on protected operations in these protected objects.

18
An implementation may use a different mechanism for invoking a protected procedure in response to a hardware interrupt than is used for a call to that protected procedure from a task.

18.a
Discussion:  This is despite the fact that the priority of an interrupt handler (see D.1) is modeled after a hardware task calling the handler.

19
Notwithstanding what this subclause says elsewhere, the Attach_Handler and Interrupt_Handler pragmas are allowed to be used for other, implementation defined, forms of interrupt handlers.

19.a
Ramification: For example, if an implementation wishes to allow interrupt handlers to have parameters, it is allowed to do so via these pragmas; it need not invent implementation-defined pragmas for the purpose.

Implementation Advice

20
Whenever possible, the implementation should allow interrupt handlers to be called directly by the hardware.

21
Whenever practical, the implementation should detect violations of any implementation-defined restrictions before run time.

NOTES

22 4
The Attach_Handler pragma can provide static attachment of handlers to interrupts if the implementation supports preelaboration of protected objects.  (See C.4.)

23 5
The ceiling priority of a protected object that one of its procedures is attached to an interrupt should be at least as high as the highest processor priority at which that interrupt will ever be delivered.

24 6
Protected procedures can also be attached dynamically to interrupts via operations declared in the predefined package Interrupts.

25 7
An example of a possible implementation-defined restriction is disallowing the use of the standard storage pools within the body of a protected procedure that is an interrupt handler.

C.3.2 The Package Interrupts

Static Semantics

1
The following language-defined packages exist:

2
with System;
package Ada.Interrupts is

   type Interrupt_ID is implementation-defined;

   type Parameterless_Handler is
      access protected procedure;

3

4
   function Is_Reserved (Interrupt : Interrupt_ID)
      return Boolean;

5
   function Is_Attached (Interrupt : Interrupt_ID)
      return Boolean;

6
   function Current_Handler (Interrupt : Interrupt_ID)
      return Parameterless_Handler;

7
   procedure Attach_Handler
      (New_Handler : in Parameterless_Handler;
       Interrupt   : in Interrupt_ID);

8
   procedure Exchange_Handler
      (Old_Handler : out Parameterless_Handler;
       New_Handler : in Parameterless_Handler;
       Interrupt   : in Interrupt_ID);

9
   procedure Detach_Handler
      (Interrupt : in Interrupt_ID);

10
   function Reference(Interrupt : Interrupt_ID)
      return System.Address;

11
private
   ... -- not specified by the language
end Ada.Interrupts;

12
package Ada.Interrupts.Names is
   implementation-defined : constant Interrupt_ID :=
     implementation-defined;
      . . .
   implementation-defined : constant Interrupt_ID :=
     implementation-defined;
end Ada.Interrupts.Names;

Dynamic Semantics

13
The Interrupt_ID type is an implementation-defined discrete type used to identify interrupts.

14
The Is_Reserved function returns True if and only if the specified interrupt is reserved.

15
The Is_Attached function returns True if and only if a user-specified interrupt handler is attached to the interrupt.

16
The Current_Handler function returns a value that represents the attached handler of the interrupt.  If no user-defined handler is attached to the interrupt, Current_Handler returns a value that designates the default treatment; calling Attach_Handler or Exchange_Handler with this value restores the default treatment.

17
The Attach_Handler procedure attaches the specified handler to the interrupt, overriding any existing treatment (including a user handler) in effect for that interrupt. If New_Handler is null, the default treatment is restored. If New_Handler designates a protected procedure to which the pragma Interrupt_Handler does not apply, Program_Error is raised.  In this case, the operation does not modify the existing interrupt treatment.

18
The Exchange_Handler procedure operates in the same manner as Attach_Handler with the addition that the value returned in Old_Handler designates the previous treatment for the specified interrupt.

18.a
Ramification: Calling Attach_Handler or Exchange_Handler with this value for New_Handler restores the previous handler.

19
The Detach_Handler procedure restores the default treatment for the specified interrupt.

20
For all operations defined in this package that take a parameter of type Interrupt_ID, with the exception of Is_Reserved and Reference, a check is made that the specified interrupt is not reserved. Program_Error is raised if this check fails.

21
If, by using the Attach_Handler, Detach_Handler, or Exchange_Handler procedures, an attempt is made to detach a handler that was attached statically (using the pragma Attach_Handler), the handler is not detached and Program_Error is raised.

22
The Reference function returns a value of type System.Address that can be used to attach a task entry, via an address clause (see J.7.1) to the interrupt specified by Interrupt.  This function raises Program_Error if attaching task entries to interrupts (or to this particular interrupt) is not supported.

Implementation Requirements

23
At no time during attachment or exchange of handlers shall the current handler of the corresponding interrupt be undefined.

Documentation Requirements

24
If the Ceiling_Locking policy (see D.3) is in effect the implementation shall document the default ceiling priority assigned to a protected object that contains either the Attach_Handler or Interrupt_Handler pragmas, but not the Interrupt_Priority pragma. [This default need not be the same for all interrupts.]

Implementation Advice

25
If implementation-defined forms of interrupt handler procedures are supported, such as protected procedures with parameters, then for each such form of a handler, a type analogous to Parameterless_Handler should be specified in a child package of Interrupts, with the same operations as in the predefined package Interrupts.

NOTES

26 8
The package Interrupts.Names contains implementation-defined names (and constant values) for the interrupts that are supported by the implementation.

Examples

27
Example of interrupt handlers:

28
Device_Priority : constant
  array (1..5) of System.Interrupt_Priority := ( ... );
protected type Device_Interface
  (Int_ID : Ada.Interrupts.Interrupt_ID) is
  procedure Handler;
  pragma Attach_Handler(Handler, Int_ID);
  ...
  pragma Interrupt_Priority(Device_Priority(Int_ID));
end Device_Interface;
  ...
Device_1_Driver : Device_Interface(1);
  ...
Device_5_Driver : Device_Interface(5);
  ...



[Home] [Prev] [Next] [Index]

documentation@rational.com
Copyright © 1993-1998, Rational Software Corporation.   All rights reserved.