111
|
1 -- C954A01.A
|
|
2 --
|
|
3 -- Grant of Unlimited Rights
|
|
4 --
|
|
5 -- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
|
|
6 -- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
|
|
7 -- unlimited rights in the software and documentation contained herein.
|
|
8 -- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
|
|
9 -- this public release, the Government intends to confer upon all
|
|
10 -- recipients unlimited rights equal to those held by the Government.
|
|
11 -- These rights include rights to use, duplicate, release or disclose the
|
|
12 -- released technical data and computer software in whole or in part, in
|
|
13 -- any manner and for any purpose whatsoever, and to have or permit others
|
|
14 -- to do so.
|
|
15 --
|
|
16 -- DISCLAIMER
|
|
17 --
|
|
18 -- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
|
|
19 -- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
|
|
20 -- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
|
|
21 -- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
|
|
22 -- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
|
|
23 -- PARTICULAR PURPOSE OF SAID MATERIAL.
|
|
24 --*
|
|
25 --
|
|
26 -- OBJECTIVE:
|
|
27 -- Check that if a task requeued without abort on a protected entry queue
|
|
28 -- is aborted, the abort is deferred until the entry call completes,
|
|
29 -- after which the task becomes completed.
|
|
30 --
|
|
31 -- TEST DESCRIPTION:
|
|
32 -- Declare a protected type which simulates a printer device driver
|
|
33 -- (foundation code).
|
|
34 --
|
|
35 -- Declare a task which simulates a printer server for multiple printers.
|
|
36 --
|
|
37 -- For the protected type, declare an entry with a barrier that is set
|
|
38 -- false by a protected procedure (which simulates starting a print job
|
|
39 -- on the printer), and is set true by a second protected procedure (which
|
|
40 -- simulates a handler called when the printer interrupts, indicating
|
|
41 -- that printing is done).
|
|
42 --
|
|
43 -- For the task, declare an entry whose corresponding accept statement
|
|
44 -- contains a call to first protected procedure of the protected type
|
|
45 -- (which sets the barrier of the protected entry to false), followed by
|
|
46 -- a requeue with abort to the protected entry. Declare a second entry
|
|
47 -- which does nothing.
|
|
48 --
|
|
49 -- Declare a "requesting" task which calls the printer server task entry
|
|
50 -- (and thus executes the requeue). Attempt to abort the requesting
|
|
51 -- task. Verify that it is not aborted. Call the second protected
|
|
52 -- procedure of the protected type (the interrupt handler) and verify that
|
|
53 -- the protected entry completes for the requesting task. Verify that
|
|
54 -- the requesting task is then aborted.
|
|
55 --
|
|
56 -- TEST FILES:
|
|
57 -- This test depends on the following foundation code:
|
|
58 --
|
|
59 -- F954A00.A
|
|
60 --
|
|
61 --
|
|
62 -- CHANGE HISTORY:
|
|
63 -- 06 Dec 94 SAIC ACVC 2.0
|
|
64 -- 10 Oct 96 SAIC Added pragma elaborate.
|
|
65 --
|
|
66 --!
|
|
67
|
|
68 package C954A01_0 is -- Printer server abstraction.
|
|
69
|
|
70 -- Simulate a system with multiple printers. The entry Print requests
|
|
71 -- that data be printed on the next available printer. The entry call
|
|
72 -- is accepted when a printer is available, and completes when printing
|
|
73 -- is done.
|
|
74
|
|
75
|
|
76 task Printer_Server is
|
|
77 entry Print (File_Name : String); -- Test the requeue statement.
|
|
78 entry Verify_Results; -- Artifice for test purposes.
|
|
79 end Printer_Server;
|
|
80
|
|
81 end C954A01_0;
|
|
82
|
|
83
|
|
84 --==================================================================--
|
|
85
|
|
86
|
|
87 with Report;
|
|
88 with ImpDef;
|
|
89
|
|
90 with F954A00; -- Printer device abstraction.
|
|
91 use F954A00;
|
|
92 pragma Elaborate(F954A00);
|
|
93
|
|
94 package body C954A01_0 is -- Printer server abstraction.
|
|
95
|
|
96 task body Printer_Server is
|
|
97 Printers_Busy : Boolean := True;
|
|
98 Index : Printer_ID := 1;
|
|
99 Print_Accepted : Boolean := False;
|
|
100 begin
|
|
101
|
|
102 loop
|
|
103 -- Wait for a printer to become available:
|
|
104
|
|
105 while Printers_Busy loop
|
|
106 Printers_Busy := False; -- Exit loop if
|
|
107 -- entry accepted.
|
|
108 select
|
|
109 Printer(Index).Done_Printing; -- Accepted immed.
|
|
110 -- when printer is
|
|
111 -- available.
|
|
112 else
|
|
113 Index := 1 + (Index mod Number_Of_Printers);-- Entry not immed.
|
|
114 Printers_Busy := True; -- accepted; keep
|
|
115 end select; -- looping.
|
|
116 end loop;
|
|
117 -- Value of Index
|
|
118 -- at loop exit
|
|
119 -- identifies the
|
|
120 -- avail. printer.
|
|
121
|
|
122 -- Wait for a print request or terminate:
|
|
123
|
|
124 select
|
|
125 accept Print (File_Name : String) do
|
|
126 Print_Accepted := True; -- Allow
|
|
127 -- Verify_Results
|
|
128 -- to be accepted.
|
|
129
|
|
130 Printer(Index).Start_Printing (File_Name); -- Begin printing on
|
|
131 -- the available
|
|
132 -- -- -- printer.
|
|
133 -- Requeue is tested here --
|
|
134 -- --
|
|
135 -- Requeue caller so
|
|
136 requeue Printer(Index).Done_Printing; -- server task free
|
|
137 -- to accept other
|
|
138 end Print; -- requests.
|
|
139 or
|
|
140 -- Guard ensures that Verify_Results cannot be accepted
|
|
141 -- until after Print has been accepted. This avoids a
|
|
142 -- race condition in the main program.
|
|
143
|
|
144 when Print_Accepted => accept Verify_Results; -- Artifice for
|
|
145 -- testing purposes.
|
|
146 or
|
|
147 terminate;
|
|
148 end select;
|
|
149
|
|
150 -- Allow other tasks to get control
|
|
151 delay ImpDef.Long_Minimum_Task_Switch;
|
|
152
|
|
153 end loop;
|
|
154
|
|
155 exception
|
|
156 when others =>
|
|
157 Report.Failed ("Exception raised in Printer_Server task");
|
|
158 end Printer_Server;
|
|
159
|
|
160
|
|
161 end C954A01_0;
|
|
162
|
|
163
|
|
164 --==================================================================--
|
|
165
|
|
166
|
|
167 with Report;
|
|
168 with ImpDef;
|
|
169
|
|
170 with F954A00; -- Printer device abstraction.
|
|
171 with C954A01_0; -- Printer server abstraction.
|
|
172
|
|
173 use C954A01_0;
|
|
174 use F954A00;
|
|
175
|
|
176 procedure C954A01 is
|
|
177
|
|
178 Long_Enough : constant Duration := ImpDef.Long_Switch_To_New_Task;
|
|
179
|
|
180 --==============================================--
|
|
181
|
|
182 task Print_Request; -- Send a print request.
|
|
183
|
|
184 task body Print_Request is
|
|
185 My_File : constant String := "MYFILE.DAT";
|
|
186 begin
|
|
187 Printer_Server.Print (My_File); -- Invoke requeue statement.
|
|
188 Report.Failed ("Task continued execution following entry call");
|
|
189 exception
|
|
190 when others =>
|
|
191 Report.Failed ("Exception raised in Print_Request task");
|
|
192 end Print_Request;
|
|
193
|
|
194 --==============================================--
|
|
195
|
|
196 begin -- Main program.
|
|
197
|
|
198 Report.Test ("C954A01", "Requeue without abort - check that the abort " &
|
|
199 "is deferred until after the rendezvous completes. (Task to PO)");
|
|
200
|
|
201 -- To pass this test, the following must be true:
|
|
202 --
|
|
203 -- (A) The abort of Print_Request is deferred until after the
|
|
204 -- Done_Printing entry body completes.
|
|
205 -- (B) Print_Request aborts after the Done_Printing entry call
|
|
206 -- completes.
|
|
207 --
|
|
208 -- Call the entry Verify_Results. The entry call will not be accepted
|
|
209 -- until after Print_Request has been requeued to Done_Printing.
|
|
210
|
|
211 Printer_Server.Verify_Results; -- Accepted after Print_Request is
|
|
212 -- requeued to Done_Printing.
|
|
213
|
|
214 -- Simulate an application which needs access to the printer within
|
|
215 -- a specified time, and which aborts the current printer job if time
|
|
216 -- runs out.
|
|
217
|
|
218 select
|
|
219 Printer(1).Done_Printing; -- Wait for printer to come free.
|
|
220 or
|
|
221 delay Long_Enough; -- Print job took too long.
|
|
222 abort Print_Request; -- Abort print job.
|
|
223 end select;
|
|
224
|
|
225 Printer_Server.Verify_Results; -- Abortion completion point: force
|
|
226 -- abort to complete (if it's going
|
|
227 -- to).
|
|
228
|
|
229 -- Verify that the Done_Printing entry body has not yet completed,
|
|
230 -- and thus that Print_Request has not been aborted.
|
|
231
|
|
232 if Printer(1).Is_Done then
|
|
233 Report.Failed ("Target entry of requeue executed prematurely");
|
|
234 elsif Print_Request'Terminated then
|
|
235 Report.Failed ("Caller was aborted before entry was complete");
|
|
236 else
|
|
237
|
|
238 Printer(1).Handle_Interrupt; -- Simulate a printer interrupt,
|
|
239 -- signaling that printing is
|
|
240 -- done.
|
|
241
|
|
242 -- The Done_Printing entry body will complete before the next protected
|
|
243 -- action is called (Printer(1).Is_Done). Verify (A) and (B): that the
|
|
244 -- Print_Request is aborted.
|
|
245
|
|
246 Printer_Server.Verify_Results; -- Abortion completion point: force
|
|
247 -- Print_Request abort to complete.
|
|
248
|
|
249 if not Printer(1).Is_Done then
|
|
250 Report.Failed ("Target entry of requeue did not complete");
|
|
251 end if;
|
|
252
|
|
253 if not Print_Request'Terminated then
|
|
254 Report.Failed ("Task not aborted following completion of entry call");
|
|
255 abort Print_Request; -- Try to kill hung task.
|
|
256 end if;
|
|
257
|
|
258 end if;
|
|
259
|
|
260 Report.Result;
|
|
261
|
|
262 end C954A01;
|