OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [ada/] [acats/] [tests/] [c9/] [c954014.a] - Blame information for rev 720

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 720 jeremybenn
-- C954014.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 a requeue is not canceled and that the requeueing
28
--     task is unaffected when a calling task is aborted. Check that the
29
--     abort is deferred until the entry call is complete.
30
--     Specifically, check requeue to an entry in a different task,
31
--     requeue where the entry call has parameters, and requeue
32
--     without the abort option.
33
--
34
-- TEST DESCRIPTION
35
--     In the Driver create a task that places a call on the
36
--     Distributor.  In the Distributor requeue this call on the Credit task.
37
--     Abort the calling task when it is known to be in rendezvous with the
38
--     Credit task. (We arrange this by using artificial synchronization
39
--     points in the Driver and the accept body of the Credit task) Ensure
40
--     that the abort is deferred (the task is not terminated) until the
41
--     accept body completes.   Afterwards, send one extra message through
42
--     the Distributor to check that the requeueing task has not been
43
--     disrupted.
44
--
45
--     This series of tests uses a simulation of a transaction driven
46
--     processing system.  Line Drivers accept input from an external source
47
--     and build them into transaction records.  These records are then
48
--     encapsulated in message tasks which remain extant for the life of the
49
--     transaction in the system.  The message tasks put themselves on the
50
--     input queue of a Distributor which, from information in the
51
--     transaction and/or system load conditions forwards them to other
52
--     operating tasks. These in turn might forward the transactions to yet
53
--     other tasks for further action.  The routing is, in real life, dynamic
54
--     and unpredictable at the time of message generation.  All rerouting in
55
--     this  model is done by means of requeues.
56
--
57
--
58
-- CHANGE HISTORY:
59
--      06 Dec 94   SAIC    ACVC 2.0
60
--      25 Nov 95   SAIC    Replaced global variables with protected objects
61
--                          for ACVC 2.0.1.
62
--
63
--!
64
 
65
with Report;
66
with ImpDef;
67
 
68
procedure C954014 is
69
 
70
   -- Arbitrary test values
71
   Credit_Return : constant := 1;
72
   Debit_Return  : constant := 2;
73
 
74
 
75
   protected type Shared_Boolean (Initial_Value : Boolean := False) is
76
      procedure Set_True;
77
      procedure Set_False;
78
      function  Value return Boolean;
79
   private
80
      Current_Value : Boolean := Initial_Value;
81
   end Shared_Boolean;
82
 
83
   protected body Shared_Boolean is
84
      procedure Set_True is
85
      begin
86
         Current_Value := True;
87
      end Set_True;
88
 
89
      procedure Set_False is
90
      begin
91
         Current_Value := False;
92
      end Set_False;
93
 
94
      function Value return Boolean is
95
      begin
96
         return Current_Value;
97
      end Value;
98
   end Shared_Boolean;
99
 
100
 
101
   TC_Debit_Message_Complete  : Shared_Boolean (False);
102
 
103
   -- Synchronization flags for handshaking between the Line_Driver
104
   -- and the Accept body in the Credit Task
105
   TC_Handshake_A : Shared_Boolean (False);
106
   TC_Handshake_B : Shared_Boolean (False);
107
   TC_Handshake_C : Shared_Boolean (False);
108
   TC_Handshake_D : Shared_Boolean (False);
109
   TC_Handshake_E : Shared_Boolean (False);
110
   TC_Handshake_F : Shared_Boolean (False);
111
 
112
 
113
   type Transaction_Code is (Credit, Debit);
114
 
115
   type Transaction_Record;
116
   type acc_Transaction_Record is access Transaction_Record;
117
   type Transaction_Record is
118
      record
119
         ID               : integer := 0;
120
         Code             : Transaction_Code := Debit;
121
         Account_Number   : integer := 0;
122
         Stock_Number     : integer := 0;
123
         Quantity         : integer := 0;
124
         Return_Value     : integer := 0;
125
         TC_Message_Count : integer := 0;
126
         TC_Thru_Distrib  : Boolean;
127
      end record;
128
 
129
 
130
   task type Message_Task is
131
      entry Accept_Transaction (In_Transaction : acc_Transaction_Record);
132
   end Message_Task;
133
   type acc_Message_Task is access Message_Task;
134
 
135
   task Line_Driver is
136
      entry start;
137
   end Line_Driver;
138
 
139
   task Distributor is
140
      entry Input(Transaction : acc_Transaction_Record);
141
   end Distributor;
142
 
143
   task Credit_Computation is
144
      entry Input(Transaction : acc_Transaction_Record);
145
   end Credit_Computation;
146
 
147
   task Debit_Computation is
148
      entry Input(Transaction : acc_Transaction_Record);
149
   end Debit_Computation;
150
 
151
 
152
   -- Assemble messages received from an external source
153
   --   Creates a message task for each. The message tasks remain extant
154
   --   for the life of the messages in the system.
155
   --      TC: The Line Driver task would normally be designed to loop
156
   --      continuously creating the messages as input is received.  Simulate
157
   --      this  but limit it to two dummy messages for this test and use
158
   --      special artificial handshaking checks with the Credit accept body
159
   --      to control the test. Allow it to terminate at the end
160
   --
161
   task body Line_Driver is
162
      Current_ID : integer := 1;
163
      TC_First_message_sent: Boolean := false;
164
 
165
      procedure Build_Credit_Record
166
                              ( Next_Transaction : acc_Transaction_Record ) is
167
         Dummy_Account : constant integer := 100;
168
      begin
169
            Next_Transaction.ID := Current_ID;
170
            Next_Transaction.Code := Credit;
171
 
172
            Next_Transaction.Account_Number := Dummy_Account;
173
            Current_ID := Current_ID + 1;
174
      end Build_Credit_Record;
175
 
176
 
177
      procedure Build_Debit_Record
178
                              ( Next_Transaction : acc_Transaction_Record ) is
179
         Dummy_Account : constant integer := 200;
180
      begin
181
            Next_Transaction.ID := Current_ID;
182
            Next_Transaction.Code := Debit;
183
 
184
            Next_Transaction.Account_Number := Dummy_Account;
185
            Current_ID := Current_ID + 1;
186
      end Build_Debit_Record;
187
 
188
   begin
189
 
190
      accept Start;       -- Wait for trigger from main
191
 
192
      for i in 1..2 loop  -- TC: arbitrarily limit to one credit message
193
                          --     and one debit, then complete
194
         declare
195
            -- Create a task for the next message
196
            Next_Message_Task : acc_Message_Task := new Message_Task;
197
            -- Create a record for it
198
            Next_Transaction : acc_Transaction_Record :=
199
                                                   new Transaction_Record;
200
         begin
201
            if not TC_First_Message_Sent then
202
               -- send out the first message which will be aborted
203
               Build_Credit_Record ( Next_Transaction );
204
               Next_Message_Task.Accept_Transaction ( Next_Transaction );
205
               TC_First_Message_Sent := true;
206
 
207
               -- Wait for Credit task to get into the accept body
208
               --   The call from the Message Task has been requeued by
209
               --   the distributor
210
               while not TC_Handshake_A.Value loop
211
                  delay ImpDef.Minimum_Task_Switch;
212
               end loop;
213
 
214
               -- Abort the calling task; the Credit task is guaranteed to
215
               -- be in the accept body
216
               abort Next_Message_Task.all;     -- We are still in this declare
217
                                                -- block
218
 
219
               -- Inform the Credit task that the abort has been initiated
220
               TC_Handshake_B.Set_True;
221
 
222
               -- Now wait for the "acknowledgment" from the Credit task
223
               -- this ensures a complete task switch (at least)
224
               while not TC_Handshake_C.Value loop
225
                  delay ImpDef.Minimum_Task_Switch;
226
               end loop;
227
 
228
               -- The aborted task must not terminate till the accept body
229
               -- has completed
230
               if Next_Message_Task'terminated then
231
                  Report.Failed ("The abort was not deferred");
232
               end if;
233
 
234
               -- Inform the Credit task that the termination has been checked
235
               TC_Handshake_D.Set_True;
236
 
237
               -- Now wait for the completion of the accept body in the
238
               -- Credit task
239
               while not TC_Handshake_E.Value loop
240
                  delay ImpDef.Minimum_Task_Switch;
241
               end loop;
242
 
243
               while not ( Next_Message_Task'terminated ) loop
244
                  delay ImpDef.Minimum_Task_Switch;
245
               end loop;
246
 
247
               -- Indicate to the Main program that this section is complete
248
               TC_Handshake_F.Set_True;
249
 
250
            else
251
               -- The main part of the test is complete. Send one Debit message
252
               -- as further exercise of the Distributor to ensure it has not
253
               -- been affected by the abort of the requeue;
254
               Build_Debit_Record ( Next_Transaction );
255
               Next_Message_Task.Accept_Transaction ( Next_Transaction );
256
            end if;
257
         end;   -- declare
258
      end loop;
259
 
260
   exception
261
      when others =>
262
         Report.Failed ("Unexpected exception in Line_Driver");
263
   end Line_Driver;
264
 
265
 
266
 
267
   task body Message_Task is
268
 
269
      TC_Original_Transaction_Code : Transaction_Code;
270
      This_Transaction : acc_Transaction_Record := new Transaction_Record;
271
 
272
   begin
273
 
274
      accept Accept_Transaction (In_Transaction : acc_Transaction_Record) do
275
         This_Transaction.all := In_Transaction.all;
276
      end Accept_Transaction;
277
 
278
      -- Note the original code to ensure correct return
279
      TC_Original_Transaction_Code := This_Transaction.Code;
280
 
281
      -- Queue up on Distributor's Input queue
282
      Distributor.Input ( This_Transaction );
283
      -- This task will now wait for the requeued rendezvous
284
      -- to complete before proceeding
285
 
286
      -- After the required computations have been performed
287
      -- return the Transaction_Record appropriately (probably to an output
288
      -- line driver)
289
      null;            -- stub
290
 
291
      -- For the test check that the return values are as expected
292
      if TC_Original_Transaction_Code /= This_Transaction.Code then
293
         -- Incorrect rendezvous
294
         Report.Failed ("Message Task: Incorrect code returned");
295
      end if;
296
 
297
      if This_Transaction.Code = Credit then
298
         -- The only Credit message was the one that should have been aborted
299
         Report.Failed ("Abort was not effective");
300
      else
301
         if This_Transaction.Return_Value     /= Debit_Return or
302
            This_Transaction.TC_Message_Count /= 1            or not
303
            This_Transaction.TC_Thru_Distrib       then
304
               Report.Failed ("Expected path not traversed");
305
         end if;
306
         TC_Debit_Message_Complete.Set_True;
307
      end if;
308
 
309
   exception
310
      when others =>
311
         Report.Failed ("Unexpected exception in Message_Task");
312
 
313
   end Message_Task;
314
 
315
 
316
 
317
   -- Dispose each input Transaction_Record to the appropriate
318
   -- computation tasks
319
   --
320
   task body Distributor is
321
 
322
   begin
323
      loop
324
         select
325
            accept Input (Transaction : acc_Transaction_Record) do
326
 
327
               -- Indicate that the  message did pass through the
328
               -- Distributor Task
329
               Transaction.TC_Thru_Distrib := true;
330
 
331
               -- Pass this transaction on the appropriate computation
332
               -- task
333
               case Transaction.Code is
334
                  when Credit =>
335
                     requeue Credit_Computation.Input;   -- without abort
336
                  when Debit =>
337
                     requeue Debit_Computation.Input;    -- without abort
338
               end case;
339
            end Input;
340
         or
341
            terminate;
342
         end select;
343
      end loop;
344
 
345
   exception
346
      when others =>
347
         Report.Failed ("Unexpected exception in Distributor");
348
   end Distributor;
349
 
350
 
351
 
352
   -- Computation task.
353
   --   Note:  After the computation is performed in this task and the
354
   --          accept body is completed the rendezvous in the original
355
   --          message task is completed.
356
   task body Credit_Computation is
357
      Message_Count   : integer := 0;
358
   begin
359
      loop
360
         select
361
            accept Input ( Transaction : acc_Transaction_Record) do
362
               -- Perform the computations required for this transaction
363
               --
364
               null;     -- stub
365
 
366
               -- The rest of this code is for Test Control
367
               --
368
               if not Transaction.TC_Thru_Distrib then
369
                  Report.Failed
370
                         ("Credit Task: Wrong queue, Distributor bypassed");
371
               end if;
372
               if Transaction.code /= Credit then
373
                  Report.Failed
374
                         ("Credit Task: Requeue delivered to the wrong queue");
375
               end if;
376
 
377
               -- for the test plug a known value and count
378
               Transaction.Return_Value := Credit_Return;
379
               -- one, and only one message should pass through
380
               if Message_Count /= 0 then
381
                  Report.Failed ("Aborted Requeue was not canceled -1");
382
               end if;
383
               Message_Count := Message_Count + 1;
384
               Transaction.TC_Message_Count := Message_Count;
385
 
386
               -- Having done the basic housekeeping we now need to signal
387
               -- that we are in the accept body of the credit task.  The
388
               -- message has arrived and the Line Driver may now abort the
389
               -- calling task
390
               TC_Handshake_A.Set_True;
391
 
392
               -- Now wait for the Line Driver to inform us the calling
393
               -- task has been aborted
394
               while not TC_Handshake_B.Value loop
395
                  delay ImpDef.Minimum_Task_Switch;
396
               end loop;
397
 
398
               -- The abort has taken place
399
               -- Inform the Line Driver that we are still running in the
400
               -- accept body
401
               TC_Handshake_C.Set_True;
402
 
403
               -- Now wait for the Line Driver to digest this information
404
               while not TC_Handshake_D.Value loop
405
                  delay ImpDef.Minimum_Task_Switch;
406
               end loop;
407
 
408
               -- The Line driver has checked that the caller is not terminated
409
               -- We can now complete the accept
410
 
411
            end Input;
412
            -- We are out of the accept
413
            TC_Handshake_E.Set_True;
414
 
415
         or
416
            terminate;
417
         end select;
418
      end loop;
419
   exception
420
      when others =>
421
         Report.Failed ("Unexpected exception in Credit_Computation");
422
   end Credit_Computation;
423
 
424
 
425
 
426
   -- Computation task.
427
   --   Note:  After the computation is performed in this task and the
428
   --          accept body is completed the rendezvous in the original
429
   --          message task is completed.
430
   task body Debit_Computation is
431
      Message_Count   : integer := 0;
432
   begin
433
      loop
434
         select
435
            accept Input (Transaction : acc_Transaction_Record) do
436
               -- Perform the computations required for this message
437
               --
438
               null;      -- stub
439
 
440
               -- The rest of this code is for Test Control
441
               --
442
               if not Transaction.TC_Thru_Distrib then
443
                  Report.Failed
444
                         ("Debit Task: Wrong queue, Distributor bypassed");
445
               end if;
446
               if Transaction.code /= Debit then
447
                  Report.Failed
448
                         ("Debit Task: Requeue delivered to the wrong queue");
449
               end if;
450
 
451
               -- for the test plug a known value and count
452
               Transaction.Return_Value := Debit_Return;
453
               -- one, and only one, message should pass through
454
               Message_Count := Message_Count + 1;
455
               Transaction.TC_Message_Count := Message_Count;
456
            end Input;
457
         or
458
            terminate;
459
         end select;
460
      end loop;
461
   exception
462
      when others =>
463
         Report.Failed ("Unexpected exception in Debit_Computation");
464
 
465
 
466
   end Debit_Computation;
467
 
468
 
469
begin -- c954014
470
   Report.Test ("C954014", "Abort a task that has a call" &
471
                                          " requeued_without_abort");
472
 
473
   Line_Driver.Start;   -- Start the test
474
 
475
   -- Wait for the message tasks to complete before reporting the result
476
   --
477
   while not (TC_Handshake_F.Value                  -- abort not effective?
478
              and TC_Debit_Message_Complete.Value   -- Distributor affected?
479
              and TC_Handshake_E.Value ) loop       -- accept not completed?
480
      delay ImpDef.Minimum_Task_Switch;
481
   end loop;
482
 
483
   Report.Result;
484
 
485
end C954014;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.