File : atomic_controller.adb


--                              -*- Mode: Ada -*-
-- Filename        : atomic_controller.adb
-- Description     : this genetic monitor synchronizes the parallel part of
--                    an atomic action and distributes a failure signal to
--                    all (monitor is used in conjunction with
--                    generic_atomic_actions)
-- Author          : Uwe Zimmer
-- Created On      : Wed Aug 28 17:12:06 2002
-- Last Modified By: .
-- Last Modified On: .
-- Update Count    : 0
-- Status          : Unknown, Use with caution!

package body Atomic_Controller is

   protected body Monitor is

      procedure Get_Id (Id: out Task_Ids) is

         begin
            Id := Id_Counter;
            if Id_Counter < Task_Ids'Last then
               Id_Counter := Task_Ids'Succ (Id_Counter);
            end if;
      end Get_Id;

      entry Check_In (Task_Id : in Task_Ids)
      when State = Checking_In is

      begin
         if Check_List (Task_Id) = Is_In then
            raise Repeated_Check_In;
         else
            Check_List (Task_Id) := Is_In;
            if Check_List = Check_List_All_In then
               State := All_Checked_In;
            end if;
         end if;
      end Check_In;


      entry Fail (Condition : in Atomic_Condition)
      when State = All_Checked_In is

      begin
         Final_Condition := Condition;
      end Fail;


      entry Failed when Final_Condition /= Succeeded is

      begin
         null;
      end Failed;


      entry Check_Out (for Check_Out_Queue in Check_Out_State)
                         (Task_Id : in Task_Ids)
      when State = Checking_Out
        or Check_Out (Check_Out_Queue)'Count = Task_List'Length is

      begin
         State := Checking_Out;
         Check_List (Task_Id) := Is_Out;
         if Check_List = Check_List_All_Out then
            State := Final;
         end if;
      end Check_Out;


      entry Action_Result (Condition : out Atomic_Condition)
      when State = Final is

        begin
           Condition       := Final_Condition;
           State           := Checking_In;
           Final_Condition := Succeeded;
        end Action_Result;

   end Monitor;

end Atomic_Controller;