|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ B T ┃
Length: 33612 (0x834c) Types: TextFile Names: »B«
└─⟦afbc8121e⟧ Bits:30000532 8mm tape, Rational 1000, MC68020_OS2000 7_2_2 └─ ⟦77aa8350c⟧ »DATA« └─⟦f794ecd1d⟧ └─⟦24d1ddd49⟧ └─⟦this⟧
-- The use of this system is subject to the software license terms and -- conditions agreed upon between Rational and the Customer. -- -- Copyright 1988 by Rational. -- -- RESTRICTED RIGHTS LEGEND -- -- Use, duplication, or disclosure by the Government is subject to -- restrictions as set forth in subdivision (b)(3)(ii) of the Rights in -- Technical Data and Computer Software clause at 52.227-7013. -- -- -- Rational -- 3320 Scott Boulevard -- Santa Clara, California 95054-3197 -- -- PROPRIETARY AND CONFIDENTIAL INFORMATION OF RATIONAL; -- USE OR COPYING WITHOUT EXPRESS WRITTEN AUTHORIZATION -- IS STRICTLY PROHIBITED. THIS MATERIAL IS PROTECTED AS -- AN UNPUBLISHED WORK UNDER THE U.S. COPYRIGHT ACT OF -- 1976. CREATED 1988. ALL RIGHTS RESERVED. -- -- separate (Task_Management) package body Termination_And_Abortion is pragma Suppress_All; function "=" (X, Y : Tt.Wait_List_Link) return Boolean renames Tt."="; procedure Delete_Entry_Queues (The_Task : Task_Id; Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); Next_Caller : Task_Id; Message : Entry_Call_Message; Status : Mq.Stratus; begin if Debug_Mode then Debugging.Put_Message ("Entered Delete_Entry_Queues"); end if; -- if Safety_Check then -- Checking.Check_Task (The_Task, "Delete_Entry_Queues", -- Current_Task => Current_Task); -- end if; -- mark the task as non_callable The_Task.Action_State (Non_Callable) := True; if The_Task.Queues.Wait_List /= null then for I in First_Entry_Index .. The_Task.Queues.Wait_List.List'Last loop declare The_Wait_Item : Mq.Wait_Item renames The_Task.Queues.Wait_List.List (I); The_Queue : Mq.Id renames The_Wait_Item.Wait_Queue; begin -- Only evacuate if the current task. PRS 9723630-0120-1 if The_Wait_Item.Ipc_Queue and The_Task = Current_Task then Ipc.Evacuate_Queue (The_Queue => The_Queue, Queue_Data => Message_Queue_Utilities. Get_Associated_Data (The_Queue, The_Task)); end if; -- Only delete if necessary. if (not The_Wait_Item.Ipc_Queue) or (The_Task = Current_Task) then Delete_A_Queue: loop Mq.Delete_If_Empty (The_Queue, Status); if Status /= Mq.Q_Notemp then if Safety_Check then Checking.Check_Message_Queue_Status (Status, Err.Bad_Status_From_Delete_If_Empty, Current_Task => Current_Task); end if; -- The_Queue := Mq.Null_Id; The_Queue.Upper := 0; The_Queue.Lower := 0; exit Delete_A_Queue; end if; Cause_Tasking_Error: loop Mq.Retrieve_If_Available (The_Queue, Message'Address, Entry_Call_Message_Size, Status); exit when Status = Mq.Q_Nomess; Message_Queue_Utilities.Cancel_Timer (Message.Timer_Id, Current_Task => Current_Task); Next_Caller := To_Task_Id (Message.Caller); Next_Caller.Exception_Id := Exceptions.Tasking_Error; Next_Caller.Action_State (Exception_Pending) := True; Message_Queue_Utilities.Send_Reply (Next_Caller, Rendezvous_Done, Current_Task => Current_Task); end loop Cause_Tasking_Error; end loop Delete_A_Queue; end if; end; end loop; end if; end Delete_Entry_Queues; procedure Prepare_For_Aborted_Entry_Caller_Reply (Abortee : Task_Id; Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); -- There is a comment in Abort_Multiple_Tasks that explains all of this Aborted_While_Calling_Entry : Integer renames Current_Task.Activations_In_Progress; function Convert is new Unchecked_Conversion (System.Address, Group_Ref); Aborter_Id : Task_Id renames Convert (Abortee.Activations_In_Progress'Address).all; begin Aborted_While_Calling_Entry := Aborted_While_Calling_Entry + 1; Aborter_Id := Current_Task; end Prepare_For_Aborted_Entry_Caller_Reply; procedure Forced_Termination (The_Task : Task_Id; Term_Via_Abort : Boolean; Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); begin -- if Debug_Mode then -- Debugging.Put_Message ("Entered Forced_Termination, The_Task =" & -- Integer'Image (The_Task.Os9_Process_Id)); -- end if; if Safety_Check then Checking.Check_Task (The_Task, "Forced_Termination", Current_Task => Current_Task); end if; if The_Task.Action_State (Abnormal) or else The_Task.Suspension_State = Terminated then return; end if; if Term_Via_Abort then The_Task.Action_State (Abnormal) := True; -- mark task as non_callable and delete queues Delete_Entry_Queues (The_Task, Current_Task => Current_Task); end if; if The_Task.Suspension_State = Not_Activated then The_Task.Suspension_State := Terminated; The_Task.Action_State (Parent_Or_Child_Ok_Tcb_Reclamation) := True; The_Task.Master_Block.Non_Terminated := The_Task.Master_Block.Non_Terminated - 1; The_Task.Master_Block.Non_Terminable := The_Task.Master_Block.Non_Terminable - 1; if not Term_Via_Abort then Delete_Entry_Queues (The_Task, Current_Task => Current_Task); end if; elsif The_Task.Suspension_State = Calling_Entry or else The_Task.Suspension_State = Awaiting_Entry_Call or else The_Task.Suspension_State = Delaying or else The_Task.Suspension_State = Not_Suspended then -- A task that calls Collective_Termination will -- be in Not_Suspended state, but it still needs a reply; -- other non-suspended tasks do not get a reply. if (The_Task.Suspension_State /= Not_Suspended) or else ((The_Task = Current_Task) and then (not Term_Via_Abort)) then if Term_Via_Abort then if The_Task.Suspension_State = Calling_Entry then Prepare_For_Aborted_Entry_Caller_Reply (Abortee => The_Task, Current_Task => Current_Task); end if; Message_Queue_Utilities.Send_Reply (The_Task, Task_Aborted, Current_Task => Current_Task); else Message_Queue_Utilities.Send_Reply (The_Task, Termination_Selected, Current_Task => Current_Task); end if; end if; end if; end Forced_Termination; procedure Collective_Termination (For_Layer : Layer_Id; Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); Next_Task : Task_Id; Next_Layer : Layer_Id; begin -- if Debug_Mode then -- Debugging.Put_Message ("Entered Collective_Termination"); -- end if; -- Because Collective_Termination is recursive, and the runtime -- does not have stack_checks enabled, we verify here that the -- stack has not overflowed. If it has, a fatal error is reported -- and the process terminates. This will generally cause program -- deadlock, but the program cannot safely proceed, since there -- is insufficient stack to complete the termination sequence. Process_Ops.Verify_Stack; if For_Layer.Non_Terminated > 0 then Next_Task := For_Layer.Dependent_Task_List.Next; while Next_Task /= null loop if Next_Task.Suspension_State /= Terminated then Next_Layer := Next_Task.Current_Layer; while Next_Layer /= null loop Collective_Termination (Next_Layer, Current_Task => Current_Task); Next_Layer := Next_Layer.Layer_Link; end loop; Forced_Termination (Next_Task, Term_Via_Abort => False, Current_Task => Current_Task); end if; Next_Task := Next_Task.Layer_Link.Next; end loop; end if; end Collective_Termination; procedure Wait_Until_Really_Dead (Child : Task_Id; Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); Reply : Reply_Kind; begin if not Child.Action_State (Parent_Or_Child_Ok_Tcb_Reclamation) then Child.Action_State (Parent_Or_Child_Ok_Tcb_Reclamation) := True; Message_Queue_Utilities.Await_Reply (Awaiting_Tcb_Reclamation_Ok, Reply, Current_Task => Current_Task); if Safety_Check then Checking.Check_Reply (Reply, Child_Tcb_Reclaimable, Current_Task => Current_Task); end if; end if; end Wait_Until_Really_Dead; procedure Do_Await_Dependents (Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); Current_Layer : Layer_Id := Current_Task.Current_Layer; Next_Dependent : Task_Id; Next_Next_Task : Task_Id; Reply : Reply_Kind; begin if Current_Layer /= null then -- if Safety_Check then -- Checking.Check_Layer (Current_Layer, "Await_Dependents", -- Current_Task => Current_Task); -- end if; if Current_Layer.Non_Terminable > 0 then Message_Queue_Utilities.Await_Reply (Awaiting_Dependent_Termination, Reply, Current_Task => Current_Task); if Safety_Check then Checking.Check_Reply (Reply, Dependents_Terminated, Current_Task => Current_Task); end if; elsif Current_Layer.Non_Terminated > 0 then Collective_Termination (Current_Layer, Current_Task => Current_Task); end if; Next_Dependent := Current_Layer.Dependent_Task_List.Next; while Next_Dependent /= null loop if Safety_Check then Checking.Check_Task (Next_Dependent, "Await_Dependents", Current_Task => Current_Task); end if; Next_Next_Task := Next_Dependent.Layer_Link.Next; Wait_Until_Really_Dead (Child => Next_Dependent, Current_Task => Current_Task); Storage_Manager.Free_Queues (Next_Dependent.Queues, Current_Task => Current_Task); Storage_Manager.Free_Tcb (Next_Dependent); Next_Dependent := Next_Next_Task; end loop; Current_Task.Current_Layer := Current_Layer.Layer_Link; Runtime_Exceptions.Check_For_Abnormality (Current_Task => Current_Task); -- else -- if Debug_Mode then -- Debugging.Put_Message -- ("*** Warning: Await_Dependents called but Current_Layer is null"); -- end if; end if; end Do_Await_Dependents; procedure Await_Dependents is pragma Routine_Number (Runtime_Ids.Await_Dependents); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; begin if Debug_Mode then Debugging.Put_Message ("Entered Await_Dependents"); end if; Do_Await_Dependents (Current_Task); Release_Lock; end Await_Dependents; procedure Make_Masters_Cold (The_Task : Task_Id; Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); Next_Layer : Layer_Id; begin -- if Debug_Mode then -- Debugging.Put_Message ("Entered Make_Masters_Cold"); -- end if; -- if Safety_Check then -- Checking.Check_Task (The_Task, "Make_Masters_Cold", -- Current_Task => Current_Task); -- Checking.Check_Layer (The_Task.Master_Block, "Make_Masters_Cold", -- Current_Task => Current_Task); -- end if; -- Because Make_Masters_Cold is recursive, and the runtime -- does not have stack_checks enabled, we verify here that the -- stack has not overflowed. If it has, a fatal error is reported -- and the process terminates. This will generally cause program -- deadlock, but the program cannot safely proceed, since there -- is insufficient stack to complete the termination sequence. Process_Ops.Verify_Stack; -- declare Master_Layer : Layer_Id renames The_Task.Master_Block; Master_Task : Task_Id renames Master_Layer.Master_Task; begin if The_Task.Suspension_State = Terminated then -- if Safety_Check and then (Master_Layer.Non_Terminated = 0) then -- Runtime_Exceptions.Raise_Runtime_Error -- ("Make_Masters_Cold", -- "decrementing non_terminated count below zero", -- Err.Layer_State_Inconsistency, -- Current_Task => Current_Task); -- end if; Master_Layer.Non_Terminated := Master_Layer.Non_Terminated - 1; end if; -- if Safety_Check and then (Master_Layer.Non_Terminable = 0) then -- Runtime_Exceptions.Raise_Runtime_Error -- ("Make_Masters_Cold", -- "decrementing non_terminable count below zero", -- Err.Layer_State_Inconsistency, -- Current_Task => Current_Task); -- end if; Master_Layer.Non_Terminable := Master_Layer.Non_Terminable - 1; if Master_Layer.Non_Terminable > 0 then return; elsif Master_Task.Suspension_State = Awaiting_Dependent_Termination and then (The_Task.Master_Block = Master_Task.Current_Layer) then if Master_Layer.Non_Terminated > 0 then Collective_Termination (Master_Layer, Current_Task => Current_Task); end if; Message_Queue_Utilities.Send_Reply (Master_Task, Dependents_Terminated, Current_Task => Current_Task); elsif Master_Layer.Coldness = Cool then Master_Layer.Coldness := Cold; Next_Layer := Master_Layer.Layer_Link; while Next_Layer /= null loop if Next_Layer.Non_Terminable <= 0 then Next_Layer.Coldness := Cold; Next_Layer := Next_Layer.Layer_Link; else Next_Layer.Coldness := Cool; exit; end if; end loop; if Next_Layer = null then Make_Masters_Cold (Master_Task, Current_Task => Current_Task); end if; end if; end; end Make_Masters_Cold; procedure Task_Completion is pragma Routine_Number (Runtime_Ids.Task_Completion); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; begin if Debug_Mode then Debugging.Put_Message ("Entered Task_Completion"); end if; if not Current_Task.Action_State (Abnormal) then -- If abnormal, then aborter has already deleted entry queues -- mark task as non_callable and delete entry queues Delete_Entry_Queues (The_Task => Current_Task, Current_Task => Current_Task); end if; Do_Await_Dependents (Current_Task); Release_Lock; end Task_Completion; procedure Task_End is pragma Routine_Number (Runtime_Ids.Task_End); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; begin if Debug_Mode then Debugging.Put_Message ("Entered Task_End"); end if; if not Current_Task.Action_State (Activation_Done) then Creation_And_Activation.Notify_Parent_Internal (Tasking_Error_Found => (Current_Task.Exception_Id /= null), Current_Task => Current_Task); end if; if not Current_Task.Action_State (Non_Callable) then -- If Non_Callable, then aborter has already deleted entry queues -- else mark task as non_callable and delete entry queues Delete_Entry_Queues (Current_Task, Current_Task => Current_Task); end if; -- if Safety_Check and then (Current_Task.Current_Layer /= null) then -- -- Tartan called Await_Dependents here instead -- -- of Raise_Runtime_Error. -- -- Runtime_Exceptions.Raise_Runtime_Error -- ("Task_End", "Current layer is non-null", -- Err.Layer_State_Inconsistency, -- Current_Task => Current_Task); -- end if; Current_Task.Suspension_State := Terminated; if not Current_Task.Action_State (Selecting_Termination) then -- If terminating via a select-with-terminate-alternative, then -- already made masters cold. Make_Masters_Cold (Current_Task, Current_Task => Current_Task); end if; if Current_Task.Action_State (Parent_Or_Child_Ok_Tcb_Reclamation) then Message_Queue_Utilities.Send_Reply (Current_Task.Master_Block.Master_Task, Child_Tcb_Reclaimable, Current_Task => Current_Task); else Current_Task.Action_State (Parent_Or_Child_Ok_Tcb_Reclamation) := True; end if; -- if Debug_Mode then -- Debugging.Put_Message -- ("In Task_Management.Task_End, about to call OS9_Ops.Suicide"); -- end if; Release_Lock; Process_Ops.Suicide; -- if Debug_Mode then -- Debugging.Put_Message ("*** ERROR - Task_End returning to caller"); -- end if; end Task_End; procedure Terminate_Activation_Group (First_In_Group : Task_Id; Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); Next_Task : Task_Id := First_In_Group; begin if (First_In_Group /= null) and then (First_In_Group.Suspension_State = Not_Activated) then loop -- if Safety_Check and then -- (Next_Task.Suspension_State /= Not_Activated) then -- -- Runtime_Exceptions.Raise_Runtime_Error -- ("Terminate_Activation_Group", -- "Group member has been activated", -- Err.Suspension_State_Inconsistency, -- Current_Task => Current_Task); -- end if; Forced_Termination (Next_Task, Term_Via_Abort => False, Current_Task => Current_Task); -- Until a task is activated, the Callers_Link field is -- used to store the link to the next member of the -- activation group. -- Next_Task := Next_Task.Callers_Link.Next; exit when Next_Task = null; end loop; end if; end Terminate_Activation_Group; procedure Terminate_Allocated_Offspring (Activation_Group : Group_Ref) is pragma Routine_Number (Runtime_Ids.Terminate_Allocated_Offspring); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; First_In_Group : Task_Id := Activation_Group.all; begin -- if Debug_Mode then -- Debugging.Put_Message ("Entered Terminate_Allocated_Offspring"); -- end if; Activation_Group.all := null; Terminate_Activation_Group (First_In_Group => First_In_Group, Current_Task => Current_Task); Release_Lock; end Terminate_Allocated_Offspring; procedure Terminate_Dependent_Offspring is pragma Routine_Number (Runtime_Ids.Terminate_Dependent_Offspring); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; First_In_Group : Task_Id := Current_Task.Current_Layer.Dependent_Task_List.Next; begin -- if Debug_Mode then -- Debugging.Put_Message ("Entered Terminate_Dependent_Offspring"); -- end if; while First_In_Group /= null loop if First_In_Group.Suspension_State = Not_Activated then Terminate_Activation_Group (First_In_Group => First_In_Group, Current_Task => Current_Task); end if; First_In_Group := First_In_Group.Layer_Link.Next; end loop; Release_Lock; end Terminate_Dependent_Offspring; procedure Abortion (The_Task : Task_Id; Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); Next_Layer : Layer_Id; Next_Child : Task_Id; begin -- if Debug_Mode then -- Debugging.Put_Message ("Entered Abortion"); -- end if; -- -- if Safety_Check then -- Checking.Check_Task (The_Task, "Abortion", -- Current_Task => Current_Task); -- if The_Task.Current_Layer /= null then -- Checking.Check_Layer (The_Task.Current_Layer, "Abortion", -- Current_Task => Current_Task); -- end if; -- end if; Next_Layer := The_Task.Current_Layer; while Next_Layer /= null loop Next_Child := Next_Layer.Dependent_Task_List.Next; while Next_Child /= null loop Abortion (Next_Child, Current_Task => Current_Task); Next_Child := Next_Child.Layer_Link.Next; end loop; Next_Layer := Next_Layer.Layer_Link; end loop; Forced_Termination (The_Task, Term_Via_Abort => True, Current_Task => Current_Task); end Abortion; procedure Abort_Main_Program is pragma Routine_Number (Runtime_Ids.Internal); -- The call to abort the main program is made from -- serialization, so the lock is already held. Current_Task : constant Task_Id := Task_Map.Get_Current_Task_Id; begin Abort_Main_Program_Flag := False; -- if Debug_Mode then -- Debugging.Put_Message ("Entered Abort_Main_Program"); -- end if; Abortion (Root_Task_Ptr, Current_Task); -- do not release the lock end Abort_Main_Program; procedure Abort_Multiple_Tasks (Task_Count : Positive; The_First_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Abort_Multiple_Tasks, Pop_Params => False); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; type Task_Array is array (1 .. Task_Count) of Task_Id; type Task_Array_Ref is access Task_Array; for Task_Array_Ref'Storage_Size use 0; function Convert is new Unchecked_Conversion (System.Address, Task_Array_Ref); Abortees : Task_Array renames Convert (The_First_Task'Address).all; -- LRM 9.10(5) requires that if a task is blocked on an unaccepted -- entry call at the time that it is aborted, then it must be -- removed from the entry queue before the completion of the -- execution of the abort statement. To implement this, the -- Activations_In_Progress field of the TCB is flagrantly abused. -- In the case of the abortee, this field is used to store the -- Task_Id of the aborter; in the case of the aborter, this field -- is used to store the count of abortees that were in this state -- at the time of their abortion. If the count is non-zero, then -- the aborter blocks, awaiting a reply. The count is decremented by -- each of the "special" abortees after they have removed themselves -- from the appropriate entry queue; the abortee who decrements -- the count to zero sends a reply to unblock the aborter. Aborted_While_Calling_Entry : Integer renames Current_Task.Activations_In_Progress; Reply : Reply_Kind; begin -- if Debug_Mode then -- if Task_Count = 1 then -- Debugging.Put_Message ("Entered Abort_Task"); -- else -- Debugging.Put_Message ("Entered Abort_Multiple_Tasks"); -- end if; -- end if; Runtime_Exceptions.Check_For_Abnormality (Current_Task => Current_Task); Aborted_While_Calling_Entry := 0; for I in Abortees'Range loop if Safety_Check then Checking.Check_Task (Abortees (I), "Abort_Multiple_Tasks", Current_Task => Current_Task); end if; Abortion (Abortees (I), Current_Task => Current_Task); end loop; if Aborted_While_Calling_Entry /= 0 then Message_Queue_Utilities.Await_Reply (Awaiting_Abortee_Reply, Reply, Current_Task => Current_Task); if Safety_Check then Checking.Check_Reply (Reply, Abortion_Acknowledged, Current_Task => Current_Task); -- if Aborted_While_Calling_Entry /= 0 then -- Runtime_Exceptions.Raise_Runtime_Error -- ("Abort_Multiple_Tasks", -- "Aborter awakened with non-zero pending reply count: " & -- Integer'Image (Aborted_While_Calling_Entry), -- Err.Suspension_State_Inconsistency, -- Current_Task => Current_Task); -- end if; end if; end if; Runtime_Exceptions.Check_For_Abnormality (Current_Task => Current_Task); Release_Lock; end Abort_Multiple_Tasks; procedure Make_Eligible_For_Termination (Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); Terminable : Boolean := True; Next_Layer : Layer_Id := Current_Task.Current_Layer; begin -- if Safety_Check and then (Next_Layer /= null) then -- Checking.Check_Layer (Next_Layer, "Make_Eligible_For_Termination", -- Current_Task => Current_Task); -- end if; while Terminable and then Next_Layer /= null loop if Next_Layer.Non_Terminable > 0 then Terminable := False; Next_Layer.Coldness := Cool; else Next_Layer.Coldness := Cold; Next_Layer := Next_Layer.Layer_Link; end if; end loop; if Terminable then Termination_And_Abortion.Make_Masters_Cold (Current_Task, Current_Task => Current_Task); end if; end Make_Eligible_For_Termination; procedure Make_Ineligible_For_Termination (Current_Task : Task_Id) is pragma Routine_Number (Runtime_Ids.Internal); Next_Master : Task_Id := Current_Task; Next_Layer : Layer_Id := Current_Task.Current_Layer; begin loop -- if Safety_Check and then (Next_Layer /= null) then -- Checking.Check_Layer (Next_Layer, -- "Make_Ineligible_For_Termination", -- Current_Task => Current_Task); -- end if; while Next_Layer /= null loop if Next_Layer.Coldness = Cold then Next_Layer.Coldness := Warm; Next_Layer := Next_Layer.Layer_Link; elsif Next_Layer.Coldness = Cool then Next_Layer.Coldness := Warm; return; elsif Next_Layer.Coldness = Warm then return; else -- root or illegal Runtime_Exceptions.Raise_Runtime_Error ("MIFT", "bad layer inner loop", Err.Layer_State_Inconsistency, Current_Task => Current_Task); end if; end loop; Next_Layer := Next_Master.Master_Block; Next_Master := Next_Layer.Master_Task; Next_Layer.Non_Terminable := Next_Layer.Non_Terminable + 1; if Next_Layer.Coldness = Cold then Next_Layer.Coldness := Cool; Next_Layer := Next_Layer.Layer_Link; elsif Next_Layer.Coldness = Cool or else Next_Layer.Coldness = Warm then return; else -- Root Runtime_Exceptions.Raise_Runtime_Error ("MIFT", "root layer outer loop", Err.Layer_State_Inconsistency, Current_Task => Current_Task); end if; end loop; end Make_Ineligible_For_Termination; function Check_Return_Task (The_Task : Task_Id; Ptr_Stack_Frame : System_Address) return Boolean is pragma Routine_Number (Runtime_Ids.Check_Return_Task); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; Result : Boolean; begin -- if Debug_Mode then -- Debugging.Put_Message ("Entered Check_Return_Task"); -- end if; -- -- if Safety_Check then -- Checking.Check_Task (The_Task, "Check_Return_Task", -- Current_Task => Current_Task); -- end if; -- Result := Addressing.Is_Contained -- (The_Task.Master_Block, -- Frame_Begin => Ptr_Stack_Frame, -- Frame_End => Current_Task.Stack_Bounds.First); -- declare Middle : System_Address := The_Task.Master_Block.all'Address; begin --return (Frame_End <= Middle) and then (Middle < Frame_Begin); Result := (Le (Current_Task.Stack_Bounds.First, Middle)) and then (Lt (Middle, Ptr_Stack_Frame)); end; Release_Lock; return Result; end Check_Return_Task; end Termination_And_Abortion; pragma Runtime_Unit (Unit_Number => Runtime_Ids.Runtime_Compunit, Elab_Routine_Number => Runtime_Ids.Internal);