1 ------------------------------------------------------------------------------
3 -- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
5 -- SYSTEM.INTERRUPT_MANAGEMENT.OPERATIONS --
10 -- Copyright (C) 1997-1998, Florida State University --
12 -- GNARL is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNARL; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- GNARL was developed by the GNARL team at Florida State University. It is --
31 -- now maintained by Ada Core Technologies Inc. in cooperation with Florida --
32 -- State University (http://www.gnat.com). --
34 ------------------------------------------------------------------------------
36 -- This is a POSIX-like version of this package.
37 -- Note: this file can only be used for POSIX compliant systems.
44 with System
.OS_Interface
;
45 -- used for various type, constant, and operations
47 with System
.Storage_Elements
;
48 -- used for To_Address
51 with Unchecked_Conversion
;
53 package body System
.Interrupt_Management
.Operations
is
56 use System
.OS_Interface
;
58 type Interrupt_Mask_Ptr
is access all Interrupt_Mask
;
61 Unchecked_Conversion
(Interrupt_Mask_Ptr
, sigset_t_ptr
);
67 Initial_Action
: array (Signal
) of aliased struct_sigaction
;
69 Default_Action
: aliased struct_sigaction
;
71 Ignore_Action
: aliased struct_sigaction
;
73 ----------------------------
74 -- Thread_Block_Interrupt --
75 ----------------------------
77 procedure Thread_Block_Interrupt
78 (Interrupt
: Interrupt_ID
)
80 Result
: Interfaces
.C
.int
;
81 Mask
: aliased sigset_t
;
84 Result
:= sigemptyset
(Mask
'Access);
85 pragma Assert
(Result
= 0);
86 Result
:= sigaddset
(Mask
'Access, Signal
(Interrupt
));
87 pragma Assert
(Result
= 0);
88 Result
:= pthread_sigmask
(SIG_BLOCK
, Mask
'Unchecked_Access, null);
89 pragma Assert
(Result
= 0);
90 end Thread_Block_Interrupt
;
92 ------------------------------
93 -- Thread_Unblock_Interrupt --
94 ------------------------------
96 procedure Thread_Unblock_Interrupt
97 (Interrupt
: Interrupt_ID
)
99 Mask
: aliased sigset_t
;
100 Result
: Interfaces
.C
.int
;
103 Result
:= sigemptyset
(Mask
'Access);
104 pragma Assert
(Result
= 0);
105 Result
:= sigaddset
(Mask
'Access, Signal
(Interrupt
));
106 pragma Assert
(Result
= 0);
107 Result
:= pthread_sigmask
(SIG_UNBLOCK
, Mask
'Unchecked_Access, null);
108 pragma Assert
(Result
= 0);
109 end Thread_Unblock_Interrupt
;
111 ------------------------
112 -- Set_Interrupt_Mask --
113 ------------------------
115 procedure Set_Interrupt_Mask
(Mask
: access Interrupt_Mask
) is
116 Result
: Interfaces
.C
.int
;
119 Result
:= pthread_sigmask
120 (SIG_SETMASK
, +Interrupt_Mask_Ptr
(Mask
), null);
121 pragma Assert
(Result
= 0);
122 end Set_Interrupt_Mask
;
124 procedure Set_Interrupt_Mask
125 (Mask
: access Interrupt_Mask
;
126 OMask
: access Interrupt_Mask
)
128 Result
: Interfaces
.C
.int
;
131 Result
:= pthread_sigmask
132 (SIG_SETMASK
, +Interrupt_Mask_Ptr
(Mask
), +Interrupt_Mask_Ptr
(OMask
));
133 pragma Assert
(Result
= 0);
134 end Set_Interrupt_Mask
;
136 ------------------------
137 -- Get_Interrupt_Mask --
138 ------------------------
140 procedure Get_Interrupt_Mask
(Mask
: access Interrupt_Mask
) is
141 Result
: Interfaces
.C
.int
;
144 Result
:= pthread_sigmask
145 (SIG_SETMASK
, null, +Interrupt_Mask_Ptr
(Mask
));
146 pragma Assert
(Result
= 0);
147 end Get_Interrupt_Mask
;
153 function Interrupt_Wait
154 (Mask
: access Interrupt_Mask
)
157 Result
: Interfaces
.C
.int
;
158 Sig
: aliased Signal
;
161 Result
:= sigwait
(Mask
, Sig
'Access);
167 return Interrupt_ID
(Sig
);
170 ----------------------------
171 -- Install_Default_Action --
172 ----------------------------
174 procedure Install_Default_Action
(Interrupt
: Interrupt_ID
) is
175 Result
: Interfaces
.C
.int
;
180 Initial_Action
(Signal
(Interrupt
))'Access, null);
181 pragma Assert
(Result
= 0);
182 end Install_Default_Action
;
184 ---------------------------
185 -- Install_Ignore_Action --
186 ---------------------------
188 procedure Install_Ignore_Action
(Interrupt
: Interrupt_ID
) is
189 Result
: Interfaces
.C
.int
;
192 Result
:= sigaction
(Signal
(Interrupt
), Ignore_Action
'Access, null);
193 pragma Assert
(Result
= 0);
194 end Install_Ignore_Action
;
196 -------------------------
197 -- Fill_Interrupt_Mask --
198 -------------------------
200 procedure Fill_Interrupt_Mask
(Mask
: access Interrupt_Mask
) is
201 Result
: Interfaces
.C
.int
;
204 Result
:= sigfillset
(Mask
);
205 pragma Assert
(Result
= 0);
206 end Fill_Interrupt_Mask
;
208 --------------------------
209 -- Empty_Interrupt_Mask --
210 --------------------------
212 procedure Empty_Interrupt_Mask
(Mask
: access Interrupt_Mask
) is
213 Result
: Interfaces
.C
.int
;
216 Result
:= sigemptyset
(Mask
);
217 pragma Assert
(Result
= 0);
218 end Empty_Interrupt_Mask
;
220 ---------------------------
221 -- Add_To_Interrupt_Mask --
222 ---------------------------
224 procedure Add_To_Interrupt_Mask
225 (Mask
: access Interrupt_Mask
;
226 Interrupt
: Interrupt_ID
)
228 Result
: Interfaces
.C
.int
;
231 Result
:= sigaddset
(Mask
, Signal
(Interrupt
));
232 pragma Assert
(Result
= 0);
233 end Add_To_Interrupt_Mask
;
235 --------------------------------
236 -- Delete_From_Interrupt_Mask --
237 --------------------------------
239 procedure Delete_From_Interrupt_Mask
240 (Mask
: access Interrupt_Mask
;
241 Interrupt
: Interrupt_ID
)
243 Result
: Interfaces
.C
.int
;
246 Result
:= sigdelset
(Mask
, Signal
(Interrupt
));
247 pragma Assert
(Result
= 0);
248 end Delete_From_Interrupt_Mask
;
255 (Mask
: access Interrupt_Mask
;
256 Interrupt
: Interrupt_ID
) return Boolean
258 Result
: Interfaces
.C
.int
;
261 Result
:= sigismember
(Mask
, Signal
(Interrupt
));
262 pragma Assert
(Result
= 0 or else Result
= 1);
266 -------------------------
267 -- Copy_Interrupt_Mask --
268 -------------------------
270 procedure Copy_Interrupt_Mask
271 (X
: out Interrupt_Mask
;
276 end Copy_Interrupt_Mask
;
278 ----------------------------
279 -- Interrupt_Self_Process --
280 ----------------------------
282 procedure Interrupt_Self_Process
(Interrupt
: Interrupt_ID
) is
283 Result
: Interfaces
.C
.int
;
286 Result
:= kill
(getpid
, Signal
(Interrupt
));
287 pragma Assert
(Result
= 0);
288 end Interrupt_Self_Process
;
293 mask
: aliased sigset_t
;
294 allmask
: aliased sigset_t
;
295 Result
: Interfaces
.C
.int
;
298 for Sig
in 1 .. Signal
'Last loop
300 (Sig
, null, Initial_Action
(Sig
)'Unchecked_Access);
303 -- we can't check Result here since sigaction will fail on
304 -- SIGKILL, SIGSTOP, and possibly other signals
305 -- pragma Assert (Result = 0);
309 -- Setup the masks to be exported.
311 Result
:= sigemptyset
(mask
'Access);
312 pragma Assert
(Result
= 0);
314 Result
:= sigfillset
(allmask
'Access);
315 pragma Assert
(Result
= 0);
317 Default_Action
.sa_flags
:= 0;
318 Default_Action
.sa_mask
:= mask
;
319 Default_Action
.sa_handler
:=
320 Storage_Elements
.To_Address
321 (Storage_Elements
.Integer_Address
(SIG_DFL
));
323 Ignore_Action
.sa_flags
:= 0;
324 Ignore_Action
.sa_mask
:= mask
;
325 Ignore_Action
.sa_handler
:=
326 Storage_Elements
.To_Address
327 (Storage_Elements
.Integer_Address
(SIG_IGN
));
329 for I
in Interrupt_ID
loop
330 if Keep_Unmasked
(I
) then
331 Result
:= sigaddset
(mask
'Access, Signal
(I
));
332 pragma Assert
(Result
= 0);
333 Result
:= sigdelset
(allmask
'Access, Signal
(I
));
334 pragma Assert
(Result
= 0);
338 -- The Keep_Unmasked signals should be unmasked for Environment task
340 Result
:= pthread_sigmask
(SIG_UNBLOCK
, mask
'Unchecked_Access, null);
341 pragma Assert
(Result
= 0);
343 -- Get the signal mask of the Environment Task
345 Result
:= pthread_sigmask
(SIG_SETMASK
, null, mask
'Unchecked_Access);
346 pragma Assert
(Result
= 0);
348 -- Setup the constants exported
350 Environment_Mask
:= Interrupt_Mask
(mask
);
352 All_Tasks_Mask
:= Interrupt_Mask
(allmask
);
355 end System
.Interrupt_Management
.Operations
;