c940004.a
来自「linux下编程用 编译软件」· A 代码 · 共 417 行
A
417 行
-- C940004.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.--*---- TEST OBJECTIVE:-- Check that a protected record can be used to control access to-- resources (data internal to the protected record).---- TEST DESCRIPTION:-- Declare a resource descriptor tagged type. Extend the type and-- use the extended type in a protected data structure.-- Implement a binary semaphore type. Declare an entry for-- requesting a specific resource and an procedure for releasing the-- same resource. Declare an object of this (protected) type.-- Declare and start three tasks each of which asks for a resource-- when directed to. Verify that resources are properly allocated-- and deallocated.------ CHANGE HISTORY:---- 12 DEC 93 SAIC Initial PreRelease version-- 23 JUL 95 SAIC Second PreRelease version-- 16 OCT 95 SAIC ACVC 2.1-- 13 MAR 03 RLB Fixed race condition in test.----!package C940004_0 is-- Resource_Pkg type ID_Type is new Integer range 0..10; type User_Descriptor_Type is tagged record Id : ID_Type := 0; end record;end C940004_0; -- Resource_Pkg--============================---- no body for C940004_0--=============================--with C940004_0; -- Resource_Pkg-- This generic package implements a semaphore to control a single resourcegeneric type Generic_Record_Type is new C940004_0.User_Descriptor_Type with private;package C940004_1 is-- Generic_Semaphore_Pkg -- generic package extends the tagged formal generic -- type with some implementation relevant details, and -- it provides a semaphore with operations that work -- on that type type User_Rec_Type is new Generic_Record_Type with private; protected type Semaphore_Type is function TC_Count return Integer; entry Request (R : in out User_Rec_Type); procedure Release (R : in out User_Rec_Type); private In_Use : Boolean := false; end Semaphore_Type; function Has_Access (R : User_Rec_Type) return Boolean;private type User_Rec_Type is new Generic_Record_Type with record Access_To_Resource : boolean := false; end record;end C940004_1; -- Generic_Semaphore_Pkg--===================================================--package body C940004_1 is-- Generic_Semaphore_Pkg protected body Semaphore_Type is function TC_Count return Integer is begin return Request'Count; end TC_Count; entry Request (R : in out User_Rec_Type) when not In_Use is begin In_Use := true; R.Access_To_Resource := true; end Request; procedure Release (R : in out User_Rec_Type) is begin In_Use := false; R.Access_To_Resource := false; end Release; end Semaphore_Type; function Has_Access (R : User_Rec_Type) return Boolean is begin return R.Access_To_Resource; end Has_Access;end C940004_1; -- Generic_Semaphore_Pkg--=============================================--with Report;with C940004_0; -- Resource_Pkg,with C940004_1; -- Generic_Semaphore_Pkg;package C940004_2 is-- Printer_Mgr_Pkg -- Instantiate the generic to get code to manage a single printer; -- User processes contend for the printer, asking for it by a call -- to Request, and relinquishing it by a call to Release -- This package extends a tagged type to customize it for the printer -- in question, then it uses the type to instantiate the generic and -- declare a semaphore specific to the particular resource package Resource_Pkg renames C940004_0; type User_Desc_Type is new Resource_Pkg.User_Descriptor_Type with record New_Details : Integer := 0; -- for example end record; package Instantiation is new C940004_1 -- Generic_Semaphore_Pkg (Generic_Record_Type => User_Desc_Type); Printer_Access_Mgr : Instantiation.Semaphore_Type;end C940004_2; -- Printer_Mgr_Pkg--============================---- no body for C940004_2--============================--with C940004_0; -- Resource_Pkg,with C940004_2; -- Printer_Mgr_Pkg;package C940004_3 is-- User_Task_Pkg-- This package models user tasks that will request and release-- the printer package Resource_Pkg renames C940004_0; package Printer_Mgr_Pkg renames C940004_2; task type User_Task_Type (ID : Resource_Pkg.ID_Type) is entry Get_Printer; -- instructs task to request resource entry Release_Printer -- instructs task to release printer (Descriptor : in out Printer_Mgr_pkg.Instantiation.User_Rec_Type); --==================-- -- Test management machinery --==================-- entry TC_Get_Descriptor -- returns descriptor (Descriptor : out Printer_Mgr_Pkg.Instantiation.User_Rec_Type); end User_Task_Type; --==================-- -- Test management machinery --==================-- TC_Times_Obtained : Integer := 0; TC_Times_Released : Integer := 0;end C940004_3; -- User_Task_Pkg;--==============================================--with Report;with C940004_0; -- Resource_Pkg,with C940004_2; -- Printer_Mgr_Pkg,package body C940004_3 is-- User_Task_Pkg task body User_Task_Type is D : Printer_Mgr_Pkg.Instantiation.User_Rec_Type; begin D.Id := ID; ----------------------------------- Main: loop select accept Get_Printer; Printer_Mgr_Pkg.Printer_Access_Mgr.Request (D); -- request resource; if resource is not available, -- task will be queued to wait --===================-- -- Test management machinery --===================-- TC_Times_Obtained := TC_Times_Obtained + 1; -- when request granted, note it and post a message or accept Release_Printer (Descriptor : in out Printer_Mgr_Pkg.Instantiation.User_Rec_Type) do Printer_Mgr_Pkg.Printer_Access_Mgr.Release (D); -- release the resource, note its release TC_Times_Released := TC_Times_Released + 1; Descriptor := D; end Release_Printer; exit Main; or accept TC_Get_Descriptor (Descriptor : out Printer_Mgr_Pkg.Instantiation.User_Rec_Type) do Descriptor := D; end TC_Get_Descriptor; end select; end loop main; exception when others => Report.Failed ("exception raised in User_Task"); end User_Task_Type;end C940004_3; -- User_Task_Pkg;--==========================================================--with Report;with ImpDef;with C940004_0; -- Resource_Pkg,with C940004_2; -- Printer_Mgr_Pkg,with C940004_3; -- User_Task_Pkg;procedure C940004 is Verbose : constant Boolean := False; package Resource_Pkg renames C940004_0; package Printer_Mgr_Pkg renames C940004_2; package User_Task_Pkg renames C940004_3; Task1 : User_Task_Pkg.User_Task_Type (1); Task2 : User_Task_Pkg.User_Task_Type (2); Task3 : User_Task_Pkg.User_Task_Type (3); User_Rec_1, User_Rec_2, User_Rec_3 : Printer_Mgr_Pkg.Instantiation.User_Rec_Type;begin Report.Test ("C940004", "Check that a protected record can be used to " & "control access to resources"); if (User_Task_Pkg.TC_Times_Obtained /= 0) or (User_Task_Pkg.TC_Times_Released /= 0) or Printer_Mgr_Pkg.Instantiation.Has_Access (User_Rec_1) or Printer_Mgr_Pkg.Instantiation.Has_Access (User_Rec_2) or Printer_Mgr_Pkg.Instantiation.Has_Access (User_Rec_3) then Report.Failed ("Wrong initial conditions"); end if; Task1.Get_Printer; -- ask for resource -- request for resource should be granted Task1.TC_Get_Descriptor (User_Rec_1);-- wait here 'til task gets resource if (User_Task_Pkg.TC_Times_Obtained /= 1) or (User_Task_Pkg.TC_Times_Released /= 0) or not Printer_Mgr_Pkg.Instantiation.Has_Access (User_Rec_1) then Report.Failed ("Resource not assigned to task 1"); end if; Task2.Get_Printer; -- ask for resource -- request for resource should be denied -- and task queued to wait -- Task 1 still waiting to accept Release_Printer, still holds resource -- Task 2 queued on Semaphore.Request -- Ensure that Task2 is queued before continuing to make checks and queue -- Task3. We use a for loop here to avoid hangs in broken implementations. for TC_Cnt in 1 .. 20 loop exit when Printer_Mgr_Pkg.Printer_Access_Mgr.TC_Count >= 1; delay Impdef.Minimum_Task_Switch; end loop; if (User_Task_Pkg.TC_Times_Obtained /= 1) or (User_Task_Pkg.TC_Times_Released /= 0) then Report.Failed ("Resource assigned to task 2"); end if; Task3.Get_Printer; -- ask for resource -- request for resource should be denied -- and task 3 queued on Semaphore.Request Task1.Release_Printer (User_Rec_1);-- task 1 releases resource -- released resource should be given to -- queued task 2. Task2.TC_Get_Descriptor (User_Rec_2);-- wait here for task 2 -- Task 1 has released resource and completed -- Task 2 has seized the resource -- Task 3 is queued on Semaphore.Request if (User_Task_Pkg.TC_Times_Obtained /= 2) or (User_Task_Pkg.TC_Times_Released /= 1) or Printer_Mgr_Pkg.Instantiation.Has_Access (User_Rec_1) or not Printer_Mgr_Pkg.Instantiation.Has_Access (User_Rec_2) then Report.Failed ("Resource not properly released/assigned" & " to task 2"); if Verbose then Report.Comment ("TC_Times_Obtained: " & Integer'Image (User_Task_Pkg.TC_Times_Obtained)); Report.Comment ("TC_Times_Released: " & Integer'Image (User_Task_Pkg.TC_Times_Released)); Report.Comment ("User 1 Has_Access:" & Boolean'Image (Printer_Mgr_Pkg.Instantiation. Has_Access (User_Rec_1))); Report.Comment ("User 2 Has_Access:" & Boolean'Image (Printer_Mgr_Pkg.Instantiation. Has_Access (User_Rec_2))); end if; end if; Task2.Release_Printer (User_Rec_2);-- task 2 releases resource -- task 3 is released from queue, and is given resource Task3.TC_Get_Descriptor (User_Rec_3);-- wait for task 3 if (User_Task_Pkg.TC_Times_Obtained /= 3) or (User_Task_Pkg.TC_Times_Released /= 2) or Printer_Mgr_Pkg.Instantiation.Has_Access (User_Rec_2) or not Printer_Mgr_Pkg.Instantiation.Has_Access (User_Rec_3) then Report.Failed ("Resource not properly released/assigned " & "to task 3"); if Verbose then Report.Comment ("TC_Times_Obtained: " & Integer'Image (User_Task_Pkg.TC_Times_Obtained)); Report.Comment ("TC_Times_Released: " & Integer'Image (User_Task_Pkg.TC_Times_Released)); Report.Comment ("User 1 Has_Access:" & Boolean'Image (Printer_Mgr_Pkg.Instantiation. Has_Access (User_Rec_1))); Report.Comment ("User 2 Has_Access:" & Boolean'Image (Printer_Mgr_Pkg.Instantiation. Has_Access (User_Rec_2))); Report.Comment ("User 3 Has_Access:" & Boolean'Image (Printer_Mgr_Pkg.Instantiation. Has_Access (User_Rec_3))); end if; end if; Task3.Release_Printer (User_Rec_3);-- task 3 releases resource if (User_Task_Pkg.TC_Times_Obtained /=3) or (User_Task_Pkg.TC_Times_Released /=3) or Printer_Mgr_Pkg.Instantiation.Has_Access (User_Rec_3) then Report.Failed ("Resource not properly released by task 3"); if Verbose then Report.Comment ("TC_Times_Obtained: " & Integer'Image (User_Task_Pkg.TC_Times_Obtained)); Report.Comment ("TC_Times_Released: " & Integer'Image (User_Task_Pkg.TC_Times_Released)); Report.Comment ("User 1 Has_Access:" & Boolean'Image (Printer_Mgr_Pkg.Instantiation. Has_Access (User_Rec_1))); Report.Comment ("User 2 Has_Access:" & Boolean'Image (Printer_Mgr_Pkg.Instantiation. Has_Access (User_Rec_2))); Report.Comment ("User 3 Has_Access:" & Boolean'Image (Printer_Mgr_Pkg.Instantiation. Has_Access (User_Rec_3))); end if; end if; -- Ensure that all tasks have terminated before reporting the result while not (Task1'terminated and Task2'terminated and Task3'terminated) loop delay ImpDef.Minimum_Task_Switch; end loop; Report.Result;end C940004;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?