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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 720 jeremybenn
-- C954019.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 when a requeue is to the same entry the items go to the
28
--      right queue and that they are placed back on the end of the queue.
29
--
30
-- TEST DESCRIPTION:
31
--      Simulate part of a message handling application where the messages are
32
--      composed of several segments.  The sequence of the segments within the
33
--      message is specified by Seg_Sequence_No.   The segments are handled by
34
--      different tasks  and finally forwarded to an output driver.  The
35
--      segments can arrive in any order but must be assembled into the proper
36
--      sequence for final output.  There is a Sequencer task interposed
37
--      before the Driver.  This takes the segments of the message off the
38
--      Ordering_Queue and those that are in the right order it sends on to
39
--      the driver; those that are out of order it places back on the end of
40
--      the queue.
41
--
42
--      The test just simulates the arrival of the segments at the Sequencer.
43
--      The task generating the segments handshakes with the Sequencer during
44
--      the  "Await Arrival" phase  ensuring that the three segments of a
45
--      message arrive in REVERSE order (the End-of-Message segment arrives
46
--      first and the Header last).  In the first cycle the sequencer pulls
47
--      segments off the queue and puts them back on the end till it
48
--      encounters the header.  It checks the sequence of the ones it pulls
49
--      off in case the segments are being put back on in the wrong part of
50
--      the queue. Having cycled once through it no longer verifies the
51
--      sequence - it just executes the "application" code for the correct
52
--      order for dispatch to the driver.
53
--
54
--      In this simple example no attempt is made to address segments of
55
--      another message arriving or any other error conditions (such as
56
--      missing segments, timing etc.)
57
--
58
--
59
-- CHANGE HISTORY:
60
--      06 Dec 94   SAIC    ACVC 2.0
61
--      19 Dec 94   SAIC    Remove parameter from requeue statement
62
--
63
--!
64
 
65
with Report;
66
with ImpDef;
67
 
68
procedure C954019 is
69
begin
70
 
71
 
72
   Report.Test ("C954019", "Check Requeue to the same Accept");
73
 
74
   declare  -- encapsulate the test
75
 
76
      type Segment_Sequence is range 1..8;
77
      Header : constant Segment_Sequence := Segment_Sequence'first;
78
 
79
      type Message_Segment is record
80
         ID              : integer;            -- Message ID
81
         Seg_Sequence_No : Segment_Sequence;   -- Within the message
82
         Alpha           : string (1..128);
83
         EOM             : Boolean := false;   -- true for final msg segment
84
      end record;
85
      type acc_Message_Segment is access Message_Segment;
86
 
87
      task TC_Simulate_Arrival;
88
 
89
      task type Carrier_Task is
90
         entry Input ( Segment : acc_Message_Segment );
91
      end Carrier_Task;
92
      type acc_Carrier_Task is access Carrier_Task;
93
 
94
      task Sequencer is
95
         entry Ordering_Queue ( Segment : acc_Message_Segment );
96
         entry TC_Handshake_1;
97
         entry TC_Handshake_2;
98
      end Sequencer;
99
 
100
      task Output_Driver is
101
         entry Input ( Segment : acc_Message_Segment );
102
      end Output_Driver;
103
 
104
 
105
      -- Simulate the arrival of three message segments in REVERSE order
106
      --
107
      task body TC_Simulate_Arrival is
108
         begin
109
 
110
            for i in 1..3 loop
111
               declare
112
                  -- Create a task for the next message segment
113
                  Next_Segment_Task : acc_Carrier_Task := new Carrier_Task;
114
                  -- Create a record for the next segment
115
                  Next_Segment : acc_Message_Segment := new Message_Segment;
116
               begin
117
                  if i = 1 then
118
                     -- Build the EOM segment as the first to "send"
119
                     Next_Segment.Seg_Sequence_No := Header + 2;
120
                     Next_Segment.EOM := true;
121
                  elsif i = 2 then
122
                     -- Wait for the first segment to arrive at the Sequencer
123
                     -- before "sending" the second
124
                     Sequencer.TC_Handshake_1;
125
                     -- Build the segment
126
                     Next_Segment.Seg_Sequence_No := Header + 1;
127
                  else
128
                     -- Wait for the second segment to arrive at the Sequencer
129
                     -- before "sending" the third
130
                     Sequencer.TC_Handshake_2;
131
                     -- Build the segment. The last segment in order to
132
                     -- arrive will be the "header" segment
133
                     Next_Segment.Seg_Sequence_No := Header;
134
                  end if;
135
                  -- pass the record to its carrier
136
                  Next_Segment_Task.Input ( Next_Segment );
137
               end;
138
            end loop;
139
      exception
140
         when others =>
141
              Report.Failed ("Unexpected Exception in TC_Simulate_Arrival");
142
      end TC_Simulate_Arrival;
143
 
144
 
145
      -- One of these is generated for each message segment and the flow
146
      -- of the segments through the system is controlled by the calls the
147
      -- task makes and the requeues of those calls
148
      --
149
      task body Carrier_Task is
150
         This_Segment : acc_Message_Segment := new Message_Segment;
151
      begin
152
         accept Input ( Segment : acc_Message_Segment ) do
153
            This_Segment.all := Segment.all;
154
         end Input;
155
         null; --:: stub.  Pass the segment around the application as needed
156
 
157
         -- Now output the segment to the Output_Driver.  First we have to
158
         -- go through the Sequencer.
159
         Sequencer.Ordering_Queue ( This_Segment );
160
      exception
161
         when others =>
162
              Report.Failed ("Unexpected Exception in Carrier_Task");
163
      end Carrier_Task;
164
 
165
 
166
      -- Pull segments off the Ordering_Queue and deliver them in the correct
167
      -- sequence to the Output_Driver.
168
      --
169
      task body Sequencer is
170
         Next_Needed : Segment_Sequence := Header;
171
 
172
         TC_Await_Arrival     : Boolean := true;
173
         TC_First_Cycle       : Boolean := true;
174
         TC_Expected_Sequence : Segment_Sequence := Header+2;
175
      begin
176
         loop
177
            select
178
               accept Ordering_Queue ( Segment : acc_Message_Segment ) do
179
 
180
                  --=====================================================
181
                  -- This part is all Test_Control code
182
 
183
                  if TC_Await_Arrival then
184
                     -- We have to arrange that the segments arrive on the
185
                     -- queue in the right order, so we handshake with the
186
                     -- TC_Simulate_Arrival task to "send" only one at
187
                     -- a time
188
                     accept TC_Handshake_1;   -- the first  has arrived
189
                                              -- and has been pulled off the
190
                                              -- queue
191
 
192
                     -- Wait for the second to arrive (the first has already
193
                     -- been pulled off the queue
194
                     while Ordering_Queue'count < 1 loop
195
                        delay ImpDef.Minimum_Task_Switch;
196
                     end loop;
197
                     --
198
                     accept TC_Handshake_2;   -- the second has arrived
199
 
200
                     -- Wait for the third to arrive
201
                     while Ordering_Queue'count < 2 loop
202
                        delay ImpDef.Minimum_Task_Switch;
203
                     end loop;
204
 
205
                     -- Subsequent passes through the loop, bypass this code
206
                     TC_Await_Arrival := false;
207
 
208
 
209
                  end if; -- await arrival
210
 
211
                  if TC_First_Cycle then
212
                     -- Check the order of the original three
213
                     if Segment.Seg_Sequence_No /= TC_Expected_Sequence then
214
                        -- The segments are not being pulled off in the
215
                        -- expected sequence.  This could occur if the
216
                        -- requeue is not putting them back on the end.
217
                        Report.Failed ("Sequencer: Segment out of sequence");
218
                     end if; -- sequence check
219
                     -- Decrement the expected sequence
220
                     if TC_Expected_Sequence /= Header then
221
                        TC_Expected_Sequence := TC_Expected_Sequence - 1;
222
                     else
223
                        TC_First_Cycle := false; -- This is the Header - the
224
                                                 -- first two segments are
225
                                                 -- back on the queue
226
 
227
                     end if; -- decrementing
228
                  end if; -- first pass
229
                  --=====================================================
230
 
231
                  -- And this is the Application code
232
                  if Segment.Seg_Sequence_No = Next_Needed then
233
                     if Segment.EOM then
234
                        Next_Needed := Header;  -- reset for next message
235
                     else
236
                        Next_Needed := Next_Needed + 1;
237
                     end if;
238
                     requeue Output_Driver.Input with abort;
239
                     Report.Failed ("Requeue did not complete accept body");
240
                  else
241
                     -- Not the next needed - put it back on the queue
242
                     requeue Sequencer.Ordering_Queue;
243
                     Report.Failed ("Requeue did not complete accept body");
244
                  end if;
245
               end Ordering_Queue;
246
            or
247
               terminate;
248
            end select;
249
         end loop;
250
      exception
251
         when others =>
252
              Report.Failed ("Unexpected Exception in Sequencer");
253
      end Sequencer;
254
 
255
 
256
      task body Output_Driver is
257
         This_Segment : acc_Message_Segment := new Message_Segment;
258
 
259
         TC_Expected_Sequence : Segment_Sequence := Segment_Sequence'first;
260
         TC_Segment_Total     : integer := 0;
261
         TC_Expected_Total    : integer := 3;
262
      begin
263
         loop
264
            -- Note: normally we would expect this Accept to be in a select
265
            -- with terminate.  For the test we exit the loop on completion
266
            -- to give better control
267
            accept Input ( Segment : acc_Message_Segment ) do
268
               This_Segment.all := Segment.all;
269
            end Input;
270
 
271
            null;  --::: stub - output the next segment of the message
272
 
273
            -- The following is all test control code
274
            --
275
            if This_Segment.Seg_Sequence_No /= TC_Expected_Sequence then
276
               Report.Failed ("Output_Driver: Segment out of sequence");
277
            end if;
278
            TC_Expected_Sequence := TC_Expected_Sequence + 1;
279
 
280
            -- Now count the number of segments
281
            TC_Segment_Total := TC_Segment_Total + 1;
282
 
283
            -- Check the number and exit loop when complete
284
            -- There must be exactly TC_Expected_Total in number and
285
            --    the last one must be EOM
286
            --    (test will hang if < TC_Expected_Total arrive
287
            --    without EOM)
288
            if This_Segment.EOM then
289
               -- This is the last segment.
290
               if TC_Segment_Total /= TC_Expected_Total then
291
                  Report.Failed ("EOM and wrong number of segments");
292
               end if;
293
               exit;   -- the loop and terminate the task
294
            elsif TC_Segment_Total = TC_Expected_Total then
295
               Report.Failed ("No EOM found");
296
               exit;
297
            end if;
298
         end loop;
299
      exception
300
         when others =>
301
              Report.Failed ("Unexpected Exception in Output_Driver");
302
      end Output_Driver;
303
 
304
 
305
 
306
   begin
307
 
308
      null;
309
 
310
   end; -- encapsulation
311
 
312
   Report.Result;
313
 
314
end C954019;

powered by: WebSVN 2.1.0

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