| -- 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; |