OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [ada/] [s-intman-solaris.adb] - Blame information for rev 16

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
------------------------------------------------------------------------------
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-2005 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 a Solaris version of this package.
35
 
36
--  Make a careful study of all signals available under the OS,
37
--  to see which need to be reserved, kept always unmasked,
38
--  or kept always unmasked.
39
 
40
--  Be on the lookout for special signals that
41
--  may be used by the thread library.
42
 
43
with Interfaces.C;
44
--  used for int
45
 
46
with System.OS_Interface;
47
--  used for various Constants, Signal and types
48
 
49
package body System.Interrupt_Management is
50
 
51
   use Interfaces.C;
52
   use System.OS_Interface;
53
 
54
   type Interrupt_List is array (Interrupt_ID range <>) of Interrupt_ID;
55
 
56
   Exception_Interrupts : constant Interrupt_List :=
57
     (SIGFPE, SIGILL, SIGSEGV, SIGBUS);
58
 
59
   Unreserve_All_Interrupts : Interfaces.C.int;
60
   pragma Import
61
     (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts");
62
 
63
   function State (Int : Interrupt_ID) return Character;
64
   pragma Import (C, State, "__gnat_get_interrupt_state");
65
   --  Get interrupt state.  Defined in init.c
66
   --  The input argument is the interrupt number,
67
   --  and the result is one of the following:
68
 
69
   User    : constant Character := 'u';
70
   Runtime : constant Character := 'r';
71
   Default : constant Character := 's';
72
   --    'n'   this interrupt not set by any Interrupt_State pragma
73
   --    'u'   Interrupt_State pragma set state to User
74
   --    'r'   Interrupt_State pragma set state to Runtime
75
   --    's'   Interrupt_State pragma set state to System (use "default"
76
   --           system handler)
77
 
78
   ----------------------
79
   -- Notify_Exception --
80
   ----------------------
81
 
82
   --  This function identifies the Ada exception to be raised using
83
   --  the information when the system received a synchronous signal.
84
   --  Since this function is machine and OS dependent, different code
85
   --  has to be provided for different target.
86
 
87
   procedure Notify_Exception
88
     (signo   : Signal;
89
      info    : access siginfo_t;
90
      context : access ucontext_t);
91
 
92
   ----------------------
93
   -- Notify_Exception --
94
   ----------------------
95
 
96
   procedure Notify_Exception
97
     (signo   : Signal;
98
      info    : access siginfo_t;
99
      context : access ucontext_t)
100
   is
101
      pragma Unreferenced (context);
102
   begin
103
      --  Check that treatment of exception propagation here
104
      --  is consistent with treatment of the abort signal in
105
      --  System.Task_Primitives.Operations.
106
 
107
      case signo is
108
         when SIGFPE =>
109
            case info.si_code is
110
               when  FPE_INTDIV |
111
                     FPE_INTOVF |
112
                     FPE_FLTDIV |
113
                     FPE_FLTOVF |
114
                     FPE_FLTUND |
115
                     FPE_FLTRES |
116
                     FPE_FLTINV |
117
                     FPE_FLTSUB =>
118
 
119
                  raise Constraint_Error;
120
 
121
               when others =>
122
                  pragma Assert (False);
123
                  null;
124
            end case;
125
 
126
         when SIGILL | SIGSEGV | SIGBUS  =>
127
            raise Storage_Error;
128
 
129
         when others =>
130
            pragma Assert (False);
131
            null;
132
      end case;
133
   end Notify_Exception;
134
 
135
   ----------------
136
   -- Initialize --
137
   ----------------
138
 
139
   Initialized : Boolean := False;
140
 
141
   procedure Initialize is
142
      act     : aliased struct_sigaction;
143
      old_act : aliased struct_sigaction;
144
      mask    : aliased sigset_t;
145
      Result  : Interfaces.C.int;
146
 
147
   begin
148
      if Initialized then
149
         return;
150
      end if;
151
 
152
      Initialized := True;
153
 
154
      --  Need to call pthread_init very early because it is doing signal
155
      --  initializations.
156
 
157
      pthread_init;
158
 
159
      --  Change this if you want to use another signal for task abort.
160
      --  SIGTERM might be a good one.
161
 
162
      Abort_Task_Interrupt := SIGABRT;
163
 
164
      act.sa_handler := Notify_Exception'Address;
165
 
166
      --  Set sa_flags to SA_NODEFER so that during the handler execution
167
      --  we do not change the Signal_Mask to be masked for the Signal.
168
      --  This is a temporary fix to the problem that the Signal_Mask is
169
      --  not restored after the exception (longjmp) from the handler.
170
      --  The right fix should be made in sigsetjmp so that we save
171
      --  the Signal_Set and restore it after a longjmp.
172
 
173
      --  In that case, this field should be changed back to 0. ??? (Dong-Ik)
174
 
175
      act.sa_flags := 16;
176
 
177
      Result := sigemptyset (mask'Access);
178
      pragma Assert (Result = 0);
179
 
180
      --  ??? For the same reason explained above, we can't mask these
181
      --  signals because otherwise we won't be able to catch more than
182
      --  one signal.
183
 
184
      act.sa_mask := mask;
185
 
186
      pragma Assert (Keep_Unmasked = (Interrupt_ID'Range => False));
187
      pragma Assert (Reserve = (Interrupt_ID'Range => False));
188
 
189
      for J in Exception_Interrupts'Range loop
190
         if State (Exception_Interrupts (J)) /= User then
191
            Keep_Unmasked (Exception_Interrupts (J)) := True;
192
            Reserve (Exception_Interrupts (J)) := True;
193
 
194
            if State (Exception_Interrupts (J)) /= Default then
195
               Result :=
196
                 sigaction
197
                 (Signal (Exception_Interrupts (J)), act'Unchecked_Access,
198
                  old_act'Unchecked_Access);
199
               pragma Assert (Result = 0);
200
            end if;
201
         end if;
202
      end loop;
203
 
204
      if State (Abort_Task_Interrupt) /= User then
205
         Keep_Unmasked (Abort_Task_Interrupt) := True;
206
         Reserve (Abort_Task_Interrupt) := True;
207
      end if;
208
 
209
      --  Set SIGINT to unmasked state as long as it's
210
      --  not in "User" state.  Check for Unreserve_All_Interrupts last
211
 
212
      if State (SIGINT) /= User then
213
         Keep_Unmasked (SIGINT) := True;
214
         Reserve (SIGINT) := True;
215
      end if;
216
 
217
      --  Check all signals for state that requires keeping them
218
      --  unmasked and reserved
219
 
220
      for J in Interrupt_ID'Range loop
221
         if State (J) = Default or else State (J) = Runtime then
222
            Keep_Unmasked (J) := True;
223
            Reserve (J) := True;
224
         end if;
225
      end loop;
226
 
227
      --  Add the set of signals that must always be unmasked for this target
228
 
229
      for J in Unmasked'Range loop
230
         Keep_Unmasked (Interrupt_ID (Unmasked (J))) := True;
231
         Reserve (Interrupt_ID (Unmasked (J))) := True;
232
      end loop;
233
 
234
      --  Add target-specific reserved signals
235
 
236
      for J in Reserved'Range loop
237
         Reserve (Interrupt_ID (Reserved (J))) := True;
238
      end loop;
239
 
240
      --  Process pragma Unreserve_All_Interrupts. This overrides any
241
      --  settings due to pragma Interrupt_State:
242
 
243
      if Unreserve_All_Interrupts /= 0 then
244
         Keep_Unmasked (SIGINT) := False;
245
         Reserve (SIGINT) := False;
246
      end if;
247
 
248
      --  We do not have Signal 0 in reality. We just use this value
249
      --  to identify not existing signals (see s-intnam.ads). Therefore,
250
      --  Signal 0 should not be used in all signal related operations hence
251
      --  mark it as reserved.
252
 
253
      Reserve (0) := True;
254
   end Initialize;
255
 
256
end System.Interrupt_Management;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.