c954012.a

来自「linux下编程用 编译软件」· A 代码 · 共 497 行 · 第 1/2 页

A
497
字号
               if Current_Priority = High then                  Current_Priority := Low;               else                  Current_Priority := High;               end if;               Build_Credit_Record( Next_Transaction );               Next_Message_Task.Accept_Transaction ( Next_Transaction );            end if;         end;   -- declare      end loop;      -- TC: Wait for Credit_Overloaded to be cleared, then insure that the      -- Distributor has evalated all tasks. Otherwise, some tasks may never      -- be evaluated.      while Credit_Overloaded.Value loop        delay ImpDef.Minimum_Task_Switch;      end loop;      Distributor.TC_Credit_OK;   exception      when others =>         Report.Failed ("Unexpected exception in Line_Driver");   end Line_Driver;   task body Message_Task is      TC_Original_Transaction_Code : Transaction_Code;      This_Transaction : acc_Transaction_Record := new Transaction_Record;   begin      accept Accept_Transaction (In_Transaction : acc_Transaction_Record) do         This_Transaction.all := In_Transaction.all;      end Accept_Transaction;      -- Note the original code to ensure correct return      TC_Original_Transaction_Code := This_Transaction.Code;      -- Queue up on Distributor's Input queue      Distributor.Input ( This_Transaction );      -- This task will now wait for the requeued rendezvous      -- to complete before proceeding      -- After the required computations have been performed      -- return the Transaction_Record appropriately (probably to an output      -- line driver)      null;            -- stub      -- For the test check that the return values are as expected      if TC_Original_Transaction_Code /= This_Transaction.Code then         -- Incorrect rendezvous         Report.Failed ("Message Task: Incorrect code returned");      end if;      if This_Transaction.Code = Credit then         if This_Transaction.Return_Value  /= Credit_Return or            This_Transaction.Time_Stamp     = Base_Time     then               Report.Failed ("Expected path not traversed");         end if;            TC_Tasks_Completed.Increment;      else         if This_Transaction.Return_Value  /= Debit_Return or            This_Transaction.Message_Count /= 1             or            This_Transaction.Time_Stamp     = Base_Time     then               Report.Failed ("Expected path not traversed");         end if;         TC_Debit_Message_Complete.Set_True;      end if;   exception      when others =>         Report.Failed ("Unexpected exception in Message_Task");   end Message_Task;   -- Dispose each input Transaction_Record to the appropriate   -- computation tasks   --   task body Distributor is   begin      loop         select            accept Input (Transaction : acc_Transaction_Record) do               -- Time_Stamp the messages with the current time               --    TC: Used, incidentally, by the test to check that the               --    message did pass through the Distributor Task               Transaction.Time_Stamp := Ada.Calendar.Clock;               -- Pass this transaction on to the appropriate computation               -- task but temporarily hold low-priority transactions under               -- overload conditions               case Transaction.Code is                  when Credit =>                     if Credit_Overloaded.Value and                        Transaction.Priority = Low then                        requeue Wait_for_Underload with abort;                     else                        requeue Credit_Computation.Input with abort;                     end if;                  when Debit =>                     requeue Debit_Computation.Input with abort;               end case;            end Input;         or            when not Credit_Overloaded.Value =>            accept Wait_for_Underload (Transaction : acc_Transaction_Record) do               requeue Credit_Computation.Input with abort;            end Wait_for_Underload;         or            accept TC_Credit_OK;               -- We need this to insure that we evaluate the guards at least               -- once when Credit_Overloaded is False. Otherwise, tasks               -- could stay queued on Wait_for_Underload forever (starvation).         or            terminate;         end select;      end loop;   exception      when others =>         Report.Failed ("Unexpected exception in Distributor");   end Distributor;   -- Computation task.  After the computation is performed the rendezvous   -- in the original message task is completed.   --   task body Credit_Computation is      Message_Count   : integer := 0;   begin      loop         select            accept Input ( Transaction : acc_Transaction_Record) do               if Credit_Overloaded.Value and                  Transaction.Priority = Low then                  -- We should not be getting any Low Priority messages. They                  -- should be waiting on the Distributor's Wait_for_Underload                  -- queue                  Report.Failed                     ("Credit Task: Low priority transaction during overload");               end if;               -- Perform the computations required for this transaction               null; -- stub               -- For the test:               if Transaction.Time_Stamp = Base_Time then                  Report.Failed                         ("Credit Task: Wrong queue, Distributor bypassed");               end if;               if Transaction.code /= Credit then                  Report.Failed                         ("Credit Task: Requeue delivered to the wrong queue");               end if;               -- The following is all Test Control code:               Transaction.Return_Value := Credit_Return;               Message_Count := Message_Count + 1;               --               -- Now take special action depending on which Message               if Message_Count = 1 then                  -- After the first message :                  Credit_Overloaded.Set_True;                  -- Now flag the Line_Driver that the second and subsequent                  -- messages may now be sent                  TC_First_Message_Has_Arrived.Set_True;               end if;               if Message_Count = 3 then                  -- The two high priority transactions created subsequent                  -- to the overload have now been processed                  Credit_Overloaded.Set_False;               end if;            end Input;         or            terminate;         end select;      end loop;   exception      when others =>         Report.Failed ("Unexpected exception in Credit_Computation");   end Credit_Computation;   -- Computation task.  After the computation is performed the rendezvous   -- in the original message task is completed.   --   task body Debit_Computation is      Message_Count   : integer := 0;   begin      loop         select            accept Input (Transaction : acc_Transaction_Record) do               -- Perform the computations required for this message               null;      -- stub               -- For the test:               if Transaction.Time_Stamp = Base_Time then                  Report.Failed                         ("Debit Task: Wrong queue, Distributor bypassed");               end if;               if Transaction.code /= Debit then                  Report.Failed                         ("Debit Task: Requeue delivered to the wrong queue");               end if;               -- for the test plug a known value and count               Transaction.Return_Value := Debit_Return;               -- one, and only one, message should pass through               Message_Count := Message_Count + 1;               Transaction.Message_Count := Message_Count;            end Input;         or            terminate;         end select;      end loop;   exception      when others =>         Report.Failed ("Unexpected exception in Debit_Computation");   end Debit_Computation;begin -- c954012   Report.Test ("C954012", "Requeue within an accept body" &                           " to another entry in the same task");   Line_Driver.Start;  -- Start the test   -- Ensure that the message tasks complete before reporting the result   while (TC_Tasks_Completed.Count < TC_Credit_Messages_Expected)         or (not TC_Debit_Message_Complete.Value) loop      delay ImpDef.Minimum_Task_Switch;   end loop;   Report.Result;end C954012;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?