1------------------------------------------------------------------------------ 2-- -- 3-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS -- 4-- -- 5-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T -- 6-- -- 7-- B o d y -- 8-- -- 9-- Copyright (C) 1992-2004 Free Software Foundation, Inc. -- 10-- -- 11-- GNARL is free software; you can redistribute it and/or modify it under -- 12-- terms of the GNU General Public License as published by the Free Soft- -- 13-- ware Foundation; either version 2, or (at your option) any later ver- -- 14-- sion. GNARL is distributed in the hope that it will be useful, but WITH- -- 15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- 17-- for more details. You should have received a copy of the GNU General -- 18-- Public License distributed with GNARL; see file COPYING. If not, write -- 19-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, -- 20-- MA 02111-1307, USA. -- 21-- -- 22-- As a special exception, if other files instantiate generics from this -- 23-- unit, or you link this unit with other files to produce an executable, -- 24-- this unit does not by itself cause the resulting executable to be -- 25-- covered by the GNU General Public License. This exception does not -- 26-- however invalidate any other reasons why the executable file might be -- 27-- covered by the GNU Public License. -- 28-- -- 29-- GNARL was developed by the GNARL team at Florida State University. -- 30-- Extensive contributions were provided by Ada Core Technologies, Inc. -- 31-- -- 32------------------------------------------------------------------------------ 33 34-- This is the VxWorks version of this package. 35 36-- It is likely to need tailoring to fit each operating system 37-- and machine architecture. 38 39-- PLEASE DO NOT add any dependences on other packages. 40-- This package is designed to work with or without tasking support. 41 42-- See the other warnings in the package specification before making 43-- any modifications to this file. 44 45-- Make a careful study of all signals available under the OS, 46-- to see which need to be reserved, kept always unmasked, 47-- or kept always unmasked. 48-- Be on the lookout for special signals that 49-- may be used by the thread library. 50 51with Interfaces.C; 52 53with System.OS_Interface; 54-- used for various Constants, Signal and types 55 56package body System.Interrupt_Management is 57 58 use System.OS_Interface; 59 use type Interfaces.C.int; 60 61 type Signal_List is array (Signal_ID range <>) of Signal_ID; 62 Exception_Signals : constant Signal_List (1 .. 4) := 63 (SIGFPE, SIGILL, SIGSEGV, SIGBUS); 64 65 -- Keep these variables global so that they are initialized only once 66 -- What are "these variables" ???, I see only one 67 68 Exception_Action : aliased struct_sigaction; 69 70 procedure Map_And_Raise_Exception (signo : Signal); 71 pragma Import (C, Map_And_Raise_Exception, "__gnat_map_signal"); 72 -- Map signal to Ada exception and raise it. Different versions 73 -- of VxWorks need different mappings. 74 75 ----------------------- 76 -- Local Subprograms -- 77 ----------------------- 78 79 procedure Notify_Exception (signo : Signal); 80 -- Identify the Ada exception to be raised using 81 -- the information when the system received a synchronous signal. 82 83 ---------------------- 84 -- Notify_Exception -- 85 ---------------------- 86 87 procedure Notify_Exception (signo : Signal) is 88 Mask : aliased sigset_t; 89 My_Id : t_id; 90 91 Result : int; 92 pragma Unreferenced (Result); 93 94 begin 95 Result := pthread_sigmask (SIG_SETMASK, null, Mask'Unchecked_Access); 96 Result := sigdelset (Mask'Access, signo); 97 Result := pthread_sigmask (SIG_SETMASK, Mask'Unchecked_Access, null); 98 99 -- VxWorks will suspend the task when it gets a hardware 100 -- exception. We take the liberty of resuming the task 101 -- for the application. 102 103 My_Id := taskIdSelf; 104 105 if taskIsSuspended (My_Id) /= 0 then 106 Result := taskResume (My_Id); 107 end if; 108 109 Map_And_Raise_Exception (signo); 110 end Notify_Exception; 111 112 --------------------------- 113 -- Initialize_Interrupts -- 114 --------------------------- 115 116 -- Since there is no signal inheritance between VxWorks tasks, we need 117 -- to initialize signal handling in each task. 118 119 procedure Initialize_Interrupts is 120 Result : int; 121 old_act : aliased struct_sigaction; 122 123 begin 124 for J in Exception_Signals'Range loop 125 Result := 126 sigaction 127 (Signal (Exception_Signals (J)), Exception_Action'Access, 128 old_act'Unchecked_Access); 129 pragma Assert (Result = 0); 130 end loop; 131 end Initialize_Interrupts; 132 133begin 134 declare 135 mask : aliased sigset_t; 136 Result : int; 137 138 function State (Int : Interrupt_ID) return Character; 139 pragma Import (C, State, "__gnat_get_interrupt_state"); 140 -- Get interrupt state. Defined in a-init.c 141 -- The input argument is the interrupt number, 142 -- and the result is one of the following: 143 144 Runtime : constant Character := 'r'; 145 Default : constant Character := 's'; 146 -- 'n' this interrupt not set by any Interrupt_State pragma 147 -- 'u' Interrupt_State pragma set state to User 148 -- 'r' Interrupt_State pragma set state to Runtime 149 -- 's' Interrupt_State pragma set state to System (use "default" 150 -- system handler) 151 152 begin 153 -- Initialize signal handling 154 155 -- Change this if you want to use another signal for task abort. 156 -- SIGTERM might be a good one. 157 158 Abort_Task_Signal := SIGABRT; 159 160 Exception_Action.sa_handler := Notify_Exception'Address; 161 Exception_Action.sa_flags := SA_ONSTACK; 162 Result := sigemptyset (mask'Access); 163 pragma Assert (Result = 0); 164 165 for J in Exception_Signals'Range loop 166 Result := sigaddset (mask'Access, Signal (Exception_Signals (J))); 167 pragma Assert (Result = 0); 168 end loop; 169 170 Exception_Action.sa_mask := mask; 171 172 -- Initialize hardware interrupt handling 173 174 pragma Assert (Reserve = (Interrupt_ID'Range => False)); 175 176 -- Check all interrupts for state that requires keeping them reserved 177 178 for J in Interrupt_ID'Range loop 179 if State (J) = Default or else State (J) = Runtime then 180 Reserve (J) := True; 181 end if; 182 end loop; 183 184 -- Add exception signals to the set of unmasked signals 185 186 for J in Exception_Signals'Range loop 187 Keep_Unmasked (Exception_Signals (J)) := True; 188 end loop; 189 190 -- The abort signal must also be unmasked 191 192 Keep_Unmasked (Abort_Task_Signal) := True; 193 end; 194end System.Interrupt_Management; 195