OSDN Git Service

2003-12-11 Ed Falis <falis@gnat.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / 5vinmaop.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 --                           O P E R A T I O N S                            --
7 --                                                                          --
8 --                                  B o d y                                 --
9 --                                                                          --
10 --          Copyright (C) 1992-2002 Free Software Foundation, Inc.          --
11 --                                                                          --
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.                                                      --
22 --                                                                          --
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.                                      --
29 --                                                                          --
30 -- GNARL was developed by the GNARL team at Florida State University.       --
31 -- Extensive contributions were provided by Ada Core Technologies, Inc.     --
32 --                                                                          --
33 ------------------------------------------------------------------------------
34
35 --  This is a OpenVMS/Alpha version of this package.
36
37 with System.OS_Interface;
38 --  used for various type, constant, and operations
39
40 with System.Parameters;
41
42 with System.Tasking;
43
44 with System.Tasking.Initialization;
45
46 with System.Task_Primitives.Operations;
47
48 with System.Task_Primitives.Operations.DEC;
49
50 with Unchecked_Conversion;
51
52 package body System.Interrupt_Management.Operations is
53
54    use System.OS_Interface;
55    use System.Parameters;
56    use System.Tasking;
57    use type unsigned_short;
58
59    function To_Address is new Unchecked_Conversion (Task_ID, System.Address);
60    package POP renames System.Task_Primitives.Operations;
61
62    ----------------------------
63    -- Thread_Block_Interrupt --
64    ----------------------------
65
66    procedure Thread_Block_Interrupt (Interrupt : Interrupt_ID) is
67       pragma Warnings (Off, Interrupt);
68    begin
69       null;
70    end Thread_Block_Interrupt;
71
72    ------------------------------
73    -- Thread_Unblock_Interrupt --
74    ------------------------------
75
76    procedure Thread_Unblock_Interrupt (Interrupt : Interrupt_ID) is
77       pragma Warnings (Off, Interrupt);
78    begin
79       null;
80    end Thread_Unblock_Interrupt;
81
82    ------------------------
83    -- Set_Interrupt_Mask --
84    ------------------------
85
86    procedure Set_Interrupt_Mask (Mask : access Interrupt_Mask) is
87       pragma Warnings (Off, Mask);
88    begin
89       null;
90    end Set_Interrupt_Mask;
91
92    procedure Set_Interrupt_Mask
93      (Mask  : access Interrupt_Mask;
94       OMask : access Interrupt_Mask)
95    is
96       pragma Warnings (Off, Mask);
97       pragma Warnings (Off, OMask);
98    begin
99       null;
100    end Set_Interrupt_Mask;
101
102    ------------------------
103    -- Get_Interrupt_Mask --
104    ------------------------
105
106    procedure Get_Interrupt_Mask (Mask : access Interrupt_Mask) is
107       pragma Warnings (Off, Mask);
108    begin
109       null;
110    end Get_Interrupt_Mask;
111
112    --------------------
113    -- Interrupt_Wait --
114    --------------------
115
116    function To_unsigned_long is new
117      Unchecked_Conversion (System.Address, unsigned_long);
118
119    function Interrupt_Wait (Mask : access Interrupt_Mask)
120      return Interrupt_ID
121    is
122       Self_ID : Task_ID := Self;
123       Iosb    : IO_Status_Block_Type := (0, 0, 0);
124       Status  : Cond_Value_Type;
125
126    begin
127
128       --  A QIO read is registered. The system call returns immediately
129       --  after scheduling an AST to be fired when the operation
130       --  completes.
131
132       Sys_QIO
133         (Status => Status,
134          Chan   => Rcv_Interrupt_Chan,
135          Func   => IO_READVBLK,
136          Iosb   => Iosb,
137          Astadr =>
138            POP.DEC.Interrupt_AST_Handler'Access,
139          Astprm => To_Address (Self_ID),
140          P1     => To_unsigned_long (Interrupt_Mailbox'Address),
141          P2     => Interrupt_ID'Size / 8);
142
143       pragma Assert ((Status and 1) = 1);
144
145       loop
146
147          --  Wait to be woken up. Could be that the AST has fired,
148          --  in which case the Iosb.Status variable will be non-zero,
149          --  or maybe the wait is being aborted.
150
151          POP.Sleep
152            (Self_ID,
153             System.Tasking.Interrupt_Server_Blocked_On_Event_Flag);
154
155          if Iosb.Status /= 0 then
156             if (Iosb.Status and 1) = 1
157               and then Mask (Signal (Interrupt_Mailbox))
158             then
159                return Interrupt_Mailbox;
160             else
161                return 0;
162             end if;
163          else
164             POP.Unlock (Self_ID);
165
166             if Single_Lock then
167                POP.Unlock_RTS;
168             end if;
169
170             System.Tasking.Initialization.Undefer_Abort (Self_ID);
171             System.Tasking.Initialization.Defer_Abort (Self_ID);
172
173             if Single_Lock then
174                POP.Lock_RTS;
175             end if;
176
177             POP.Write_Lock (Self_ID);
178          end if;
179       end loop;
180    end Interrupt_Wait;
181
182    ----------------------------
183    -- Install_Default_Action --
184    ----------------------------
185
186    procedure Install_Default_Action (Interrupt : Interrupt_ID) is
187       pragma Warnings (Off, Interrupt);
188    begin
189       null;
190    end Install_Default_Action;
191
192    ---------------------------
193    -- Install_Ignore_Action --
194    ---------------------------
195
196    procedure Install_Ignore_Action (Interrupt : Interrupt_ID) is
197       pragma Warnings (Off, Interrupt);
198    begin
199       null;
200    end Install_Ignore_Action;
201
202    -------------------------
203    -- Fill_Interrupt_Mask --
204    -------------------------
205
206    procedure Fill_Interrupt_Mask (Mask : access Interrupt_Mask) is
207    begin
208       Mask.all := (others => True);
209    end Fill_Interrupt_Mask;
210
211    --------------------------
212    -- Empty_Interrupt_Mask --
213    --------------------------
214
215    procedure Empty_Interrupt_Mask (Mask : access Interrupt_Mask) is
216    begin
217       Mask.all := (others => False);
218    end Empty_Interrupt_Mask;
219
220    ---------------------------
221    -- Add_To_Interrupt_Mask --
222    ---------------------------
223
224    procedure Add_To_Interrupt_Mask
225      (Mask      : access Interrupt_Mask;
226       Interrupt : Interrupt_ID)
227    is
228    begin
229       Mask (Signal (Interrupt)) := True;
230    end Add_To_Interrupt_Mask;
231
232    --------------------------------
233    -- Delete_From_Interrupt_Mask --
234    --------------------------------
235
236    procedure Delete_From_Interrupt_Mask
237      (Mask      : access Interrupt_Mask;
238       Interrupt : Interrupt_ID)
239    is
240    begin
241       Mask (Signal (Interrupt)) := False;
242    end Delete_From_Interrupt_Mask;
243
244    ---------------
245    -- Is_Member --
246    ---------------
247
248    function Is_Member
249      (Mask      : access Interrupt_Mask;
250       Interrupt : Interrupt_ID) return Boolean
251    is
252    begin
253       return Mask (Signal (Interrupt));
254    end Is_Member;
255
256    -------------------------
257    -- Copy_Interrupt_Mask --
258    -------------------------
259
260    procedure Copy_Interrupt_Mask
261      (X : out Interrupt_Mask;
262       Y : Interrupt_Mask)
263    is
264    begin
265       X := Y;
266    end Copy_Interrupt_Mask;
267
268    -------------------------
269    -- Interrupt_Self_Process --
270    -------------------------
271
272    procedure Interrupt_Self_Process (Interrupt : Interrupt_ID) is
273       Status : Cond_Value_Type;
274    begin
275       Sys_QIO
276         (Status => Status,
277          Chan   => Snd_Interrupt_Chan,
278          Func   => IO_WRITEVBLK,
279          P1     => To_unsigned_long (Interrupt'Address),
280          P2     => Interrupt_ID'Size / 8);
281
282       pragma Assert ((Status and 1) = 1);
283    end Interrupt_Self_Process;
284
285 begin
286    Environment_Mask := (others => False);
287    All_Tasks_Mask := (others => True);
288
289    for J in Interrupt_ID loop
290       if Keep_Unmasked (J) then
291          Environment_Mask (Signal (J)) := True;
292          All_Tasks_Mask (Signal (J)) := False;
293       end if;
294    end loop;
295 end System.Interrupt_Management.Operations;