OSDN Git Service

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