next up previous contents index
Next: GNAT Implementation Up: Interrupts Previous: Interrupts   Contents   Index

Subsections


Ada Model of Interrupts

The AARM defines the following model of an interrupt [BW98, section 11.2] [AAR95, section C.3(1)]:


Interrupt-Handling Protected Procedures

Ada provides two styles of interrupt-handler installation and removal: nested and non-nested. In the nested style, an interrupt handler in a given protected object is implicitly installed when the protected object comes into existence, and the treatment that had been in effect beforehand is implicitly restored when the protected object ceases to exist. In the non-nested style, interrupt handlers are installed explicitly by procedure calls, and handlers that are replaced are not restored except by explicit request [Coh96, section 19.6.1].

A handler to be installed in the nested style is identified by the following pragma appearing in a protected declaration:

    pragma Attach_Handler (Handler, Interrupt);

Handler is the name of a parameterless protected procedure in that protected declaration; Interrupt is an expression of type Interrupt_ID. The protected declaration must be library-level (it must not be nested in a subprogram body, task body, or block statement). However, if the protected declaration declares a protected type rather than a single protected object, individual objects of the type may be declared in these places. Dynamic allocation (by means of a new expression) gives greater flexibility: Allocating a protected object with an interrupt handler installs the handler associated with that object, and deallocating the protected object restores the handler previously in effect. The Interrupt_ID expression need not be static; in particular, its value may depend on a discriminant of the protected type [Coh96, section 19.6.1]. For example:


  package Nested_Handler_Example is

    protected type Device_Interface
      (Int_ID : Ada.Interrupts.Interrupt_ID) is

      procedure Handler;
      pragma Attach_Handler(Handler, Int_ID);

    end Device_Interface;

  end Nested_Handler_Example;

A handler to be installed in the non-nested style is identified by the following pragma appearing in a protected declaration:

    pragma Interrupt_Handler (Handler, Interrupt);

Again, Handler must be the name of a parameterless protected procedure. As with the Attach_Handler pragma, the protected declaration may not be nested in a subprogram body, task body, or block statement. However, this pragma has an additional restriction: if the protected declaration is for a protected type, objects of that type may not be nested in these places either [Coh96, section 19.6.1]. Therefore they must be dynamically created by means of a new expression.


Package Ada.Interrupts

Non-nested installation and removal of interrupt handlers relies on additional facilities of package Ada.Interrupts  [AAR95, section C.3(2)]:

    package Ada.Interrupts is
       type Interrupt_ID is implementation-defined;
       type Parameterless_Handler is access protected procedure;

       function Is_Reserved (Interrupt : Interrupt_ID)
          return Boolean;

       function Is_Attached (Interrupt : Interrupt_ID)
          return Boolean;

       function Current_Handler (Interrupt : Interrupt_ID)
          return Parameterless_Handler;

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

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

       procedure Detach_Handler
          (Interrupt : in Interrupt_ID);

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

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

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 [AAR95, section C.3.2].

with Ada.Task_Identification;
package Ada.Dynamic_Priorities is

   procedure Set_Priority
     (Priority : System.Any_Priority;
      T        : Ada.Task_Identification.Task_Id :=
                   Ada.Task_Identification.Current_Task);

   function Get_Priority
     (T        : Ada.Task_Identification.Task_Id :=
                   Ada.Task_Identification.Current_Task)
     return System.Any_Priority;

end Ada.Dynamic_Priorities;


Priorities

The pragma Interrupt_Priority can be used to specify the ceiling priority of a protected object (Real-Time Systems [AAR95, Annex D]).

    pragma Interrupt_Priority (expression);

Omitting the expression is equivalent to specifying the ceiling priority of the system (Interrupt_Priority'Last). Interrupts of equal or lower priority are blocked while any operation of that protected object is in progress. To avoid priority inversion, any task calling an operation on that protected object has its priority raised to the ceiling priority while the operation is executed, reflecting the urgency of completing the operation so that interrupts will become unblocked. An interrupt handler executes at the priority of its protected object, which may be higher than the priority of the interrupt if the same protected object handles more than one kind of interrupt. In addition, the procedure Set_Priority provided by package Ada.Dynamic_Priorities can be used to dynamically modify this priority.

with Ada.Task_Identification;
package Ada.Dynamic_Priorities is

   procedure Set_Priority
     (Priority : System.Any_Priority;
      T        : Ada.Task_Identification.Task_Id :=
                   Ada.Task_Identification.Current_Task);

   function Get_Priority
     (T        : Ada.Task_Identification.Task_Id :=
                   Ada.Task_Identification.Current_Task)
     return System.Any_Priority;

end Ada.Dynamic_Priorities;


next up previous contents index
Next: GNAT Implementation Up: Interrupts Previous: Interrupts   Contents   Index
(c) Javier Miranda. Canary Islands (Spain), 2002. Version 1.0