Merge -r 127928:132243 from trunk
[official-gcc.git] / gcc / ada / s-inmaop-posix.adb
blob2251c23d3c5a56c637b9413be0cdf0dbf0ac0341
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 -- O P E R A T I O N S --
7 -- --
8 -- B o d y --
9 -- --
10 -- Copyright (C) 1991-1994, Florida State University --
11 -- Copyright (C) 1995-2007, AdaCore --
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, 51 Franklin Street, Fifth Floor, --
22 -- Boston, MA 02110-1301, 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. --
32 -- Extensive contributions were provided by Ada Core Technologies, Inc. --
33 -- --
34 ------------------------------------------------------------------------------
36 -- This is a POSIX-like version of this package.
37 -- Note: this file can only be used for POSIX compliant systems.
39 with Interfaces.C;
40 -- used for int
41 -- size_t
42 -- unsigned
44 with System.OS_Interface;
45 -- used for various type, constant, and operations
47 with System.Storage_Elements;
48 -- used for To_Address
49 -- Integer_Address
51 package body System.Interrupt_Management.Operations is
53 use Interfaces.C;
54 use System.OS_Interface;
56 ---------------------
57 -- Local Variables --
58 ---------------------
60 Initial_Action : array (Signal) of aliased struct_sigaction;
62 Default_Action : aliased struct_sigaction;
63 pragma Warnings (Off, Default_Action);
65 Ignore_Action : aliased struct_sigaction;
67 ----------------------------
68 -- Thread_Block_Interrupt --
69 ----------------------------
71 procedure Thread_Block_Interrupt
72 (Interrupt : Interrupt_ID)
74 Result : Interfaces.C.int;
75 Mask : aliased sigset_t;
76 begin
77 Result := sigemptyset (Mask'Access);
78 pragma Assert (Result = 0);
79 Result := sigaddset (Mask'Access, Signal (Interrupt));
80 pragma Assert (Result = 0);
81 Result := pthread_sigmask (SIG_BLOCK, Mask'Access, null);
82 pragma Assert (Result = 0);
83 end Thread_Block_Interrupt;
85 ------------------------------
86 -- Thread_Unblock_Interrupt --
87 ------------------------------
89 procedure Thread_Unblock_Interrupt
90 (Interrupt : Interrupt_ID)
92 Mask : aliased sigset_t;
93 Result : Interfaces.C.int;
94 begin
95 Result := sigemptyset (Mask'Access);
96 pragma Assert (Result = 0);
97 Result := sigaddset (Mask'Access, Signal (Interrupt));
98 pragma Assert (Result = 0);
99 Result := pthread_sigmask (SIG_UNBLOCK, Mask'Access, null);
100 pragma Assert (Result = 0);
101 end Thread_Unblock_Interrupt;
103 ------------------------
104 -- Set_Interrupt_Mask --
105 ------------------------
107 procedure Set_Interrupt_Mask (Mask : access Interrupt_Mask) is
108 Result : Interfaces.C.int;
109 begin
110 Result := pthread_sigmask (SIG_SETMASK, Mask, null);
111 pragma Assert (Result = 0);
112 end Set_Interrupt_Mask;
114 procedure Set_Interrupt_Mask
115 (Mask : access Interrupt_Mask;
116 OMask : access Interrupt_Mask)
118 Result : Interfaces.C.int;
119 begin
120 Result := pthread_sigmask (SIG_SETMASK, Mask, OMask);
121 pragma Assert (Result = 0);
122 end Set_Interrupt_Mask;
124 ------------------------
125 -- Get_Interrupt_Mask --
126 ------------------------
128 procedure Get_Interrupt_Mask (Mask : access Interrupt_Mask) is
129 Result : Interfaces.C.int;
130 begin
131 Result := pthread_sigmask (SIG_SETMASK, null, Mask);
132 pragma Assert (Result = 0);
133 end Get_Interrupt_Mask;
135 --------------------
136 -- Interrupt_Wait --
137 --------------------
139 function Interrupt_Wait
140 (Mask : access Interrupt_Mask) return Interrupt_ID
142 Result : Interfaces.C.int;
143 Sig : aliased Signal;
145 begin
146 Result := sigwait (Mask, Sig'Access);
148 if Result /= 0 then
149 return 0;
150 end if;
152 return Interrupt_ID (Sig);
153 end Interrupt_Wait;
155 ----------------------------
156 -- Install_Default_Action --
157 ----------------------------
159 procedure Install_Default_Action (Interrupt : Interrupt_ID) is
160 Result : Interfaces.C.int;
161 begin
162 Result := sigaction
163 (Signal (Interrupt),
164 Initial_Action (Signal (Interrupt))'Access, null);
165 pragma Assert (Result = 0);
166 end Install_Default_Action;
168 ---------------------------
169 -- Install_Ignore_Action --
170 ---------------------------
172 procedure Install_Ignore_Action (Interrupt : Interrupt_ID) is
173 Result : Interfaces.C.int;
174 begin
175 Result := sigaction (Signal (Interrupt), Ignore_Action'Access, null);
176 pragma Assert (Result = 0);
177 end Install_Ignore_Action;
179 -------------------------
180 -- Fill_Interrupt_Mask --
181 -------------------------
183 procedure Fill_Interrupt_Mask (Mask : access Interrupt_Mask) is
184 Result : Interfaces.C.int;
185 begin
186 Result := sigfillset (Mask);
187 pragma Assert (Result = 0);
188 end Fill_Interrupt_Mask;
190 --------------------------
191 -- Empty_Interrupt_Mask --
192 --------------------------
194 procedure Empty_Interrupt_Mask (Mask : access Interrupt_Mask) is
195 Result : Interfaces.C.int;
196 begin
197 Result := sigemptyset (Mask);
198 pragma Assert (Result = 0);
199 end Empty_Interrupt_Mask;
201 ---------------------------
202 -- Add_To_Interrupt_Mask --
203 ---------------------------
205 procedure Add_To_Interrupt_Mask
206 (Mask : access Interrupt_Mask;
207 Interrupt : Interrupt_ID)
209 Result : Interfaces.C.int;
210 begin
211 Result := sigaddset (Mask, Signal (Interrupt));
212 pragma Assert (Result = 0);
213 end Add_To_Interrupt_Mask;
215 --------------------------------
216 -- Delete_From_Interrupt_Mask --
217 --------------------------------
219 procedure Delete_From_Interrupt_Mask
220 (Mask : access Interrupt_Mask;
221 Interrupt : Interrupt_ID)
223 Result : Interfaces.C.int;
224 begin
225 Result := sigdelset (Mask, Signal (Interrupt));
226 pragma Assert (Result = 0);
227 end Delete_From_Interrupt_Mask;
229 ---------------
230 -- Is_Member --
231 ---------------
233 function Is_Member
234 (Mask : access Interrupt_Mask;
235 Interrupt : Interrupt_ID) return Boolean
237 Result : Interfaces.C.int;
238 begin
239 Result := sigismember (Mask, Signal (Interrupt));
240 pragma Assert (Result = 0 or else Result = 1);
241 return Result = 1;
242 end Is_Member;
244 -------------------------
245 -- Copy_Interrupt_Mask --
246 -------------------------
248 procedure Copy_Interrupt_Mask
249 (X : out Interrupt_Mask;
250 Y : Interrupt_Mask) is
251 begin
252 X := Y;
253 end Copy_Interrupt_Mask;
255 ----------------------------
256 -- Interrupt_Self_Process --
257 ----------------------------
259 procedure Interrupt_Self_Process (Interrupt : Interrupt_ID) is
260 Result : Interfaces.C.int;
261 begin
262 Result := kill (getpid, Signal (Interrupt));
263 pragma Assert (Result = 0);
264 end Interrupt_Self_Process;
266 --------------------------
267 -- Setup_Interrupt_Mask --
268 --------------------------
270 procedure Setup_Interrupt_Mask is
271 begin
272 -- Mask task for all signals. The original mask of the Environment task
273 -- will be recovered by Interrupt_Manager task during the elaboration
274 -- of s-interr.adb.
276 Set_Interrupt_Mask (All_Tasks_Mask'Access);
277 end Setup_Interrupt_Mask;
279 begin
280 declare
281 mask : aliased sigset_t;
282 allmask : aliased sigset_t;
283 Result : Interfaces.C.int;
285 begin
286 Interrupt_Management.Initialize;
288 for Sig in 1 .. Signal'Last loop
289 Result := sigaction
290 (Sig, null, Initial_Action (Sig)'Access);
292 -- ??? [assert 1]
293 -- we can't check Result here since sigaction will fail on
294 -- SIGKILL, SIGSTOP, and possibly other signals
295 -- pragma Assert (Result = 0);
297 end loop;
299 -- Setup the masks to be exported
301 Result := sigemptyset (mask'Access);
302 pragma Assert (Result = 0);
304 Result := sigfillset (allmask'Access);
305 pragma Assert (Result = 0);
307 Default_Action.sa_flags := 0;
308 Default_Action.sa_mask := mask;
309 Default_Action.sa_handler :=
310 Storage_Elements.To_Address
311 (Storage_Elements.Integer_Address (SIG_DFL));
313 Ignore_Action.sa_flags := 0;
314 Ignore_Action.sa_mask := mask;
315 Ignore_Action.sa_handler :=
316 Storage_Elements.To_Address
317 (Storage_Elements.Integer_Address (SIG_IGN));
319 for J in Interrupt_ID loop
320 if Keep_Unmasked (J) then
321 Result := sigaddset (mask'Access, Signal (J));
322 pragma Assert (Result = 0);
323 Result := sigdelset (allmask'Access, Signal (J));
324 pragma Assert (Result = 0);
325 end if;
326 end loop;
328 -- The Keep_Unmasked signals should be unmasked for Environment task
330 Result := pthread_sigmask (SIG_UNBLOCK, mask'Access, null);
331 pragma Assert (Result = 0);
333 -- Get the signal mask of the Environment Task
335 Result := pthread_sigmask (SIG_SETMASK, null, mask'Access);
336 pragma Assert (Result = 0);
338 -- Setup the constants exported
340 Environment_Mask := Interrupt_Mask (mask);
342 All_Tasks_Mask := Interrupt_Mask (allmask);
343 end;
345 end System.Interrupt_Management.Operations;