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 68package 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 81end C954A01_0; 82 83 84 --==================================================================-- 85 86 87with Report; 88with ImpDef; 89 90with F954A00; -- Printer device abstraction. 91use F954A00; 92pragma Elaborate(F954A00); 93 94package 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 161end C954A01_0; 162 163 164 --==================================================================-- 165 166 167with Report; 168with ImpDef; 169 170with F954A00; -- Printer device abstraction. 171with C954A01_0; -- Printer server abstraction. 172 173use C954A01_0; 174use F954A00; 175 176procedure 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 196begin -- 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 262end C954A01; 263