1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
-- C953002.A
--
-- Grant of Unlimited Rights
--
-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
-- unlimited rights in the software and documentation contained herein.
-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
-- this public release, the Government intends to confer upon all
-- recipients unlimited rights equal to those held by the Government.
-- These rights include rights to use, duplicate, release or disclose the
-- released technical data and computer software in whole or in part, in
-- any manner and for any purpose whatsoever, and to have or permit others
-- to do so.
--
-- DISCLAIMER
--
-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
-- PARTICULAR PURPOSE OF SAID MATERIAL.
--*
--
-- OBJECTIVE:
-- Check that the servicing of entry queues of a protected object
-- continues until there are no open entries with queued calls
-- and that this takes place as part of a single protected
-- operation.
--
-- TEST DESCRIPTION:
-- This test enqueues a bunch of tasks on the entries of the
-- protected object Main_PO. At the same time another bunch of
-- of tasks are queued on the single entry of protected object
-- Holding_Pen.
-- Once all the tasks have had time to block, the main procedure
-- opens all the entries for Main_PO by calling the
-- Start_Protected_Operation protected procedure. This should
-- process all the pending callers as part of a single protected
-- operation.
-- During this protected operation, the entries of Main_PO release
-- the tasks blocked on Holding_Pen by calling the protected
-- procedure Release.
-- Once released from Holding_Pen, the task immediately calls
-- an entry in Main_PO.
-- These new calls should not gain access to Main_PO until
-- the initial protected operation on that object completes.
-- The order in which the entry calls on Main_PO are taken is
-- recorded in a global array and checked after all the tasks
-- have terminated.
--
--
-- CHANGE HISTORY:
-- 25 OCT 95 SAIC ACVC 2.1
-- 15 JAN 95 SAIC Fixed deadlock problem.
--
--!
with Report;
procedure C953002 is
Verbose : constant Boolean := False;
Half_Tasks : constant := 15; -- how many tasks of each group
Max_Tasks : constant := Half_Tasks * 2; -- total number of tasks
Note_Order : array (1..Max_Tasks) of Integer := (1..Max_Tasks => 0);
Note_Cnt : Integer := 0;
begin
Report.Test ("C953002",
"Check that the servicing of entry queues handles all" &
" open entries as part of a single protected operation");
declare
task type Assault_PO is
entry Take_ID (Id : Integer);
end Assault_PO;
First_Wave : array (1 .. Half_Tasks) of Assault_PO;
Second_Wave : array (1 .. Half_Tasks) of Assault_PO;
protected Main_PO is
entry E0 (Who : Integer);
entry E1 (Who : Integer);
entry E2 (Who : Integer);
entry E3 (Who : Integer);
entry All_Present;
procedure Start_Protected_Operation;
private
Open : Boolean := False;
end Main_PO;
protected Holding_Pen is
-- Note that Release is called by tasks executing in
-- the protected object Main_PO.
entry Wait (Who : Integer);
entry All_Present;
procedure Release;
private
Open : Boolean := False;
end Holding_Pen;
protected body Main_PO is
procedure Start_Protected_Operation is
begin
Open := True;
-- at this point all the First_Wave tasks are
-- waiting at the entries and all of them should
-- be processed as part of the protected operation.
end Start_Protected_Operation;
entry All_Present when E0'Count + E1'Count + E2'Count + E3'Count =
Max_Tasks / 2 is
begin
null; -- all tasks are waiting
end All_Present;
entry E0 (Who : Integer) when Open is
begin
Holding_Pen.Release;
-- note the order in which entry calls are handled.
Note_Cnt := Note_Cnt + 1;
Note_Order (Note_Cnt) := Who;
end E0;
entry E1 (Who : Integer) when Open is
begin
Holding_Pen.Release;
Note_Cnt := Note_Cnt + 1;
Note_Order (Note_Cnt) := Who;
end E1;
entry E2 (Who : Integer) when Open is
begin
Holding_Pen.Release;
Note_Cnt := Note_Cnt + 1;
Note_Order (Note_Cnt) := Who;
end E2;
entry E3 (Who : Integer) when Open is
begin
Holding_Pen.Release;
Note_Cnt := Note_Cnt + 1;
Note_Order (Note_Cnt) := Who;
end E3;
end Main_PO;
protected body Holding_Pen is
procedure Release is
begin
Open := True;
end Release;
entry All_Present when Wait'Count = Max_Tasks / 2 is
begin
null; -- all tasks waiting
end All_Present;
entry Wait (Who : Integer) when Open is
begin
null; -- unblock the task
end Wait;
end Holding_Pen;
task body Assault_PO is
Me : Integer;
begin
accept Take_Id (Id : Integer) do
Me := Id;
end Take_Id;
if Me >= 200 then
Holding_Pen.Wait (Me);
end if;
case Me mod 4 is
when 0 => Main_PO.E0 (Me);
when 1 => Main_PO.E1 (Me);
when 2 => Main_PO.E2 (Me);
when 3 => Main_PO.E3 (Me);
when others => null; -- cant happen
end case;
if Verbose then
Report.Comment ("task" & Integer'Image (Me) &
" done");
end if;
exception
when others =>
Report.Failed ("exception in task");
end Assault_PO;
begin -- test encapsulation
for I in First_Wave'Range loop
First_Wave (I).Take_ID (100 + I);
end loop;
for I in Second_Wave'Range loop
Second_Wave (I).Take_ID (200 + I);
end loop;
-- let all the tasks get blocked
Main_PO.All_Present;
Holding_Pen.All_Present;
-- let the games begin
if Verbose then
Report.Comment ("starting protected operation");
end if;
Main_PO.Start_Protected_Operation;
-- wait for all the tasks to complete
if Verbose then
Report.Comment ("waiting for tasks to complete");
end if;
end;
-- make sure all tasks registered their order
if Note_Cnt /= Max_Tasks then
Report.Failed ("task registration count wrong. " &
Integer'Image (Note_Cnt));
end if;
-- check the order in which entries were handled.
-- all the 100 level items should be handled as part of the
-- first protected operation and thus should be completed
-- before any 200 level item.
if Verbose then
for I in 1..Max_Tasks loop
Report.Comment ("order" & Integer'Image (I) & " is" &
Integer'Image (Note_Order (I)));
end loop;
end if;
for I in 2 .. Max_Tasks loop
if Note_Order (I) < 200 and
Note_Order (I-1) >= 200 then
Report.Failed ("protected operation failure" &
Integer'Image (Note_Order (I-1)) &
Integer'Image (Note_Order (I)));
end if;
end loop;
Report.Result;
end C953002;
|