4 -- Grant of Unlimited Rights
6 -- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
7 -- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
8 -- unlimited rights in the software and documentation contained herein.
9 -- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
10 -- this public release, the Government intends to confer upon all
11 -- recipients unlimited rights equal to those held by the Government.
12 -- These rights include rights to use, duplicate, release or disclose the
13 -- released technical data and computer software in whole or in part, in
14 -- any manner and for any purpose whatsoever, and to have or permit others
19 -- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
20 -- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
21 -- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
22 -- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
23 -- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
24 -- PARTICULAR PURPOSE OF SAID MATERIAL.
28 -- Check that a protected object provides coordinated access to shared
29 -- data. Check that it can implement a semaphore-like construct using a
30 -- parameterless procedure which allows a specific maximum number of tasks
31 -- to run and excludes all others
34 -- Implement a counting semaphore type that can be initialized to a
35 -- specific number of available resources. Declare an entry for
36 -- requesting a resource and a procedure for releasing it. Declare an
37 -- object of this type, initialized to two resources. Declare and start
38 -- three tasks each of which asks for a resource. Verify that only two
39 -- resources are granted and that the last task in is queued.
43 -- 06 Dec 94 SAIC ACVC 2.0
51 protected type Semaphore_Type
(Resources_Available
: Integer :=1) is
54 function Available
return Integer;
56 Currently_Available
: Integer := Resources_Available
;
59 Max_Resources
: constant Integer := 2;
60 Resource
: Semaphore_Type
(Max_Resources
);
66 --========================================================--
69 package body C940002_0
is
72 protected body Semaphore_Type
is
74 entry Request
when Currently_Available
>0 is -- when granted, secures
76 Currently_Available
:= Currently_Available
- 1;
79 procedure Release
is -- when called, releases
81 Currently_Available
:= Currently_Available
+ 1;
84 function Available
return Integer is -- returns number of
85 begin -- available resources
86 return Currently_Available
;
95 --========================================================--
101 task type Requesting_Task
is
102 entry Done
; -- call on Done instructs the task
103 end Requesting_Task
; -- to release resource
105 type Task_Ptr
is access Requesting_Task
;
110 function Number
return integer;
112 Count
: Integer := 0;
115 protected Hold_Lock
is
118 function Locked
return Boolean;
120 Lock_State
: Boolean := true; -- starts out locked
128 --========================================================--
135 package body C940002_1
is
138 protected body Counter
is
140 procedure Increment
is
145 procedure Decrement
is
150 function Number
return Integer is
158 protected body Hold_Lock
is
170 function Locked
return Boolean is
178 task body Requesting_Task
is
180 C940002_0
.Resource
.Request
; -- request a resource
181 -- if resource is not available,
182 -- task will be queued to wait
183 Counter
.Increment
; -- add to count of resources obtained
184 Hold_Lock
.Unlock
; -- and unlock Lock - system is stable;
185 -- status may now be queried
187 accept Done
do -- hold resource until Done is called
188 C940002_0
.Resource
.Release
; -- release the resource and
189 Counter
.Decrement
; -- note release
193 when others => Report
.Failed
("Unexpected Exception in Requesting_Task");
200 --========================================================--
212 package Semaphores
renames C940002_0
;
213 package Task_Pkg
renames C940002_1
;
217 Ptr3
: Task_Pkg
.Task_Ptr
;
220 procedure Spinlock
is
222 -- loop until unlocked
223 while Task_Pkg
.Hold_Lock
.Locked
loop
224 delay ImpDef
.Minimum_Task_Switch
;
226 Task_Pkg
.Hold_Lock
.Lock
;
231 Report
.Test
("C940002", "Check that a protected record can be used to " &
232 "control access to resources");
234 if (Task_Pkg
.Counter
.Number
/=0)
235 or (Semaphores
.Resource
.Available
/= 2) then
236 Report
.Failed
("Wrong initial conditions");
239 Ptr1
:= new Task_Pkg
.Requesting_Task
; -- newly allocated task requests
240 -- resource; request for resource should
242 Spinlock
; -- ensure that task obtains resource
244 -- Task 1 waiting for call to Done
245 -- One resource assigned to task 1
246 -- One resource still available
247 if (Task_Pkg
.Counter
.Number
/= 1)
248 or (Semaphores
.Resource
.Available
/= 1) then
249 Report
.Failed
("Resource not assigned to task 1");
252 Ptr2
:= new Task_Pkg
.Requesting_Task
; -- newly allocated task requests
253 -- resource; request for resource should
255 Spinlock
; -- ensure that task obtains resource
257 -- Task 1 waiting for call to Done
258 -- Task 2 waiting for call to Done
259 -- Resources held by tasks 1 and 2
260 -- No resources available
261 if (Task_Pkg
.Counter
.Number
/= 2)
262 or (Semaphores
.Resource
.Available
/= 0) then
263 Report
.Failed
("Resource not assigned to task 2");
266 Ptr3
:= new Task_Pkg
.Requesting_Task
; -- newly allocated task requests
267 -- resource; request for resource should
268 -- be denied and task queued to wait for
269 -- next available resource
272 Ptr1
.all.Done
; -- Task 1 releases resource and lock
273 -- Resource should be given to queued task
274 Spinlock
; -- ensure that resource is released
277 -- Task 1 holds no resource
278 -- One resource still assigned to task 2
279 -- One resource assigned to task 3
280 -- No resources available
281 if (Task_Pkg
.Counter
.Number
/= 2)
282 or (Semaphores
.Resource
.Available
/= 0) then
283 Report
.Failed
("Resource not properly released/assigned to task 3");
286 Ptr2
.all.Done
; -- Task 2 releases resource and lock
287 -- No outstanding request for resource
289 -- Tasks 1 and 2 hold no resources
290 -- One resource assigned to task 3
291 -- One resource available
292 if (Task_Pkg
.Counter
.Number
/= 1)
293 or (Semaphores
.Resource
.Available
/= 1) then
294 Report
.Failed
("Resource not properly released from task 2");
297 Ptr3
.all.Done
; -- Task 3 releases resource and lock
299 -- All resources released
300 -- All tasks terminated (or close)
301 -- Two resources available
302 if (Task_Pkg
.Counter
.Number
/=0)
303 or (Semaphores
.Resource
.Available
/= 2) then
304 Report
.Failed
("Resource not properly released from task 3");