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: 39057 (0x9891) 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 Accepting_And_Selecting is pragma Suppress_All; -- procedure Await_Call (Wait_List : Tt.Wait_List_Skin; -- Conditional : Boolean; -- Selected : out Entry_Id; -- Wakeup : out Reply_Kind; -- Parameter_Location : Address_Ref; -- Current_Task : Task_Id) is -- pragma Routine_Number (Runtime_Ids.Internal); -- -- -- -- Upon return, Wakeup contains a useful value iff -- -- Selected = Null_Entry_Id. -- -- Available : Mq.Wait_List_Index; -- Call_Msg : Entry_Call_Message; -- Status : Mq.Stratus; -- Buffer : Integer := 0; -- Retry : Boolean; -- only used in IPC case -- begin -- -- if Debug_Mode then -- -- Debugging.Put_Message ("Entered Await_Call"); -- -- Debugging.Put_Message (" Wait_List'First =" & -- -- Integer'Image (Wait_List.List'First) & -- -- ", Wait_List'Last =" & -- -- Integer'Image (Wait_List.List'Last)); -- -- Debugging.Put_Message (" Active Wait_List Elements ="); -- -- for I in Wait_List.List'Range loop -- -- if not Wait_List.List (I).Not_Active then -- -- if Wait_List.List (I).Ipc_Queue then -- -- Debugging.Put_Message -- -- (" " & Integer'Image (I) & " is IPC queue"); -- -- else -- -- Debugging.Put_Message (" " & Integer'Image (I)); -- -- end if; -- -- end if; -- -- end loop; -- -- end if; -- -- -- -- if Safety_Check and then -- -- not Current_Task.Action_State (Activation_Done) then -- -- Runtime_Exceptions.Raise_Runtime_Error -- -- ("Await_Call", "acceptor has not completed activation", -- -- Err.Acceptor_Not_Done_Activating, -- -- Current_Task => Current_Task); -- -- end if; -- -- Retry_Loop: -- loop -- -- Wakeup := No_Reply; -- -- Call_Msg := Null_Entry_Call_Message; -- -- if Conditional then -- Mq.Wait_Nonblocking -- (Wait_List.List'Address, -- Wait_List.List'Length, Status, Available); -- -- if Status = Mq.Q_Quesemp then -- Selected := Null_Entry_Id; -- Wakeup := No_Reply; -- return; -- end if; -- -- -- if Safety_Check then -- -- Checking.Check_Message_Queue_Status -- -- (Status, Err.Bad_Status_From_Wait_Nonblocking, -- -- Current_Task => Current_Task); -- -- end if; -- else -- Current_Task.Suspension_State := Awaiting_Entry_Call; -- Release_Lock; -- Mq.Wait (Wait_List.List'Address, -- Wait_List.List'Length, Available); -- Reacquire_Lock; -- -- -- if Debug_Mode then -- -- Debugging.Put_Message ("Reply received in Await_Call"); -- -- end if; -- -- -- -- if Safety_Check then -- -- if Status = Mq.Q_Quedel then -- -- if not Current_Task.Action_State (Abnormal) then -- -- Runtime_Exceptions.Raise_Runtime_Error -- -- ("Await_Call", -- -- "queues deleted, but not abnormal", -- -- Err.Reply_Queue_Already_Deleted, -- -- Current_Task => Current_Task); -- -- end if; -- -- else -- -- Checking.Check_Message_Queue_Status -- -- (Status, Err.Bad_Status_From_Wait, -- -- Current_Task => Current_Task); -- -- end if; -- -- end if; -- -- Current_Task.Suspension_State := Not_Suspended; -- end if; -- -- if Current_Task.Action_State (Abnormal) then -- Selected := Null_Entry_Id; -- Wakeup := Task_Aborted; -- Message_Queue_Utilities.Purge_Reply_Queue -- (Current_Task => Current_Task); -- return; -- -- elsif Available = 1 then -- Selected := Null_Entry_Id; -- Mq.Retrieve_Message -- (Wait_List.List (Reply_Queue_Index).Wait_Queue, -- Wakeup'Address, Reply_Message_Size); -- return; -- else -- -- Call_Msg := Message_Queue_Utilities. -- -- Retrieve_Entry_Call_Message -- -- (Wait_List.List (Available - 1).Wait_Queue, -- -- Current_Task => Current_Task); -- Mq.Retrieve_Message -- (Wait_List.List (Available - 1).Wait_Queue, -- Call_Msg'Address, Entry_Call_Message_Size); -- if Call_Msg.Caller /= Null_Caller then -- declare -- The_Caller : Task_Id := -- To_Task_Id (Call_Msg.Caller); -- begin -- The_Caller.Callers_Link := -- Current_Task.Callers_Head; -- Current_Task.Callers_Head.Next := The_Caller; -- The_Caller.Partner_Priority := -- Current_Task.Current_Priority; -- -- if Current_Task.Current_Priority < -- The_Caller.Current_Priority then -- Current_Task.Current_Priority := -- The_Caller.Current_Priority; -- end if; -- end; -- -- if Call_Msg.Timer_Id /= Null_Timer then -- Message_Queue_Utilities.Cancel_Timer -- (Call_Msg.Timer_Id, -- Current_Task => Current_Task); -- end if; -- exit Retry_Loop; -- else -- IPC message -- if Safety_Check and then -- not Wait_List.List (Available - 1).Ipc_Queue then -- Runtime_Exceptions.Raise_Runtime_Error -- ("Await_Call", "IPC msg in non-IPC queue", -- Err.Bad_Message_In_Queue, -- Current_Task => Current_Task); -- end if; -- -- Buffer := Call_Msg.Rendezvous_Params; -- -- -- Handle_Protocol may raise an exception, which -- -- will try to Acquire lock -- Release_Lock; -- Ipc.Handle_Protocol -- (Buffer => Buffer, -- Slot_Data => Ipc.Message_Slot_Data -- (Call_Msg.Timer_Id), -- Queue_Data => -- Message_Queue_Utilities.Get_Associated_Data -- (Wait_List.List (Available - 1).Wait_Queue, -- Current_Task), -- Parameters => Call_Msg.Rendezvous_Params, -- Ignore_Message => Retry); -- Reacquire_Lock; -- -- exit when not Retry; -- only IPC case -- end if; -- end if; -- end loop Retry_Loop; -- -- Parameter_Location.all := Convert (Call_Msg.Rendezvous_Params); -- -- if Buffer /= 0 or else Current_Task.Ipc_Buffer_List /= null then -- if Debug_Mode then -- Debugging.Put_Message (" creating buffer stack"); -- end if; -- -- Current_Task.Ipc_Buffer_List := -- Storage_Manager.New_Buffer_Item -- (With_Buffer => Buffer, -- Slot_Data => Integer (Mq.Associated_Data -- (Call_Msg.Timer_Id)), -- Next_Item => Current_Task.Ipc_Buffer_List); -- end if; -- -- Selected := Entry_Id (Available - 1); -- end Await_Call; -- -- -- pragma Inline (Await_Call); function Select_Rendezvous (Select_Var : Select_Info; Round_Robin : in Integer; -- really in out Parameter_Location : Address_Ref) --return Alternative_Number is --!!Kludge workaround for MP problem return Integer is pragma Routine_Number (Runtime_Ids.Select_Rendezvous); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; Wait_List : Wait_List_Skin renames Current_Task.Queues.Wait_List.all; Branch_Table : Select_Branch_Table_Skin renames Current_Task.Queues.Branch_Table.all; subtype Index is Mq.Wait_List_Index; The_Entry : Entry_Id; Wakeup : Reply_Kind; Delay_Time : Duration := Select_Var.Delay_Time; Delay_Alternative_Open : constant Boolean := Select_Var.Form = Tt.Delay_Form and then Select_Var.Delay_Arm /= 0; Terminate_Alternative_Open : constant Boolean := Select_Var.Form = Tt.Terminate_Form and then Select_Var.Delay_Arm /= 0; Else_Part_Present : constant Boolean := Select_Var.Form = Tt.Else_Form; Treat_As_Else : constant Boolean := Else_Part_Present or else (Delay_Alternative_Open and then Delay_Time <= 0.0); Doing_Delay : constant Boolean := (Delay_Alternative_Open and then Delay_Time > 0.0); Some_Accept_Open : Boolean := False; Timer_Id : Timer.Id; Call_Msg : Entry_Call_Message; Result : Alternative_Number; Available : Index; Status : Mq.Stratus; Buffer : Integer := 0; Retry : Boolean; -- only used in IPC case begin -- if Debug_Mode then -- Debugging.Put_Message ("Entered Select_Rendezvous"); -- Debugging.Put_Message (" Form is " & -- Select_Form'Image (Select_Var.Form)); -- Debugging.Put_Message (" Number of arms is " & -- Alternative_Number'Image (Select_Var.Arms)); -- Debugging.Put_Message (" Delay arm is " & -- Alternative_Number'Image -- (Select_Var.Delay_Arm)); -- for I in 1 .. Select_Var.Arms loop -- Debugging.Put_Message -- ("Arm " & Alternative_Number'Image (I) & " maps to entry " & -- Entry_Id'Image (Select_Var.Map (I).Entry_Number) & -- " and quick => " & -- Boolean'Image (Select_Var.Map (I).Quick)); -- end loop; -- Debugging.Put_Message ("Delay open => " & -- Boolean'Image (Delay_Alternative_Open)); -- Debugging.Put_Message ("Terminate open => " & -- Boolean'Image (Terminate_Alternative_Open)); -- Debugging.Put_Message ("Else present => " & -- Boolean'Image (Else_Part_Present)); -- Debugging.Put_Message ("Treating as else => " & -- Boolean'Image (Treat_As_Else)); -- end if; if Current_Task.Action_State (Abnormal) then Runtime_Exceptions.Raise_Abnormal_Task_Error (Current_Task); end if; -- first close all entries for I in First_Entry_Index .. Wait_List.List'Last loop Wait_List.List (I).Not_Active := True; end loop; declare The_Entry_Map : Tt.Entry_Vector renames Select_Var.Map; begin for I in 1 .. Select_Var.Arms loop The_Entry := The_Entry_Map (I).Entry_Number; if The_Entry /= Null_Entry_Id then Wait_List.List (Mq.Wait_List_Index (The_Entry)). Not_Active := False; Branch_Table.Table (The_Entry) := I; Some_Accept_Open := True; end if; end loop; end; -- if Debug_Mode then -- Debugging.Put_Message (" Wait_List'First =" & -- Integer'Image (Wait_List.List'First) & -- ", Wait_List'Last =" & -- Integer'Image (Wait_List.List'Last)); -- Debugging.Put_Message (" Active Wait_List Elements ="); -- for I in Wait_List.List'Range loop -- if not Wait_List.List (I).Not_Active then -- if Wait_List.List (I).Ipc_Queue then -- Debugging.Put_Message -- (" " & Integer'Image (I) & " is IPC queue"); -- else -- Debugging.Put_Message (" " & Integer'Image (I)); -- end if; -- end if; -- end loop; -- end if; if not Some_Accept_Open and then not Delay_Alternative_Open and then not Terminate_Alternative_Open and then not Else_Part_Present then Runtime_Exceptions.Raise_Program_Error; end if; if Doing_Delay then Timer_Id := Message_Queue_Utilities.Start_Timer (Delay_Time, Select_Timed_Out, Current_Task => Current_Task); elsif Terminate_Alternative_Open then Termination_And_Abortion.Make_Eligible_For_Termination (Current_Task => Current_Task); end if; -- Await_Call (Current_Task => Current_Task, -- Wait_List => Wait_List, -- Conditional => Treat_As_Else, -- Selected => The_Entry, -- Wakeup => Wakeup, -- Parameter_Location => Parameter_Location); <<Await_Call_In_Select>> null; if Treat_As_Else then Mq.Wait_Nonblocking (Wait_List.List'Address, Wait_List.List'Length, Status, Available); if Status = Mq.Q_Quesemp or else -- no callers Status = Mq.Q_Empws then -- no open alternatives Release_Lock; if Else_Part_Present then return 0; else -- non-positive delay --!! Kludge return Integer (Select_Var.Delay_Arm); end if; end if; -- if Safety_Check then -- Checking.Check_Message_Queue_Status -- (Status, Err.Bad_Status_From_Wait_Nonblocking, -- Current_Task => Current_Task); -- end if; else Current_Task.Suspension_State := Awaiting_Entry_Call; Release_Lock; Mq.Wait (Wait_List.List'Address, Wait_List.List'Length, Available); Reacquire_Lock; -- if Debug_Mode then -- Debugging.Put_Message ("Reply received in Select_Rendezvous"); -- end if; -- -- if Safety_Check then -- if Status = Mq.Q_Quedel then -- if not Current_Task.Action_State (Abnormal) then -- Runtime_Exceptions.Raise_Runtime_Error -- ("Select_Rendezvous", -- "queues deleted, but not abnormal", -- Err.Reply_Queue_Already_Deleted, -- Current_Task => Current_Task); -- end if; -- else -- Checking.Check_Message_Queue_Status -- (Status, Err.Bad_Status_From_Wait, -- Current_Task => Current_Task); -- end if; -- end if; Current_Task.Suspension_State := Not_Suspended; if Current_Task.Action_State (Abnormal) then Message_Queue_Utilities.Purge_Reply_Queue (Current_Task => Current_Task); if Terminate_Alternative_Open then Termination_And_Abortion.Make_Ineligible_For_Termination (Current_Task => Current_Task); elsif Doing_Delay then Message_Queue_Utilities.Cancel_Timer (Timer_Id, Current_Task => Current_Task); end if; Runtime_Exceptions.Raise_Abnormal_Task_Error (Current_Task => Current_Task); end if; end if; The_Entry := Entry_Id (Available - 1); if The_Entry = Null_Entry_Id then Mq.Retrieve_Message (Wait_List.List (Reply_Queue_Index).Wait_Queue, Wakeup'Address, Reply_Message_Size); if Terminate_Alternative_Open then if Safety_Check then Checking.Check_Reply (Wakeup, Termination_Selected, Current_Task => Current_Task); end if; Current_Task.Action_State (Selecting_Termination) := True; Runtime_Exceptions.Raise_Force_Term_Error (Current_Task => Current_Task); elsif Doing_Delay then if Safety_Check then Checking.Check_Reply (Wakeup, Select_Timed_Out, Current_Task => Current_Task); end if; Release_Lock; --!!Kludge return Integer (Select_Var.Delay_Arm); elsif Safety_Check then Runtime_Exceptions.Raise_Runtime_Error ("Select_Rendezvous", "unexpected wakeup reason: " & Reply_Kind'Image (Wakeup), Err.Unexpected_Reply, Current_Task => Current_Task); end if; else -- Call_Msg := Message_Queue_Utilities. -- Retrieve_Entry_Call_Message -- (Wait_List.List (Index (The_Entry)).Wait_Queue, -- Current_Task => Current_Task); Mq.Retrieve_Message (Wait_List.List (Index (The_Entry)).Wait_Queue, Call_Msg'Address, Entry_Call_Message_Size); if Terminate_Alternative_Open then Termination_And_Abortion.Make_Ineligible_For_Termination (Current_Task => Current_Task); elsif Doing_Delay then Message_Queue_Utilities.Cancel_Timer (Timer_Id, Purge_If_Expired => True, Current_Task => Current_Task); end if; if Call_Msg.Caller /= Null_Caller then declare The_Caller : Task_Id := To_Task_Id (Call_Msg.Caller); begin The_Caller.Callers_Link := Current_Task.Callers_Head; Current_Task.Callers_Head.Next := The_Caller; The_Caller.Partner_Priority := Current_Task.Current_Priority; if Current_Task.Current_Priority < The_Caller.Current_Priority then Current_Task.Current_Priority := The_Caller.Current_Priority; end if; end; if Call_Msg.Timer_Id /= Null_Timer then Message_Queue_Utilities.Cancel_Timer (Call_Msg.Timer_Id, Current_Task => Current_Task); end if; else -- IPC message -- if Safety_Check and then -- not Wait_List.List (Index (The_Entry)).Ipc_Queue then -- Runtime_Exceptions.Raise_Runtime_Error -- ("Select_Rendezvous", "IPC msg in non-IPC queue", -- Err.Bad_Message_In_Queue, -- Current_Task => Current_Task); -- end if; Buffer := Call_Msg.Rendezvous_Params; -- Handle_Protocol may raise an exception, which -- will try to Acquire lock Release_Lock; Ipc.Handle_Protocol (Buffer => Buffer, Slot_Data => Ipc.Message_Slot_Data (Call_Msg.Timer_Id), Queue_Data => Message_Queue_Utilities.Get_Associated_Data (Wait_List.List (Index (The_Entry)).Wait_Queue, Current_Task), Parameters => Call_Msg.Rendezvous_Params, Ignore_Message => Retry); Reacquire_Lock; if Retry then goto Await_Call_In_Select; end if; end if; end if; Parameter_Location.all := Convert (Call_Msg.Rendezvous_Params); Result := Branch_Table.Table (The_Entry); if Buffer /= 0 or else Current_Task.Ipc_Buffer_List /= null then -- if Debug_Mode then -- Debugging.Put_Message (" creating buffer item"); -- end if; -- Storage_Manager.New_Buffer_Item will release the lock -- Current_Task.Ipc_Buffer_List := Storage_Manager.New_Buffer_Item (With_Buffer => Buffer, Slot_Data => Integer (Mq.Associated_Data (Call_Msg.Timer_Id)), Next_Item => Current_Task.Ipc_Buffer_List); else Release_Lock; end if; if Select_Var.Map (Result).Quick then End_Accept (With_Exception => False); end if; -- if Safety_Check then -- Message_Queue_Utilities.Assert_Empty_Reply_Queue -- ("Select_Rendezvous", Current_Task => Current_Task); -- end if; -- -- if Debug_Mode then -- Debugging.Put_Message ("Select_Rendezvous returning" & -- Alternative_Number'Image (Result)); -- end if; --!!Kludge return Integer (Result); end Select_Rendezvous; procedure Begin_Accept (For_Entry : Entry_Id; Parameter_Location : Address_Ref) is pragma Routine_Number (Runtime_Ids.Begin_Accept); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; Entry_Wait_Item : Mq.Wait_Item renames Current_Task.Queues.Wait_List.all.List (Integer (For_Entry)); Accept_Wait_List : Wait_List_Skin renames Current_Task.Queues.Accept_List.all; -- reply queue already set up as 0th element of accept list Available : Mq.Wait_List_Index; Call_Msg : Entry_Call_Message; Buffer : Integer := 0; Retry : Boolean; -- only used in IPC case begin -- use the explicit representation of queue id here is a real -- kludge, but better code is generated. Accept_Wait_List.List (1).Wait_Queue.Upper := Entry_Wait_Item.Wait_Queue.Upper; Accept_Wait_List.List (1).Wait_Queue.Lower := Entry_Wait_Item.Wait_Queue.Lower; -- .. List (1).Not_Active already false -- if Debug_Mode then -- Debugging.Put_Message ("Entered Begin_Accept, Entry_Number =" & -- Integer'Image (Integer (For_Entry))); -- end if; --Runtime_Exceptions.Check_For_Abnormality (Current_Task => Current_Task); if Current_Task.Action_State (Abnormal) then Runtime_Exceptions.Raise_Abnormal_Task_Error (Current_Task => Current_Task); end if; <<Await_Call_In_Accept>> null; Current_Task.Suspension_State := Awaiting_Entry_Call; Release_Lock; Mq.Wait (Accept_Wait_List.List'Address, Accept_Wait_List.List'Length, Available); Reacquire_Lock; Current_Task.Suspension_State := Not_Suspended; -- the only possible outcomes from the wait for an accept -- are an abort message in the reply queue or an entry -- call message in the entry queue if Current_Task.Action_State (Abnormal) then Message_Queue_Utilities.Purge_Reply_Queue (Current_Task => Current_Task); Runtime_Exceptions.Raise_Abnormal_Task_Error (Current_Task => Current_Task); else -- Call_Msg := Message_Queue_Utilities. -- Retrieve_Entry_Call_Message -- (Wait_List.List (Available - 1).Wait_Queue, -- Current_Task => Current_Task); Mq.Retrieve_Message (Accept_Wait_List.List (1).Wait_Queue, Call_Msg'Address, Entry_Call_Message_Size); if Call_Msg.Caller /= Null_Caller then declare The_Caller : Task_Id := To_Task_Id (Call_Msg.Caller); begin The_Caller.Callers_Link := Current_Task.Callers_Head; Current_Task.Callers_Head.Next := The_Caller; The_Caller.Partner_Priority := Current_Task.Current_Priority; if Current_Task.Current_Priority < The_Caller.Current_Priority then Current_Task.Current_Priority := The_Caller.Current_Priority; end if; end; if Call_Msg.Timer_Id /= Null_Timer then Message_Queue_Utilities.Cancel_Timer (Call_Msg.Timer_Id, Current_Task => Current_Task); end if; else -- IPC message Buffer := Call_Msg.Rendezvous_Params; -- Handle_Protocol may raise an exception, which -- will try to Acquire lock Release_Lock; Ipc.Handle_Protocol (Buffer => Buffer, Slot_Data => Ipc.Message_Slot_Data (Call_Msg.Timer_Id), Queue_Data => Message_Queue_Utilities.Get_Associated_Data (Accept_Wait_List.List (1).Wait_Queue, Current_Task), Parameters => Call_Msg.Rendezvous_Params, Ignore_Message => Retry); Reacquire_Lock; if Retry then goto Await_Call_In_Accept; end if;-- only IPC case end if; end if; Parameter_Location.all := Convert (Call_Msg.Rendezvous_Params); if Buffer /= 0 or else Current_Task.Ipc_Buffer_List /= null then -- Storage_Manager.New_Buffer_Item will release the lock -- Current_Task.Ipc_Buffer_List := Storage_Manager.New_Buffer_Item (With_Buffer => Buffer, Slot_Data => Integer (Mq.Associated_Data (Call_Msg.Timer_Id)), Next_Item => Current_Task.Ipc_Buffer_List); else Release_Lock; end if; end Begin_Accept; procedure End_Accept (With_Exception : Boolean) is pragma Routine_Number (Runtime_Ids.End_Accept); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; Have_Buffer_Stack : constant Boolean := (Current_Task.Ipc_Buffer_List /= null); Caller : Task_Id; Prior_Priority : Priority; begin -- if Debug_Mode then -- Debugging.Put_Message ("Entered End_Accept with exception => " & -- Boolean'Image (With_Exception)); -- end if; if not Have_Buffer_Stack or else Current_Task.Ipc_Buffer_List.Buffer = 0 then -- not an IPC rendezvous Caller := Current_Task.Callers_Head.Next; Prior_Priority := Caller.Partner_Priority; -- if Safety_Check then -- Checking.Check_Task (Caller, "End_Accept", -- Current_Task => Current_Task); -- end if; if Current_Task.Action_State (Abnormal) then Caller.Exception_Id := Exceptions.Tasking_Error; Caller.Action_State (Exception_Pending) := True; elsif With_Exception then Caller.Exception_Id := Current_Task.Exception_Id; Caller.Action_State (Exception_Pending) := True; end if; Current_Task.Callers_Head := Caller.Callers_Link; Caller.Callers_Link.Next := null; -- Message_Queue_Utilities.Send_Reply -- (Caller, Rendezvous_Done, Current_Task => Current_Task); declare Status : Mq.Stratus; Message_Id : Mq.Message_Id; The_Reply : Reply_Kind := Rendezvous_Done; begin Mq.Send_Without_Priority (Value => Integer (Rendezvous_Done), Queue => Caller.Queues.Wait_List.List (Reply_Queue_Index). Wait_Queue); end; if Prior_Priority /= Current_Task.Current_Priority then Current_Task.Current_Priority := Prior_Priority; declare Reset_Priority : Integer := Integer (Prior_Priority); begin if Reset_Priority < Minimum_Os_Priority then Reset_Priority := Minimum_Os_Priority; end if; Release_Lock; Process_Ops.Set_Priority (Process_Id => Current_Task.Process_Id, Priority => Reset_Priority); -- if Safety_Check then -- Checking.Check_Os9_Ops_Status -- (Status, Err.Bad_Status_From_Set_Priority, -- Current_Task => Current_Task); -- end if; end; else Release_Lock; end if; else -- an IPC rendezvous Release_Lock; Ipc.Release_Buffer (Current_Task.Ipc_Buffer_List.Buffer, Ipc.Message_Slot_Data (Current_Task.Ipc_Buffer_List.Slot_Data)); Current_Task.Ipc_Buffer_List.Buffer := 0; end if; if Have_Buffer_Stack then -- pop a level declare Temp : Buffer_List := Current_Task.Ipc_Buffer_List.Next; begin Current_Task.Ipc_Buffer_List.Next := Buffer_Free_List; Buffer_Free_List := Current_Task.Ipc_Buffer_List; Current_Task.Ipc_Buffer_List := Temp; end; end if; --Runtime_Exceptions.Check_For_Abnormality (Current_Task => Current_Task); if Current_Task.Action_State (Abnormal) then -- must reacquire lock, since already released, and -- raise will also release. Reacquire_Lock; Runtime_Exceptions.Raise_Abnormal_Task_Error (Current_Task => Current_Task); end if; end End_Accept; procedure Quick_Accept (For_Entry : Entry_Id) is pragma Routine_Number (Runtime_Ids.Quick_Accept); Current_Task : constant Task_Id := Get_Current_Task_And_Acquire_Lock; Entry_Wait_Item : Mq.Wait_Item renames Current_Task.Queues.Wait_List.all.List (Integer (For_Entry)); Accept_Wait_List : Wait_List_Skin renames Current_Task.Queues.Accept_List.all; -- reply queue already set up as 0th element of accept list Available : Mq.Wait_List_Index; Call_Msg : Entry_Call_Message; -- NOTE: assume that all IPC messages have paraemeters, and -- hence will never be accepted via Quick_Accept. -- begin -- do work of Begin_Accept -- use the explicit representation of queue id here is a real -- kludge, but better code is generated. Accept_Wait_List.List (1).Wait_Queue.Upper := Entry_Wait_Item.Wait_Queue.Upper; Accept_Wait_List.List (1).Wait_Queue.Lower := Entry_Wait_Item.Wait_Queue.Lower; -- .. List (1).Not_Active already false -- if Debug_Mode then -- Debugging.Put_Message ("Entered Quick_Accept, Entry_Number =" & -- Integer'Image (Integer (For_Entry))); -- end if; --Runtime_Exceptions.Check_For_Abnormality (Current_Task => Current_Task); if Current_Task.Action_State (Abnormal) then Runtime_Exceptions.Raise_Abnormal_Task_Error (Current_Task => Current_Task); end if; Current_Task.Suspension_State := Awaiting_Entry_Call; Release_Lock; Mq.Wait (Accept_Wait_List.List'Address, Accept_Wait_List.List'Length, Available); Reacquire_Lock; Current_Task.Suspension_State := Not_Suspended; -- the only possible outcomes from the wait for an accept -- are an abort message in the reply queue or an entry -- call message in the entry queue if Current_Task.Action_State (Abnormal) then Message_Queue_Utilities.Purge_Reply_Queue (Current_Task => Current_Task); -- raise will release the lock Runtime_Exceptions.Raise_Abnormal_Task_Error (Current_Task => Current_Task); else -- Call_Msg := Message_Queue_Utilities. -- Retrieve_Entry_Call_Message -- (Wait_List.List (Available - 1).Wait_Queue, -- Current_Task => Current_Task); Mq.Retrieve_Message (Accept_Wait_List.List (1).Wait_Queue, Call_Msg'Address, Entry_Call_Message_Size); declare The_Caller : Task_Id := To_Task_Id (Call_Msg.Caller); begin if Call_Msg.Timer_Id /= Null_Timer then Message_Queue_Utilities.Cancel_Timer (Call_Msg.Timer_Id, Current_Task => Current_Task); end if; -- do work of End_Accept (With_Exception => False); -- Message_Queue_Utilities.Send_Reply -- (Caller, Rendezvous_Done, Current_Task => Current_Task); declare Status : Mq.Stratus; Message_Id : Mq.Message_Id; The_Reply : Reply_Kind := Rendezvous_Done; begin Mq.Send_Without_Priority (Value => Integer (Rendezvous_Done), Queue => The_Caller.Queues.Wait_List.List (Reply_Queue_Index).Wait_Queue); end; if Current_Task.Current_Priority < The_Caller.Current_Priority then declare Reset_Priority : Integer := Integer (Current_Task.Current_Priority); begin if Reset_Priority < Minimum_Os_Priority then Reset_Priority := Minimum_Os_Priority; end if; Release_Lock; Process_Ops.Set_Priority (Process_Id => Current_Task.Process_Id, Priority => Reset_Priority); -- if Safety_Check then -- Checking.Check_Os9_Ops_Status -- (Status, Err.Bad_Status_From_Set_Priority, -- Current_Task => Current_Task); -- end if; end; else Release_Lock; end if; end; end if; end Quick_Accept; end Accepting_And_Selecting; pragma Runtime_Unit (Unit_Number => Runtime_Ids.Runtime_Compunit, Elab_Routine_Number => Runtime_Ids.Internal);