OSDN Git Service

2008-05-27 Thomas Quinot <quinot@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / s-intman-vxworks.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                 GNAT 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-2008, 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,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, 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 --  Make a careful study of all signals available under the OS, to see which
37 --  need to be reserved, kept always unmasked, or kept always unmasked. Be on
38 --  the lookout for special signals that may be used by the thread library.
39
40 package body System.Interrupt_Management is
41
42    use System.OS_Interface;
43    use type Interfaces.C.int;
44
45    type Signal_List is array (Signal_ID range <>) of Signal_ID;
46    Exception_Signals : constant Signal_List (1 .. 4) :=
47                          (SIGFPE, SIGILL, SIGSEGV, SIGBUS);
48
49    Exception_Action : aliased struct_sigaction;
50    --  Keep this variable global so that it is initialized only once
51
52    procedure Notify_Exception
53      (signo      : Signal;
54       siginfo    : System.Address;
55       sigcontext : System.Address);
56    pragma Import (C, Notify_Exception, "__gnat_error_handler");
57    --  Map signal to Ada exception and raise it.  Different versions
58    --  of VxWorks need different mappings.
59
60    -----------------------
61    -- Local Subprograms --
62    -----------------------
63
64    function State (Int : Interrupt_ID) return Character;
65    pragma Import (C, State, "__gnat_get_interrupt_state");
66    --  Get interrupt state. Defined in init.c The input argument is the
67    --  interrupt number, and the result is one of the following:
68
69    Runtime : constant Character := 'r';
70    Default : constant Character := 's';
71    --    'n'   this interrupt not set by any Interrupt_State pragma
72    --    'u'   Interrupt_State pragma set state to User
73    --    'r'   Interrupt_State pragma set state to Runtime
74    --    's'   Interrupt_State pragma set state to System (use "default"
75    --           system handler)
76
77    ---------------------------
78    -- Initialize_Interrupts --
79    ---------------------------
80
81    --  Since there is no signal inheritance between VxWorks tasks, we need
82    --  to initialize signal handling in each task.
83
84    procedure Initialize_Interrupts is
85       Result  : int;
86       old_act : aliased struct_sigaction;
87    begin
88       for J in Exception_Signals'Range loop
89          Result :=
90            sigaction
91              (Signal (Exception_Signals (J)), Exception_Action'Access,
92               old_act'Unchecked_Access);
93          pragma Assert (Result = 0);
94       end loop;
95    end Initialize_Interrupts;
96
97    ----------------
98    -- Initialize --
99    ----------------
100
101    Initialized : Boolean := False;
102    --  Set to True once Initialize is called, further calls have no effect
103
104    procedure Initialize is
105       mask   : aliased sigset_t;
106       Result : int;
107
108    begin
109       if Initialized then
110          return;
111       end if;
112
113       Initialized := True;
114
115       --  Change this if you want to use another signal for task abort.
116       --  SIGTERM might be a good one.
117
118       Abort_Task_Interrupt := SIGABRT;
119
120       Exception_Action.sa_handler := Notify_Exception'Address;
121       Exception_Action.sa_flags := SA_ONSTACK + SA_SIGINFO;
122       Result := sigemptyset (mask'Access);
123       pragma Assert (Result = 0);
124
125       for J in Exception_Signals'Range loop
126          Result := sigaddset (mask'Access, Signal (Exception_Signals (J)));
127          pragma Assert (Result = 0);
128       end loop;
129
130       Exception_Action.sa_mask := mask;
131
132       --  Initialize hardware interrupt handling
133
134       pragma Assert (Reserve = (Interrupt_ID'Range => False));
135
136       --  Check all interrupts for state that requires keeping them reserved
137
138       for J in Interrupt_ID'Range loop
139          if State (J) = Default or else State (J) = Runtime then
140             Reserve (J) := True;
141          end if;
142       end loop;
143
144       --  Add exception signals to the set of unmasked signals
145
146       for J in Exception_Signals'Range loop
147          Keep_Unmasked (Exception_Signals (J)) := True;
148       end loop;
149
150       --  The abort signal must also be unmasked
151
152       Keep_Unmasked (Abort_Task_Interrupt) := True;
153    end Initialize;
154
155 end System.Interrupt_Management;