-- C940002.A
|
-- C940002.A
|
--
|
--
|
--
|
--
|
-- Grant of Unlimited Rights
|
-- Grant of Unlimited Rights
|
--
|
--
|
-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
|
-- 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
|
-- 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 in the software and documentation contained herein.
|
-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
|
-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
|
-- this public release, the Government intends to confer upon all
|
-- this public release, the Government intends to confer upon all
|
-- recipients unlimited rights equal to those held by the Government.
|
-- recipients unlimited rights equal to those held by the Government.
|
-- These rights include rights to use, duplicate, release or disclose the
|
-- These rights include rights to use, duplicate, release or disclose the
|
-- released technical data and computer software in whole or in part, in
|
-- 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
|
-- any manner and for any purpose whatsoever, and to have or permit others
|
-- to do so.
|
-- to do so.
|
--
|
--
|
-- DISCLAIMER
|
-- DISCLAIMER
|
--
|
--
|
-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
|
-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
|
-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
|
-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
|
-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
|
-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
|
-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
|
-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
|
-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
|
-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
|
-- PARTICULAR PURPOSE OF SAID MATERIAL.
|
-- PARTICULAR PURPOSE OF SAID MATERIAL.
|
--*
|
--*
|
--
|
--
|
-- OBJECTIVE:
|
-- OBJECTIVE:
|
-- Check that a protected object provides coordinated access to shared
|
-- Check that a protected object provides coordinated access to shared
|
-- data. Check that it can implement a semaphore-like construct using a
|
-- data. Check that it can implement a semaphore-like construct using a
|
-- parameterless procedure which allows a specific maximum number of tasks
|
-- parameterless procedure which allows a specific maximum number of tasks
|
-- to run and excludes all others
|
-- to run and excludes all others
|
--
|
--
|
-- TEST DESCRIPTION:
|
-- TEST DESCRIPTION:
|
-- Implement a counting semaphore type that can be initialized to a
|
-- Implement a counting semaphore type that can be initialized to a
|
-- specific number of available resources. Declare an entry for
|
-- specific number of available resources. Declare an entry for
|
-- requesting a resource and a procedure for releasing it. Declare an
|
-- requesting a resource and a procedure for releasing it. Declare an
|
-- object of this type, initialized to two resources. Declare and start
|
-- object of this type, initialized to two resources. Declare and start
|
-- three tasks each of which asks for a resource. Verify that only two
|
-- three tasks each of which asks for a resource. Verify that only two
|
-- resources are granted and that the last task in is queued.
|
-- resources are granted and that the last task in is queued.
|
--
|
--
|
--
|
--
|
-- CHANGE HISTORY:
|
-- CHANGE HISTORY:
|
-- 06 Dec 94 SAIC ACVC 2.0
|
-- 06 Dec 94 SAIC ACVC 2.0
|
--
|
--
|
--!
|
--!
|
|
|
|
|
package C940002_0 is
|
package C940002_0 is
|
-- Semaphores
|
-- Semaphores
|
|
|
protected type Semaphore_Type (Resources_Available : Integer :=1) is
|
protected type Semaphore_Type (Resources_Available : Integer :=1) is
|
entry Request;
|
entry Request;
|
procedure Release;
|
procedure Release;
|
function Available return Integer;
|
function Available return Integer;
|
private
|
private
|
Currently_Available : Integer := Resources_Available;
|
Currently_Available : Integer := Resources_Available;
|
end Semaphore_Type;
|
end Semaphore_Type;
|
|
|
Max_Resources : constant Integer := 2;
|
Max_Resources : constant Integer := 2;
|
Resource : Semaphore_Type (Max_Resources);
|
Resource : Semaphore_Type (Max_Resources);
|
|
|
end C940002_0;
|
end C940002_0;
|
-- Semaphores;
|
-- Semaphores;
|
|
|
|
|
--========================================================--
|
--========================================================--
|
|
|
|
|
package body C940002_0 is
|
package body C940002_0 is
|
-- Semaphores
|
-- Semaphores
|
|
|
protected body Semaphore_Type is
|
protected body Semaphore_Type is
|
|
|
entry Request when Currently_Available >0 is -- when granted, secures
|
entry Request when Currently_Available >0 is -- when granted, secures
|
begin -- a resource
|
begin -- a resource
|
Currently_Available := Currently_Available - 1;
|
Currently_Available := Currently_Available - 1;
|
end Request;
|
end Request;
|
|
|
procedure Release is -- when called, releases
|
procedure Release is -- when called, releases
|
begin -- a resource
|
begin -- a resource
|
Currently_Available := Currently_Available + 1;
|
Currently_Available := Currently_Available + 1;
|
end Release;
|
end Release;
|
|
|
function Available return Integer is -- returns number of
|
function Available return Integer is -- returns number of
|
begin -- available resources
|
begin -- available resources
|
return Currently_Available;
|
return Currently_Available;
|
end Available;
|
end Available;
|
|
|
end Semaphore_Type;
|
end Semaphore_Type;
|
|
|
end C940002_0;
|
end C940002_0;
|
-- Semaphores;
|
-- Semaphores;
|
|
|
|
|
--========================================================--
|
--========================================================--
|
|
|
|
|
package C940002_1 is
|
package C940002_1 is
|
-- Task_Pkg
|
-- Task_Pkg
|
|
|
task type Requesting_Task is
|
task type Requesting_Task is
|
entry Done; -- call on Done instructs the task
|
entry Done; -- call on Done instructs the task
|
end Requesting_Task; -- to release resource
|
end Requesting_Task; -- to release resource
|
|
|
type Task_Ptr is access Requesting_Task;
|
type Task_Ptr is access Requesting_Task;
|
|
|
protected Counter is
|
protected Counter is
|
procedure Increment;
|
procedure Increment;
|
procedure Decrement;
|
procedure Decrement;
|
function Number return integer;
|
function Number return integer;
|
private
|
private
|
Count : Integer := 0;
|
Count : Integer := 0;
|
end Counter;
|
end Counter;
|
|
|
protected Hold_Lock is
|
protected Hold_Lock is
|
procedure Lock;
|
procedure Lock;
|
procedure Unlock;
|
procedure Unlock;
|
function Locked return Boolean;
|
function Locked return Boolean;
|
private
|
private
|
Lock_State : Boolean := true; -- starts out locked
|
Lock_State : Boolean := true; -- starts out locked
|
end Hold_Lock;
|
end Hold_Lock;
|
|
|
|
|
end C940002_1;
|
end C940002_1;
|
-- Task_Pkg
|
-- Task_Pkg
|
|
|
|
|
--========================================================--
|
--========================================================--
|
|
|
|
|
with Report;
|
with Report;
|
with C940002_0;
|
with C940002_0;
|
-- Semaphores;
|
-- Semaphores;
|
|
|
package body C940002_1 is
|
package body C940002_1 is
|
-- Task_Pkg is
|
-- Task_Pkg is
|
|
|
protected body Counter is
|
protected body Counter is
|
|
|
procedure Increment is
|
procedure Increment is
|
begin
|
begin
|
Count := Count + 1;
|
Count := Count + 1;
|
end Increment;
|
end Increment;
|
|
|
procedure Decrement is
|
procedure Decrement is
|
begin
|
begin
|
Count := Count - 1;
|
Count := Count - 1;
|
end Decrement;
|
end Decrement;
|
|
|
function Number return Integer is
|
function Number return Integer is
|
begin
|
begin
|
return Count;
|
return Count;
|
end Number;
|
end Number;
|
|
|
end Counter;
|
end Counter;
|
|
|
|
|
protected body Hold_Lock is
|
protected body Hold_Lock is
|
|
|
procedure Lock is
|
procedure Lock is
|
begin
|
begin
|
Lock_State := true;
|
Lock_State := true;
|
end Lock;
|
end Lock;
|
|
|
procedure Unlock is
|
procedure Unlock is
|
begin
|
begin
|
Lock_State := false;
|
Lock_State := false;
|
end Unlock;
|
end Unlock;
|
|
|
function Locked return Boolean is
|
function Locked return Boolean is
|
begin
|
begin
|
return Lock_State;
|
return Lock_State;
|
end Locked;
|
end Locked;
|
|
|
end Hold_Lock;
|
end Hold_Lock;
|
|
|
|
|
task body Requesting_Task is
|
task body Requesting_Task is
|
begin
|
begin
|
C940002_0.Resource.Request; -- request a resource
|
C940002_0.Resource.Request; -- request a resource
|
-- if resource is not available,
|
-- if resource is not available,
|
-- task will be queued to wait
|
-- task will be queued to wait
|
Counter.Increment; -- add to count of resources obtained
|
Counter.Increment; -- add to count of resources obtained
|
Hold_Lock.Unlock; -- and unlock Lock - system is stable;
|
Hold_Lock.Unlock; -- and unlock Lock - system is stable;
|
-- status may now be queried
|
-- status may now be queried
|
|
|
accept Done do -- hold resource until Done is called
|
accept Done do -- hold resource until Done is called
|
C940002_0.Resource.Release; -- release the resource and
|
C940002_0.Resource.Release; -- release the resource and
|
Counter.Decrement; -- note release
|
Counter.Decrement; -- note release
|
end Done;
|
end Done;
|
|
|
exception
|
exception
|
when others => Report.Failed ("Unexpected Exception in Requesting_Task");
|
when others => Report.Failed ("Unexpected Exception in Requesting_Task");
|
end Requesting_Task;
|
end Requesting_Task;
|
|
|
end C940002_1;
|
end C940002_1;
|
-- Task_Pkg;
|
-- Task_Pkg;
|
|
|
|
|
--========================================================--
|
--========================================================--
|
|
|
|
|
with Report;
|
with Report;
|
with ImpDef;
|
with ImpDef;
|
with C940002_0,
|
with C940002_0,
|
-- Semaphores,
|
-- Semaphores,
|
C940002_1;
|
C940002_1;
|
-- Task_Pkg;
|
-- Task_Pkg;
|
|
|
procedure C940002 is
|
procedure C940002 is
|
|
|
package Semaphores renames C940002_0;
|
package Semaphores renames C940002_0;
|
package Task_Pkg renames C940002_1;
|
package Task_Pkg renames C940002_1;
|
|
|
Ptr1,
|
Ptr1,
|
Ptr2,
|
Ptr2,
|
Ptr3 : Task_Pkg.Task_Ptr;
|
Ptr3 : Task_Pkg.Task_Ptr;
|
Num : Integer;
|
Num : Integer;
|
|
|
procedure Spinlock is
|
procedure Spinlock is
|
begin
|
begin
|
-- loop until unlocked
|
-- loop until unlocked
|
while Task_Pkg.Hold_Lock.Locked loop
|
while Task_Pkg.Hold_Lock.Locked loop
|
delay ImpDef.Minimum_Task_Switch;
|
delay ImpDef.Minimum_Task_Switch;
|
end loop;
|
end loop;
|
Task_Pkg.Hold_Lock.Lock;
|
Task_Pkg.Hold_Lock.Lock;
|
end Spinlock;
|
end Spinlock;
|
|
|
begin
|
begin
|
|
|
Report.Test ("C940002", "Check that a protected record can be used to " &
|
Report.Test ("C940002", "Check that a protected record can be used to " &
|
"control access to resources");
|
"control access to resources");
|
|
|
if (Task_Pkg.Counter.Number /=0)
|
if (Task_Pkg.Counter.Number /=0)
|
or (Semaphores.Resource.Available /= 2) then
|
or (Semaphores.Resource.Available /= 2) then
|
Report.Failed ("Wrong initial conditions");
|
Report.Failed ("Wrong initial conditions");
|
end if;
|
end if;
|
|
|
Ptr1 := new Task_Pkg.Requesting_Task; -- newly allocated task requests
|
Ptr1 := new Task_Pkg.Requesting_Task; -- newly allocated task requests
|
-- resource; request for resource should
|
-- resource; request for resource should
|
-- be granted
|
-- be granted
|
Spinlock; -- ensure that task obtains resource
|
Spinlock; -- ensure that task obtains resource
|
|
|
-- Task 1 waiting for call to Done
|
-- Task 1 waiting for call to Done
|
-- One resource assigned to task 1
|
-- One resource assigned to task 1
|
-- One resource still available
|
-- One resource still available
|
if (Task_Pkg.Counter.Number /= 1)
|
if (Task_Pkg.Counter.Number /= 1)
|
or (Semaphores.Resource.Available /= 1) then
|
or (Semaphores.Resource.Available /= 1) then
|
Report.Failed ("Resource not assigned to task 1");
|
Report.Failed ("Resource not assigned to task 1");
|
end if;
|
end if;
|
|
|
Ptr2 := new Task_Pkg.Requesting_Task; -- newly allocated task requests
|
Ptr2 := new Task_Pkg.Requesting_Task; -- newly allocated task requests
|
-- resource; request for resource should
|
-- resource; request for resource should
|
-- be granted
|
-- be granted
|
Spinlock; -- ensure that task obtains resource
|
Spinlock; -- ensure that task obtains resource
|
|
|
-- Task 1 waiting for call to Done
|
-- Task 1 waiting for call to Done
|
-- Task 2 waiting for call to Done
|
-- Task 2 waiting for call to Done
|
-- Resources held by tasks 1 and 2
|
-- Resources held by tasks 1 and 2
|
-- No resources available
|
-- No resources available
|
if (Task_Pkg.Counter.Number /= 2)
|
if (Task_Pkg.Counter.Number /= 2)
|
or (Semaphores.Resource.Available /= 0) then
|
or (Semaphores.Resource.Available /= 0) then
|
Report.Failed ("Resource not assigned to task 2");
|
Report.Failed ("Resource not assigned to task 2");
|
end if;
|
end if;
|
|
|
Ptr3 := new Task_Pkg.Requesting_Task; -- newly allocated task requests
|
Ptr3 := new Task_Pkg.Requesting_Task; -- newly allocated task requests
|
-- resource; request for resource should
|
-- resource; request for resource should
|
-- be denied and task queued to wait for
|
-- be denied and task queued to wait for
|
-- next available resource
|
-- next available resource
|
|
|
|
|
Ptr1.all.Done; -- Task 1 releases resource and lock
|
Ptr1.all.Done; -- Task 1 releases resource and lock
|
-- Resource should be given to queued task
|
-- Resource should be given to queued task
|
Spinlock; -- ensure that resource is released
|
Spinlock; -- ensure that resource is released
|
|
|
|
|
-- Task 1 holds no resource
|
-- Task 1 holds no resource
|
-- One resource still assigned to task 2
|
-- One resource still assigned to task 2
|
-- One resource assigned to task 3
|
-- One resource assigned to task 3
|
-- No resources available
|
-- No resources available
|
if (Task_Pkg.Counter.Number /= 2)
|
if (Task_Pkg.Counter.Number /= 2)
|
or (Semaphores.Resource.Available /= 0) then
|
or (Semaphores.Resource.Available /= 0) then
|
Report.Failed ("Resource not properly released/assigned to task 3");
|
Report.Failed ("Resource not properly released/assigned to task 3");
|
end if;
|
end if;
|
|
|
Ptr2.all.Done; -- Task 2 releases resource and lock
|
Ptr2.all.Done; -- Task 2 releases resource and lock
|
-- No outstanding request for resource
|
-- No outstanding request for resource
|
|
|
-- Tasks 1 and 2 hold no resources
|
-- Tasks 1 and 2 hold no resources
|
-- One resource assigned to task 3
|
-- One resource assigned to task 3
|
-- One resource available
|
-- One resource available
|
if (Task_Pkg.Counter.Number /= 1)
|
if (Task_Pkg.Counter.Number /= 1)
|
or (Semaphores.Resource.Available /= 1) then
|
or (Semaphores.Resource.Available /= 1) then
|
Report.Failed ("Resource not properly released from task 2");
|
Report.Failed ("Resource not properly released from task 2");
|
end if;
|
end if;
|
|
|
Ptr3.all.Done; -- Task 3 releases resource and lock
|
Ptr3.all.Done; -- Task 3 releases resource and lock
|
|
|
-- All resources released
|
-- All resources released
|
-- All tasks terminated (or close)
|
-- All tasks terminated (or close)
|
-- Two resources available
|
-- Two resources available
|
if (Task_Pkg.Counter.Number /=0)
|
if (Task_Pkg.Counter.Number /=0)
|
or (Semaphores.Resource.Available /= 2) then
|
or (Semaphores.Resource.Available /= 2) then
|
Report.Failed ("Resource not properly released from task 3");
|
Report.Failed ("Resource not properly released from task 3");
|
end if;
|
end if;
|
|
|
Report.Result;
|
Report.Result;
|
|
|
end C940002;
|
end C940002;
|
|
|