------------------------------------------------------------------------------
--                                                                          --
--                 GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                 --
--                                                                          --
--                     S Y S T E M . I N T E R R U P T S                    --
--                                                                          --
--                                  B o d y                                 --
--                                                                          --
--          Copyright (C) 1998-2007, Free Software Foundation, Inc.         --
--                                                                          --
-- GNARL is free software; you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNARL; see file COPYING.  If not, write --
-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
-- Boston, MA 02110-1301, USA.                                              --
--                                                                          --
-- As a special exception,  if other files  instantiate  generics from this --
-- unit, or you link  this unit with other files  to produce an executable, --
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
-- covered  by the  GNU  General  Public  License.  This exception does not --
-- however invalidate  any other reasons why  the executable file  might be --
-- covered by the  GNU Public License.                                      --
--                                                                          --
-- GNARL was developed by the GNARL team at Florida State University.       --
-- Extensive contributions were provided by Ada Core Technologies, Inc.     --
--                                                                          --
------------------------------------------------------------------------------

--  This is the IRIX & NT version of this package

with Ada.Task_Identification;
--  used for Task_Id

with Ada.Exceptions;
--  used for Raise_Exception

with System.Storage_Elements;
--  used for To_Address
--           To_Integer

with System.Task_Primitives.Operations;
--  used for Self
--           Sleep
--           Wakeup
--           Write_Lock
--           Unlock

with System.Tasking.Utilities;
--  used for Make_Independent

with System.Tasking.Rendezvous;
--  used for Call_Simple

with System.Tasking.Initialization;
--  used for Defer_Abort
--           Undefer_Abort

with System.Interrupt_Management;

with System.Parameters;
--  used for Single_Lock

with Interfaces.C;
--  used for int

with Ada.Unchecked_Conversion;

package body System.Interrupts is

   use Parameters;
   use Tasking;
   use Ada.Exceptions;
   use System.OS_Interface;
   use Interfaces.C;

   package STPO renames System.Task_Primitives.Operations;
   package IMNG renames System.Interrupt_Management;

   subtype int is Interfaces.C.int;

   function To_System is new Ada.Unchecked_Conversion
     (Ada.Task_Identification.Task_Id, Task_Id);

   type Handler_Kind is (Unknown, Task_Entry, Protected_Procedure);

   type Handler_Desc is record
      Kind   : Handler_Kind := Unknown;
      T      : Task_Id;
      E      : Task_Entry_Index;
      H      : Parameterless_Handler;
      Static : Boolean := False;
   end record;

   task type Server_Task (Interrupt : Interrupt_ID) is
      pragma Interrupt_Priority (System.Interrupt_Priority'Last);
   end Server_Task;

   type Server_Task_Access is access Server_Task;

   Handlers        : array (Interrupt_ID) of Task_Id;
   Descriptors     : array (Interrupt_ID) of Handler_Desc;
   Interrupt_Count : array (Interrupt_ID) of Integer := (others => 0);

   pragma Volatile_Components (Interrupt_Count);

   procedure Attach_Handler
     (New_Handler : Parameterless_Handler;
      Interrupt   : Interrupt_ID;
      Static      : Boolean;
      Restoration : Boolean);
   --  This internal procedure is needed to finalize protected objects
   --  that contain interrupt handlers.

   procedure Signal_Handler (Sig : Interrupt_ID);
   pragma Convention (C, Signal_Handler);
   --  This procedure is used to handle all the signals

   --  Type and Head, Tail of the list containing Registered Interrupt
   --  Handlers. These definitions are used to register the handlers
   --  specified by the pragma Interrupt_Handler.

   --------------------------
   -- Handler Registration --
   --------------------------

   type Registered_Handler;
   type R_Link is access all Registered_Handler;

   type Registered_Handler is record
      H    : System.Address := System.Null_Address;
      Next : R_Link := null;
   end record;

   Registered_Handlers : R_Link := null;

   function Is_Registered (Handler : Parameterless_Handler) return Boolean;
   --  See if the Handler has been "pragma"ed using Interrupt_Handler.
   --  Always consider a null handler as registered.

   type Handler_Ptr is access procedure (Sig : Interrupt_ID);
   pragma Convention (C, Handler_Ptr);

   function TISR is new Ada.Unchecked_Conversion (Handler_Ptr, isr_address);

   --------------------
   -- Signal_Handler --
   --------------------

   procedure Signal_Handler (Sig : Interrupt_ID) is
      Handler : Task_Id renames Handlers (Sig);

   begin
      if Intr_Attach_Reset and then
        intr_attach (int (Sig), TISR (Signal_Handler'Access)) = FUNC_ERR
      then
         raise Program_Error;
      end if;

      if Handler /= null then
         Interrupt_Count (Sig) := Interrupt_Count (Sig) + 1;
         STPO.Wakeup (Handler, Interrupt_Server_Idle_Sleep);
      end if;
   end Signal_Handler;

   -----------------
   -- Is_Reserved --
   -----------------

   function Is_Reserved (Interrupt : Interrupt_ID) return Boolean is
   begin
      return IMNG.Reserve (IMNG.Interrupt_ID (Interrupt));
   end Is_Reserved;

   -----------------------
   -- Is_Entry_Attached --
   -----------------------

   function Is_Entry_Attached (Interrupt : Interrupt_ID) return Boolean is
   begin
      if Is_Reserved (Interrupt) then
         Raise_Exception (Program_Error'Identity, "Interrupt" &
           Interrupt_ID'Image (Interrupt) & " is reserved");
      end if;

      return Descriptors (Interrupt).T /= Null_Task;
   end Is_Entry_Attached;

   -------------------------
   -- Is_Handler_Attached --
   -------------------------

   function Is_Handler_Attached (Interrupt : Interrupt_ID) return Boolean is
   begin
      if Is_Reserved (Interrupt) then
         Raise_Exception (Program_Error'Identity, "Interrupt" &
           Interrupt_ID'Image (Interrupt) & " is reserved");
      end if;

      return Descriptors (Interrupt).Kind /= Unknown;
   end Is_Handler_Attached;

   ----------------
   -- Is_Ignored --
   ----------------

   function Is_Ignored (Interrupt : Interrupt_ID) return Boolean is
   begin
      raise Program_Error;
      return False;
   end Is_Ignored;

   ------------------
   -- Unblocked_By --
   ------------------

   function Unblocked_By (Interrupt : Interrupt_ID) return Task_Id is
   begin
      raise Program_Error;
      return Null_Task;
   end Unblocked_By;

   ----------------------
   -- Ignore_Interrupt --
   ----------------------

   procedure Ignore_Interrupt (Interrupt : Interrupt_ID) is
   begin
      raise Program_Error;
   end Ignore_Interrupt;

   ------------------------
   -- Unignore_Interrupt --
   ------------------------

   procedure Unignore_Interrupt (Interrupt : Interrupt_ID) is
   begin
      raise Program_Error;
   end Unignore_Interrupt;

   -------------------------------------
   -- Has_Interrupt_Or_Attach_Handler --
   -------------------------------------

   function Has_Interrupt_Or_Attach_Handler
     (Object : access Dynamic_Interrupt_Protection) return Boolean
   is
      pragma Unreferenced (Object);
   begin
      return True;
   end Has_Interrupt_Or_Attach_Handler;

   --------------
   -- Finalize --
   --------------

   procedure Finalize (Object : in out Static_Interrupt_Protection) is
   begin
      --  ??? loop to be executed only when we're not doing library level
      --  finalization, since in this case all interrupt tasks are gone.

      for N in reverse Object.Previous_Handlers'Range loop
         Attach_Handler
           (New_Handler => Object.Previous_Handlers (N).Handler,
            Interrupt   => Object.Previous_Handlers (N).Interrupt,
            Static      => Object.Previous_Handlers (N).Static,
            Restoration => True);
      end loop;

      Tasking.Protected_Objects.Entries.Finalize
        (Tasking.Protected_Objects.Entries.Protection_Entries (Object));
   end Finalize;

   -------------------------------------
   -- Has_Interrupt_Or_Attach_Handler --
   -------------------------------------

   function Has_Interrupt_Or_Attach_Handler
     (Object : access Static_Interrupt_Protection) return Boolean
   is
      pragma Unreferenced (Object);
   begin
      return True;
   end Has_Interrupt_Or_Attach_Handler;

   ----------------------
   -- Install_Handlers --
   ----------------------

   procedure Install_Handlers
     (Object       : access Static_Interrupt_Protection;
      New_Handlers : New_Handler_Array)
   is
   begin
      for N in New_Handlers'Range loop

         --  We need a lock around this ???

         Object.Previous_Handlers (N).Interrupt := New_Handlers (N).Interrupt;
         Object.Previous_Handlers (N).Static    := Descriptors
           (New_Handlers (N).Interrupt).Static;

         --  We call Exchange_Handler and not directly Interrupt_Manager.
         --  Exchange_Handler so we get the Is_Reserved check.

         Exchange_Handler
           (Old_Handler => Object.Previous_Handlers (N).Handler,
            New_Handler => New_Handlers (N).Handler,
            Interrupt   => New_Handlers (N).Interrupt,
            Static      => True);
      end loop;
   end Install_Handlers;

   ---------------------
   -- Current_Handler --
   ---------------------

   function Current_Handler
     (Interrupt : Interrupt_ID) return Parameterless_Handler
   is
   begin
      if Is_Reserved (Interrupt) then
         raise Program_Error;
      end if;

      if Descriptors (Interrupt).Kind = Protected_Procedure then
         return Descriptors (Interrupt).H;
      else
         return null;
      end if;
   end Current_Handler;

   --------------------
   -- Attach_Handler --
   --------------------

   procedure Attach_Handler
     (New_Handler : Parameterless_Handler;
      Interrupt   : Interrupt_ID;
      Static      : Boolean := False) is
   begin
      Attach_Handler (New_Handler, Interrupt, Static, False);
   end Attach_Handler;

   procedure Attach_Handler
     (New_Handler : Parameterless_Handler;
      Interrupt   : Interrupt_ID;
      Static      : Boolean;
      Restoration : Boolean)
   is
      New_Task : Server_Task_Access;

   begin
      if Is_Reserved (Interrupt) then
         raise Program_Error;
      end if;

      if not Restoration and then not Static

         --  Tries to overwrite a static Interrupt Handler with dynamic handle

        and then
          (Descriptors (Interrupt).Static

            --  New handler not specified as an Interrupt Handler by a pragma

             or else not Is_Registered (New_Handler))
      then
         Raise_Exception (Program_Error'Identity,
           "Trying to overwrite a static Interrupt Handler with a " &
           "dynamic Handler");
      end if;

      if Handlers (Interrupt) = null then
         New_Task := new Server_Task (Interrupt);
         Handlers (Interrupt) := To_System (New_Task.all'Identity);
      end if;

      if intr_attach (int (Interrupt),
        TISR (Signal_Handler'Access)) = FUNC_ERR
      then
         raise Program_Error;
      end if;

      if New_Handler = null then

         --  The null handler means we are detaching the handler

         Descriptors (Interrupt) :=
           (Kind => Unknown, T => null, E => 0, H => null, Static => False);

      else
         Descriptors (Interrupt).Kind := Protected_Procedure;
         Descriptors (Interrupt).H := New_Handler;
         Descriptors (Interrupt).Static := Static;
      end if;
   end Attach_Handler;

   ----------------------
   -- Exchange_Handler --
   ----------------------

   procedure Exchange_Handler
     (Old_Handler : out Parameterless_Handler;
      New_Handler : Parameterless_Handler;
      Interrupt   : Interrupt_ID;
      Static      : Boolean := False)
   is
   begin
      if Is_Reserved (Interrupt) then
         raise Program_Error;
      end if;

      if Descriptors (Interrupt).Kind = Task_Entry then

         --  In case we have an Interrupt Entry already installed.
         --  raise a program error. (propagate it to the caller).

         Raise_Exception (Program_Error'Identity,
           "An interrupt is already installed");
      end if;

      Old_Handler := Current_Handler (Interrupt);
      Attach_Handler (New_Handler, Interrupt, Static);
   end Exchange_Handler;

   --------------------
   -- Detach_Handler --
   --------------------

   procedure Detach_Handler
     (Interrupt : Interrupt_ID;
      Static    : Boolean := False)
   is
   begin
      if Is_Reserved (Interrupt) then
         raise Program_Error;
      end if;

      if Descriptors (Interrupt).Kind = Task_Entry then
         Raise_Exception (Program_Error'Identity,
           "Trying to detach an Interrupt Entry");
      end if;

      if not Static and then Descriptors (Interrupt).Static then
         Raise_Exception (Program_Error'Identity,
           "Trying to detach a static Interrupt Handler");
      end if;

      Descriptors (Interrupt) :=
        (Kind => Unknown, T => null, E => 0, H => null, Static => False);

      if intr_attach (int (Interrupt), null) = FUNC_ERR then
         raise Program_Error;
      end if;
   end Detach_Handler;

   ---------------
   -- Reference --
   ---------------

   function Reference (Interrupt : Interrupt_ID) return System.Address is
      Signal : constant System.Address :=
                 System.Storage_Elements.To_Address
                   (System.Storage_Elements.Integer_Address (Interrupt));

   begin
      if Is_Reserved (Interrupt) then

         --  Only usable Interrupts can be used for binding it to an Entry

         raise Program_Error;
      end if;

      return Signal;
   end Reference;

   --------------------------------
   -- Register_Interrupt_Handler --
   --------------------------------

   procedure Register_Interrupt_Handler (Handler_Addr : System.Address) is
   begin
      Registered_Handlers :=
       new Registered_Handler'(H => Handler_Addr, Next => Registered_Handlers);
   end Register_Interrupt_Handler;

   -------------------
   -- Is_Registered --
   -------------------

   --  See if the Handler has been "pragma"ed using Interrupt_Handler.
   --  Always consider a null handler as registered.

   function Is_Registered (Handler : Parameterless_Handler) return Boolean is
      Ptr : R_Link := Registered_Handlers;

      type Fat_Ptr is record
         Object_Addr  : System.Address;
         Handler_Addr : System.Address;
      end record;

      function To_Fat_Ptr is new Ada.Unchecked_Conversion
        (Parameterless_Handler, Fat_Ptr);

      Fat : Fat_Ptr;

   begin
      if Handler = null then
         return True;
      end if;

      Fat := To_Fat_Ptr (Handler);

      while Ptr /= null loop

         if Ptr.H = Fat.Handler_Addr then
            return True;
         end if;

         Ptr := Ptr.Next;
      end loop;

      return False;
   end Is_Registered;

   -----------------------------
   -- Bind_Interrupt_To_Entry --
   -----------------------------

   procedure Bind_Interrupt_To_Entry
     (T       : Task_Id;
      E       : Task_Entry_Index;
      Int_Ref : System.Address)
   is
      Interrupt   : constant Interrupt_ID :=
                      Interrupt_ID (Storage_Elements.To_Integer (Int_Ref));

      New_Task : Server_Task_Access;

   begin
      if Is_Reserved (Interrupt) then
         raise Program_Error;
      end if;

      if Descriptors (Interrupt).Kind /= Unknown then
         Raise_Exception (Program_Error'Identity,
           "A binding for this interrupt is already present");
      end if;

      if Handlers (Interrupt) = null then
         New_Task := new Server_Task (Interrupt);
         Handlers (Interrupt) := To_System (New_Task.all'Identity);
      end if;

      if intr_attach (int (Interrupt),
        TISR (Signal_Handler'Access)) = FUNC_ERR
      then
         raise Program_Error;
      end if;

      Descriptors (Interrupt).Kind := Task_Entry;
      Descriptors (Interrupt).T := T;
      Descriptors (Interrupt).E := E;

      --  Indicate the attachment of Interrupt Entry in ATCB. This is needed so
      --  that when an Interrupt Entry task terminates the binding can be
      --  cleaned up. The call to unbinding must be make by the task before it
      --  terminates.

      T.Interrupt_Entry := True;
   end Bind_Interrupt_To_Entry;

   ------------------------------
   -- Detach_Interrupt_Entries --
   ------------------------------

   procedure Detach_Interrupt_Entries (T : Task_Id) is
   begin
      for J in Interrupt_ID loop
         if not Is_Reserved (J) then
            if Descriptors (J).Kind = Task_Entry
              and then Descriptors (J).T = T
            then
               Descriptors (J).Kind := Unknown;

               if intr_attach (int (J), null) = FUNC_ERR then
                  raise Program_Error;
               end if;
            end if;
         end if;
      end loop;

      --  Indicate in ATCB that no Interrupt Entries are attached

      T.Interrupt_Entry := True;
   end Detach_Interrupt_Entries;

   ---------------------
   -- Block_Interrupt --
   ---------------------

   procedure Block_Interrupt (Interrupt : Interrupt_ID) is
   begin
      raise Program_Error;
   end Block_Interrupt;

   -----------------------
   -- Unblock_Interrupt --
   -----------------------

   procedure Unblock_Interrupt (Interrupt : Interrupt_ID) is
   begin
      raise Program_Error;
   end Unblock_Interrupt;

   ----------------
   -- Is_Blocked --
   ----------------

   function Is_Blocked (Interrupt : Interrupt_ID) return Boolean is
   begin
      raise Program_Error;
      return False;
   end Is_Blocked;

   task body Server_Task is
      Desc    : Handler_Desc renames Descriptors (Interrupt);
      Self_Id : constant Task_Id := STPO.Self;
      Temp    : Parameterless_Handler;

   begin
      Utilities.Make_Independent;

      loop
         while Interrupt_Count (Interrupt) > 0 loop
            Interrupt_Count (Interrupt) := Interrupt_Count (Interrupt) - 1;
            begin
               case Desc.Kind is
                  when Unknown =>
                     null;
                  when Task_Entry =>
                     Rendezvous.Call_Simple (Desc.T, Desc.E, Null_Address);
                  when Protected_Procedure =>
                     Temp := Desc.H;
                     Temp.all;
               end case;
            exception
               when others => null;
            end;
         end loop;

         Initialization.Defer_Abort (Self_Id);

         if Single_Lock then
            STPO.Lock_RTS;
         end if;

         STPO.Write_Lock (Self_Id);
         Self_Id.Common.State := Interrupt_Server_Idle_Sleep;
         STPO.Sleep (Self_Id, Interrupt_Server_Idle_Sleep);
         Self_Id.Common.State := Runnable;
         STPO.Unlock (Self_Id);

         if Single_Lock then
            STPO.Unlock_RTS;
         end if;

         Initialization.Undefer_Abort (Self_Id);

         --  Undefer abort here to allow a window for this task to be aborted
         --  at the time of system shutdown.

      end loop;
   end Server_Task;

end System.Interrupts;
