-- C940001.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 a protected object provides coordinated access to -- shared data. Check that it can be used to sequence a number of tasks. -- Use the protected object to control a single token for which three -- tasks compete. Check that only one task is running at a time and that -- all tasks get a chance to run sometime. -- -- TEST DESCRIPTION: -- Declare a protected type with two entries. A task may call the Take -- entry to get a token which allows it to continue processing. If it -- has the token, it may call the Give entry to return it. The tasks -- implement a discipline whereby only the task with the token may be -- active. The test does not require any specific order for the tasks -- to run. -- -- -- CHANGE HISTORY: -- 06 Dec 94 SAIC ACVC 2.0 -- 07 Jul 96 SAIC Fixed spelling nits. -- --! package C940001_0 is type Token_Type is private; True_Token : constant Token_Type; -- Create a deferred constant in order -- to provide a component init for the -- protected object protected type Token_Mgr_Prot_Unit is entry Take (T : out Token_Type); entry Give (T : in out Token_Type); private Token : Token_Type := True_Token; end Token_Mgr_Prot_Unit; function Init_Token return Token_Type; -- call to initialize an -- object of Token_Type function Token_Value (T : Token_Type) return Boolean; -- call to inspect the value of an -- object of Token_Type private type Token_Type is new boolean; True_Token : constant Token_Type := true; end C940001_0; --=================================================================-- package body C940001_0 is protected body Token_Mgr_Prot_Unit is entry Take (T : out Token_Type) when Token = true is begin -- Calling task will Take the token, so T := Token; -- check first that token_mgr owns the Token := false; -- token to give, then give it to caller end Take; entry Give (T : in out Token_Type) when Token = false is begin -- Calling task will Give the token back, if T = true then -- so first check that token_mgr does not Token := T; -- own the token, then check that the task has T := false; -- the token to give, then take it from the end if; -- task -- if caller does not own the token, then end Give; -- it falls out of the entry body with no end Token_Mgr_Prot_Unit; -- action function Init_Token return Token_Type is begin return false; end Init_Token; function Token_Value (T : Token_Type) return Boolean is begin return Boolean (T); end Token_Value; end C940001_0; --===============================================================-- with Report; with ImpDef; with C940001_0; procedure C940001 is type TC_Int_Type is range 0..2; -- range is very narrow so that erroneous execution may -- raise Constraint_Error type TC_Artifact_Type is record TC_Int : TC_Int_Type := 1; Number_of_Accesses : integer := 0; end record; TC_Artifact : TC_Artifact_Type; Sequence_Mgr : C940001_0.Token_Mgr_Prot_Unit; procedure Bump (Item : in out TC_Int_Type) is begin Item := Item + 1; exception when Constraint_Error => Report.Failed ("Incremented without corresponding decrement"); when others => Report.Failed ("Bump raised Unexpected Exception"); end Bump; procedure Decrement (Item : in out TC_Int_Type) is begin Item := Item - 1; exception when Constraint_Error => Report.Failed ("Decremented without corresponding increment"); when others => Report.Failed ("Decrement raised Unexpected Exception"); end Decrement; --==============-- task type Network_Node_Type; task body Network_Node_Type is Slot_for_Token : C940001_0.Token_Type := C940001_0.Init_Token; begin -- Ask for token - if request is not granted, task will be queued Sequence_Mgr.Take (Slot_for_Token); -- Task now has token and may perform its work --==========================-- -- in this case, the work is to ensure that the test results -- are the expected ones! --==========================-- Bump (TC_Artifact.TC_Int); -- increment when request is granted TC_Artifact.Number_Of_Accesses := TC_Artifact.Number_Of_Accesses + 1; if not C940001_0.Token_Value ( Slot_for_Token) then Report.Failed ("Incorrect results from entry Take"); end if; -- give a chance for other tasks to (incorrectly) run delay ImpDef.Minimum_Task_Switch; Decrement (TC_Artifact.TC_Int); -- prepare to return token -- Task has completed its work and will return token Sequence_Mgr.Give (Slot_for_Token); -- return token to sequence manager if c940001_0.Token_Value (Slot_for_Token) then Report.Failed ("Incorrect results from entry Give"); end if; exception when others => Report.Failed ("Unexpected exception raised in task"); end Network_Node_Type; --==============-- begin Report.Test ("C940001", "Check that a protected object can control " & "tasks by coordinating access to shared data"); declare Node_1, Node_2, Node_3 : Network_Node_Type; -- declare three tasks which will compete for -- a single token, managed by Sequence Manager begin -- tasks start null; end; -- wait for all tasks to terminate before reporting result if TC_Artifact.Number_of_Accesses /= 3 then Report.Failed ("Not all tasks got through"); end if; Report.Result; end C940001;