OSDN Git Service

* rtl.h (mem_attrs): Rename decl to expr; adjust all users.
[pf3gnuchains/gcc-fork.git] / gcc / ada / 5sintman.adb
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 --                             $Revision: 1.21 $                            --
10 --                                                                          --
11 --          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
12 --                                                                          --
13 -- GNARL is free software; you can  redistribute it  and/or modify it under --
14 -- terms of the  GNU General Public License as published  by the Free Soft- --
15 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
16 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
19 -- for  more details.  You should have  received  a copy of the GNU General --
20 -- Public License  distributed with GNARL; see file COPYING.  If not, write --
21 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
22 -- MA 02111-1307, USA.                                                      --
23 --                                                                          --
24 -- As a special exception,  if other files  instantiate  generics from this --
25 -- unit, or you link  this unit with other files  to produce an executable, --
26 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
27 -- covered  by the  GNU  General  Public  License.  This exception does not --
28 -- however invalidate  any other reasons why  the executable file  might be --
29 -- covered by the  GNU Public License.                                      --
30 --                                                                          --
31 -- GNARL was developed by the GNARL team at Florida State University. It is --
32 -- now maintained by Ada Core Technologies Inc. in cooperation with Florida --
33 -- State University (http://www.gnat.com).                                  --
34 --                                                                          --
35 ------------------------------------------------------------------------------
36
37 --  This is a Solaris version of this package.
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 --  Make a careful study of all signals available under the OS,
43 --  to see which need to be reserved, kept always unmasked,
44 --  or kept always unmasked.
45
46 --  Be on the lookout for special signals that
47 --  may be used by the thread library.
48
49 with Interfaces.C;
50 --  used for int
51
52 with System.OS_Interface;
53 --  used for various Constants, Signal and types
54
55 package body System.Interrupt_Management is
56
57    use Interfaces.C;
58    use System.OS_Interface;
59
60    type Interrupt_List is array (Interrupt_ID range <>) of Interrupt_ID;
61
62    Exception_Interrupts : constant Interrupt_List :=
63      (SIGFPE, SIGILL, SIGSEGV, SIGBUS);
64
65    Unreserve_All_Interrupts : Interfaces.C.int;
66    pragma Import
67      (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts");
68
69    ----------------------
70    -- Notify_Exception --
71    ----------------------
72
73    --  This function identifies the Ada exception to be raised using
74    --  the information when the system received a synchronous signal.
75    --  Since this function is machine and OS dependent, different code
76    --  has to be provided for different target.
77
78    procedure Notify_Exception
79      (signo   : Signal;
80       info    : access siginfo_t;
81       context : access ucontext_t);
82
83    procedure Notify_Exception
84      (signo   : Signal;
85       info    : access siginfo_t;
86       context : access ucontext_t) is
87    begin
88       --  Check that treatment of exception propagation here
89       --  is consistent with treatment of the abort signal in
90       --  System.Task_Primitives.Operations.
91
92       case signo is
93          when SIGFPE =>
94             case info.si_code is
95                when  FPE_INTDIV |
96                      FPE_INTOVF |
97                      FPE_FLTDIV |
98                      FPE_FLTOVF |
99                      FPE_FLTUND |
100                      FPE_FLTRES |
101                      FPE_FLTINV |
102                      FPE_FLTSUB =>
103
104                   raise Constraint_Error;
105
106                when others =>
107                   pragma Assert (False);
108                   null;
109             end case;
110
111          when SIGILL | SIGSEGV | SIGBUS  =>
112             raise Storage_Error;
113
114          when others =>
115             pragma Assert (False);
116             null;
117       end case;
118    end Notify_Exception;
119
120    ---------------------------
121    -- Initialize_Interrupts --
122    ---------------------------
123
124    --  Nothing needs to be done on this platform.
125
126    procedure Initialize_Interrupts is
127    begin
128       null;
129    end Initialize_Interrupts;
130
131 ----------------------------
132 -- Package Initialization --
133 ----------------------------
134
135 begin
136    declare
137       act     : aliased struct_sigaction;
138       old_act : aliased struct_sigaction;
139       mask    : aliased sigset_t;
140       Result  : Interfaces.C.int;
141
142    begin
143       --  Need to call pthread_init very early because it is doing signal
144       --  initializations.
145
146       pthread_init;
147
148       --  Change this if you want to use another signal for task abort.
149       --  SIGTERM might be a good one.
150
151       Abort_Task_Interrupt := SIGABRT;
152
153       act.sa_handler := Notify_Exception'Address;
154
155       --  Set sa_flags to SA_NODEFER so that during the handler execution
156       --  we do not change the Signal_Mask to be masked for the Signal.
157       --  This is a temporary fix to the problem that the Signal_Mask is
158       --  not restored after the exception (longjmp) from the handler.
159       --  The right fix should be made in sigsetjmp so that we save
160       --  the Signal_Set and restore it after a longjmp.
161
162       --  In that case, this field should be changed back to 0. ??? (Dong-Ik)
163
164       act.sa_flags := 16;
165
166       Result := sigemptyset (mask'Access);
167       pragma Assert (Result = 0);
168
169       --  ??? For the same reason explained above, we can't mask these
170       --  signals because otherwise we won't be able to catch more than
171       --  one signal.
172
173       act.sa_mask := mask;
174
175       Keep_Unmasked (Abort_Task_Interrupt) := True;
176       Keep_Unmasked (SIGXCPU) := True;
177       Keep_Unmasked (SIGFPE) := True;
178       Result :=
179         sigaction
180         (Signal (SIGFPE), act'Unchecked_Access,
181          old_act'Unchecked_Access);
182       pragma Assert (Result = 0);
183
184       --  By keeping SIGINT unmasked, allow the user to do a Ctrl-C, but in the
185       --  same time, disable the ability of handling this signal
186       --  via Ada.Interrupts.
187       --  The pragma Unreserve_All_Interrupts let the user the ability to
188       --  change this behavior.
189
190       if Unreserve_All_Interrupts = 0 then
191          Keep_Unmasked (SIGINT) := True;
192       end if;
193
194       for J in
195         Exception_Interrupts'First + 1 .. Exception_Interrupts'Last loop
196          Keep_Unmasked (Exception_Interrupts (J)) := True;
197
198          if Unreserve_All_Interrupts = 0 then
199             Result :=
200               sigaction
201               (Signal (Exception_Interrupts (J)), act'Unchecked_Access,
202                old_act'Unchecked_Access);
203             pragma Assert (Result = 0);
204          end if;
205       end loop;
206
207       for J in Unmasked'Range loop
208          Keep_Unmasked (Interrupt_ID (Unmasked (J))) := True;
209       end loop;
210
211       Reserve := Keep_Unmasked or Keep_Masked;
212
213       for J in Reserved'Range loop
214          Reserve (Interrupt_ID (Reserved (J))) := True;
215       end loop;
216
217       --  We do not have Signal 0 in reality. We just use this value
218       --  to identify not existing signals (see s-intnam.ads). Therefore,
219       --  Signal 0 should not be used in all signal related operations hence
220       --  mark it as reserved.
221
222       Reserve (0) := True;
223    end;
224 end System.Interrupt_Management;