annotate gcc/ada/libgnarl/s-inmaop__posix.adb @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- SYSTEM.INTERRUPT_MANAGEMENT.OPERATIONS --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
kono
parents:
diff changeset
9 -- Copyright (C) 1991-2017, Florida State University --
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
10 -- Copyright (C) 1995-2018, AdaCore --
111
kono
parents:
diff changeset
11 -- --
kono
parents:
diff changeset
12 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
13 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
14 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
17 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
18 -- --
kono
parents:
diff changeset
19 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
20 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
21 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
22 -- --
kono
parents:
diff changeset
23 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
24 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
25 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
26 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
27 -- --
kono
parents:
diff changeset
28 -- GNARL was developed by the GNARL team at Florida State University. --
kono
parents:
diff changeset
29 -- Extensive contributions were provided by Ada Core Technologies, Inc. --
kono
parents:
diff changeset
30 -- --
kono
parents:
diff changeset
31 ------------------------------------------------------------------------------
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33 -- This is a POSIX-like version of this package
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 -- Note: this file can only be used for POSIX compliant systems
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 with Interfaces.C;
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 with System.OS_Interface;
kono
parents:
diff changeset
40 with System.Storage_Elements;
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 package body System.Interrupt_Management.Operations is
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 use Interfaces.C;
kono
parents:
diff changeset
45 use System.OS_Interface;
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 ---------------------
kono
parents:
diff changeset
48 -- Local Variables --
kono
parents:
diff changeset
49 ---------------------
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 Initial_Action : array (Signal) of aliased struct_sigaction;
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 Default_Action : aliased struct_sigaction;
kono
parents:
diff changeset
54 pragma Warnings (Off, Default_Action);
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 Ignore_Action : aliased struct_sigaction;
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 ----------------------------
kono
parents:
diff changeset
59 -- Thread_Block_Interrupt --
kono
parents:
diff changeset
60 ----------------------------
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 procedure Thread_Block_Interrupt
kono
parents:
diff changeset
63 (Interrupt : Interrupt_ID)
kono
parents:
diff changeset
64 is
kono
parents:
diff changeset
65 Result : Interfaces.C.int;
kono
parents:
diff changeset
66 Mask : aliased sigset_t;
kono
parents:
diff changeset
67 begin
kono
parents:
diff changeset
68 Result := sigemptyset (Mask'Access);
kono
parents:
diff changeset
69 pragma Assert (Result = 0);
kono
parents:
diff changeset
70 Result := sigaddset (Mask'Access, Signal (Interrupt));
kono
parents:
diff changeset
71 pragma Assert (Result = 0);
kono
parents:
diff changeset
72 Result := pthread_sigmask (SIG_BLOCK, Mask'Access, null);
kono
parents:
diff changeset
73 pragma Assert (Result = 0);
kono
parents:
diff changeset
74 end Thread_Block_Interrupt;
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 ------------------------------
kono
parents:
diff changeset
77 -- Thread_Unblock_Interrupt --
kono
parents:
diff changeset
78 ------------------------------
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 procedure Thread_Unblock_Interrupt
kono
parents:
diff changeset
81 (Interrupt : Interrupt_ID)
kono
parents:
diff changeset
82 is
kono
parents:
diff changeset
83 Mask : aliased sigset_t;
kono
parents:
diff changeset
84 Result : Interfaces.C.int;
kono
parents:
diff changeset
85 begin
kono
parents:
diff changeset
86 Result := sigemptyset (Mask'Access);
kono
parents:
diff changeset
87 pragma Assert (Result = 0);
kono
parents:
diff changeset
88 Result := sigaddset (Mask'Access, Signal (Interrupt));
kono
parents:
diff changeset
89 pragma Assert (Result = 0);
kono
parents:
diff changeset
90 Result := pthread_sigmask (SIG_UNBLOCK, Mask'Access, null);
kono
parents:
diff changeset
91 pragma Assert (Result = 0);
kono
parents:
diff changeset
92 end Thread_Unblock_Interrupt;
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 ------------------------
kono
parents:
diff changeset
95 -- Set_Interrupt_Mask --
kono
parents:
diff changeset
96 ------------------------
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 procedure Set_Interrupt_Mask (Mask : access Interrupt_Mask) is
kono
parents:
diff changeset
99 Result : Interfaces.C.int;
kono
parents:
diff changeset
100 begin
kono
parents:
diff changeset
101 Result := pthread_sigmask (SIG_SETMASK, Mask, null);
kono
parents:
diff changeset
102 pragma Assert (Result = 0);
kono
parents:
diff changeset
103 end Set_Interrupt_Mask;
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 procedure Set_Interrupt_Mask
kono
parents:
diff changeset
106 (Mask : access Interrupt_Mask;
kono
parents:
diff changeset
107 OMask : access Interrupt_Mask)
kono
parents:
diff changeset
108 is
kono
parents:
diff changeset
109 Result : Interfaces.C.int;
kono
parents:
diff changeset
110 begin
kono
parents:
diff changeset
111 Result := pthread_sigmask (SIG_SETMASK, Mask, OMask);
kono
parents:
diff changeset
112 pragma Assert (Result = 0);
kono
parents:
diff changeset
113 end Set_Interrupt_Mask;
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 ------------------------
kono
parents:
diff changeset
116 -- Get_Interrupt_Mask --
kono
parents:
diff changeset
117 ------------------------
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 procedure Get_Interrupt_Mask (Mask : access Interrupt_Mask) is
kono
parents:
diff changeset
120 Result : Interfaces.C.int;
kono
parents:
diff changeset
121 begin
kono
parents:
diff changeset
122 Result := pthread_sigmask (SIG_SETMASK, null, Mask);
kono
parents:
diff changeset
123 pragma Assert (Result = 0);
kono
parents:
diff changeset
124 end Get_Interrupt_Mask;
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 --------------------
kono
parents:
diff changeset
127 -- Interrupt_Wait --
kono
parents:
diff changeset
128 --------------------
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 function Interrupt_Wait
kono
parents:
diff changeset
131 (Mask : access Interrupt_Mask) return Interrupt_ID
kono
parents:
diff changeset
132 is
kono
parents:
diff changeset
133 Result : Interfaces.C.int;
kono
parents:
diff changeset
134 Sig : aliased Signal;
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 begin
kono
parents:
diff changeset
137 Result := sigwait (Mask, Sig'Access);
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 if Result /= 0 then
kono
parents:
diff changeset
140 return 0;
kono
parents:
diff changeset
141 end if;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 return Interrupt_ID (Sig);
kono
parents:
diff changeset
144 end Interrupt_Wait;
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 ----------------------------
kono
parents:
diff changeset
147 -- Install_Default_Action --
kono
parents:
diff changeset
148 ----------------------------
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 procedure Install_Default_Action (Interrupt : Interrupt_ID) is
kono
parents:
diff changeset
151 Result : Interfaces.C.int;
kono
parents:
diff changeset
152 begin
kono
parents:
diff changeset
153 Result := sigaction
kono
parents:
diff changeset
154 (Signal (Interrupt),
kono
parents:
diff changeset
155 Initial_Action (Signal (Interrupt))'Access, null);
kono
parents:
diff changeset
156 pragma Assert (Result = 0);
kono
parents:
diff changeset
157 end Install_Default_Action;
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 ---------------------------
kono
parents:
diff changeset
160 -- Install_Ignore_Action --
kono
parents:
diff changeset
161 ---------------------------
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 procedure Install_Ignore_Action (Interrupt : Interrupt_ID) is
kono
parents:
diff changeset
164 Result : Interfaces.C.int;
kono
parents:
diff changeset
165 begin
kono
parents:
diff changeset
166 Result := sigaction (Signal (Interrupt), Ignore_Action'Access, null);
kono
parents:
diff changeset
167 pragma Assert (Result = 0);
kono
parents:
diff changeset
168 end Install_Ignore_Action;
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 -------------------------
kono
parents:
diff changeset
171 -- Fill_Interrupt_Mask --
kono
parents:
diff changeset
172 -------------------------
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 procedure Fill_Interrupt_Mask (Mask : access Interrupt_Mask) is
kono
parents:
diff changeset
175 Result : Interfaces.C.int;
kono
parents:
diff changeset
176 begin
kono
parents:
diff changeset
177 Result := sigfillset (Mask);
kono
parents:
diff changeset
178 pragma Assert (Result = 0);
kono
parents:
diff changeset
179 end Fill_Interrupt_Mask;
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 --------------------------
kono
parents:
diff changeset
182 -- Empty_Interrupt_Mask --
kono
parents:
diff changeset
183 --------------------------
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 procedure Empty_Interrupt_Mask (Mask : access Interrupt_Mask) is
kono
parents:
diff changeset
186 Result : Interfaces.C.int;
kono
parents:
diff changeset
187 begin
kono
parents:
diff changeset
188 Result := sigemptyset (Mask);
kono
parents:
diff changeset
189 pragma Assert (Result = 0);
kono
parents:
diff changeset
190 end Empty_Interrupt_Mask;
kono
parents:
diff changeset
191
kono
parents:
diff changeset
192 ---------------------------
kono
parents:
diff changeset
193 -- Add_To_Interrupt_Mask --
kono
parents:
diff changeset
194 ---------------------------
kono
parents:
diff changeset
195
kono
parents:
diff changeset
196 procedure Add_To_Interrupt_Mask
kono
parents:
diff changeset
197 (Mask : access Interrupt_Mask;
kono
parents:
diff changeset
198 Interrupt : Interrupt_ID)
kono
parents:
diff changeset
199 is
kono
parents:
diff changeset
200 Result : Interfaces.C.int;
kono
parents:
diff changeset
201 begin
kono
parents:
diff changeset
202 Result := sigaddset (Mask, Signal (Interrupt));
kono
parents:
diff changeset
203 pragma Assert (Result = 0);
kono
parents:
diff changeset
204 end Add_To_Interrupt_Mask;
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 --------------------------------
kono
parents:
diff changeset
207 -- Delete_From_Interrupt_Mask --
kono
parents:
diff changeset
208 --------------------------------
kono
parents:
diff changeset
209
kono
parents:
diff changeset
210 procedure Delete_From_Interrupt_Mask
kono
parents:
diff changeset
211 (Mask : access Interrupt_Mask;
kono
parents:
diff changeset
212 Interrupt : Interrupt_ID)
kono
parents:
diff changeset
213 is
kono
parents:
diff changeset
214 Result : Interfaces.C.int;
kono
parents:
diff changeset
215 begin
kono
parents:
diff changeset
216 Result := sigdelset (Mask, Signal (Interrupt));
kono
parents:
diff changeset
217 pragma Assert (Result = 0);
kono
parents:
diff changeset
218 end Delete_From_Interrupt_Mask;
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 ---------------
kono
parents:
diff changeset
221 -- Is_Member --
kono
parents:
diff changeset
222 ---------------
kono
parents:
diff changeset
223
kono
parents:
diff changeset
224 function Is_Member
kono
parents:
diff changeset
225 (Mask : access Interrupt_Mask;
kono
parents:
diff changeset
226 Interrupt : Interrupt_ID) return Boolean
kono
parents:
diff changeset
227 is
kono
parents:
diff changeset
228 Result : Interfaces.C.int;
kono
parents:
diff changeset
229 begin
kono
parents:
diff changeset
230 Result := sigismember (Mask, Signal (Interrupt));
kono
parents:
diff changeset
231 pragma Assert (Result = 0 or else Result = 1);
kono
parents:
diff changeset
232 return Result = 1;
kono
parents:
diff changeset
233 end Is_Member;
kono
parents:
diff changeset
234
kono
parents:
diff changeset
235 -------------------------
kono
parents:
diff changeset
236 -- Copy_Interrupt_Mask --
kono
parents:
diff changeset
237 -------------------------
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 procedure Copy_Interrupt_Mask
kono
parents:
diff changeset
240 (X : out Interrupt_Mask;
kono
parents:
diff changeset
241 Y : Interrupt_Mask) is
kono
parents:
diff changeset
242 begin
kono
parents:
diff changeset
243 X := Y;
kono
parents:
diff changeset
244 end Copy_Interrupt_Mask;
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 ----------------------------
kono
parents:
diff changeset
247 -- Interrupt_Self_Process --
kono
parents:
diff changeset
248 ----------------------------
kono
parents:
diff changeset
249
kono
parents:
diff changeset
250 procedure Interrupt_Self_Process (Interrupt : Interrupt_ID) is
kono
parents:
diff changeset
251 Result : Interfaces.C.int;
kono
parents:
diff changeset
252 begin
kono
parents:
diff changeset
253 Result := kill (getpid, Signal (Interrupt));
kono
parents:
diff changeset
254 pragma Assert (Result = 0);
kono
parents:
diff changeset
255 end Interrupt_Self_Process;
kono
parents:
diff changeset
256
kono
parents:
diff changeset
257 --------------------------
kono
parents:
diff changeset
258 -- Setup_Interrupt_Mask --
kono
parents:
diff changeset
259 --------------------------
kono
parents:
diff changeset
260
kono
parents:
diff changeset
261 procedure Setup_Interrupt_Mask is
kono
parents:
diff changeset
262 begin
kono
parents:
diff changeset
263 -- Mask task for all signals. The original mask of the Environment task
kono
parents:
diff changeset
264 -- will be recovered by Interrupt_Manager task during the elaboration
kono
parents:
diff changeset
265 -- of s-interr.adb.
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 Set_Interrupt_Mask (All_Tasks_Mask'Access);
kono
parents:
diff changeset
268 end Setup_Interrupt_Mask;
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 begin
kono
parents:
diff changeset
271 declare
kono
parents:
diff changeset
272 mask : aliased sigset_t;
kono
parents:
diff changeset
273 allmask : aliased sigset_t;
kono
parents:
diff changeset
274 Result : Interfaces.C.int;
kono
parents:
diff changeset
275
kono
parents:
diff changeset
276 begin
kono
parents:
diff changeset
277 Interrupt_Management.Initialize;
kono
parents:
diff changeset
278
kono
parents:
diff changeset
279 for Sig in 1 .. Signal'Last loop
kono
parents:
diff changeset
280 Result := sigaction
kono
parents:
diff changeset
281 (Sig, null, Initial_Action (Sig)'Access);
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 -- ??? [assert 1]
kono
parents:
diff changeset
284 -- we can't check Result here since sigaction will fail on
kono
parents:
diff changeset
285 -- SIGKILL, SIGSTOP, and possibly other signals
kono
parents:
diff changeset
286 -- pragma Assert (Result = 0);
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 end loop;
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 -- Setup the masks to be exported
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 Result := sigemptyset (mask'Access);
kono
parents:
diff changeset
293 pragma Assert (Result = 0);
kono
parents:
diff changeset
294
kono
parents:
diff changeset
295 Result := sigfillset (allmask'Access);
kono
parents:
diff changeset
296 pragma Assert (Result = 0);
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 Default_Action.sa_flags := 0;
kono
parents:
diff changeset
299 Default_Action.sa_mask := mask;
kono
parents:
diff changeset
300 Default_Action.sa_handler :=
kono
parents:
diff changeset
301 Storage_Elements.To_Address
kono
parents:
diff changeset
302 (Storage_Elements.Integer_Address (SIG_DFL));
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 Ignore_Action.sa_flags := 0;
kono
parents:
diff changeset
305 Ignore_Action.sa_mask := mask;
kono
parents:
diff changeset
306 Ignore_Action.sa_handler :=
kono
parents:
diff changeset
307 Storage_Elements.To_Address
kono
parents:
diff changeset
308 (Storage_Elements.Integer_Address (SIG_IGN));
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 for J in Interrupt_ID loop
kono
parents:
diff changeset
311 if Keep_Unmasked (J) then
kono
parents:
diff changeset
312 Result := sigaddset (mask'Access, Signal (J));
kono
parents:
diff changeset
313 pragma Assert (Result = 0);
kono
parents:
diff changeset
314 Result := sigdelset (allmask'Access, Signal (J));
kono
parents:
diff changeset
315 pragma Assert (Result = 0);
kono
parents:
diff changeset
316 end if;
kono
parents:
diff changeset
317 end loop;
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 -- The Keep_Unmasked signals should be unmasked for Environment task
kono
parents:
diff changeset
320
kono
parents:
diff changeset
321 Result := pthread_sigmask (SIG_UNBLOCK, mask'Access, null);
kono
parents:
diff changeset
322 pragma Assert (Result = 0);
kono
parents:
diff changeset
323
kono
parents:
diff changeset
324 -- Get the signal mask of the Environment Task
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 Result := pthread_sigmask (SIG_SETMASK, null, mask'Access);
kono
parents:
diff changeset
327 pragma Assert (Result = 0);
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 -- Setup the constants exported
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 Environment_Mask := Interrupt_Mask (mask);
kono
parents:
diff changeset
332
kono
parents:
diff changeset
333 All_Tasks_Mask := Interrupt_Mask (allmask);
kono
parents:
diff changeset
334 end;
kono
parents:
diff changeset
335
kono
parents:
diff changeset
336 end System.Interrupt_Management.Operations;