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: 8515 (0x2143) Types: TextFile Names: »B«
└─⟦bad92a95e⟧ Bits:30000535 8mm tape, Rational 1000, RPC 1_0_2 └─ ⟦bb34fe6e2⟧ »DATA« └─⟦15d8b76c6⟧ └─⟦this⟧
separate (Transport_Stream) task body Worker is All_Pools : Pool_List := null; -- This is a terrible structure. To speed up allocation, -- there should be a hash table on remote address for pools -- which have null local_socket_ids. Someday. Free_Streams : Stream_List := null; Last_Unique_Id : Unique_Id := 0; function Next_Unique_Id return Unique_Id is begin if Last_Unique_Id = Unique_Id'Last then Last_Unique_Id := Null_Unique_Id + 1; else Last_Unique_Id := Last_Unique_Id + 1; end if; return Last_Unique_Id; end Next_Unique_Id; procedure Do_Create (Pool : out Pool_Id; Network : Transport_Defs.Network_Name; Remote_Host : Transport_Defs.Host_Id; Remote_Socket : Transport_Defs.Socket_Id; Local_Socket : Transport_Defs.Socket_Id) is New_Pool : Pool_Id; begin New_Pool := new Pool_Type (Network_Length => Network'Length, Remote_Host_Length => Remote_Host'Length, Remote_Socket_Length => Remote_Socket'Length, Local_Socket_Length => Local_Socket'Length); New_Pool.Idle := null; New_Pool.Network := Network; New_Pool.Remote_Host := Remote_Host; New_Pool.Remote_Socket := Remote_Socket; New_Pool.Local_Socket := Local_Socket; New_Pool.Next := All_Pools; All_Pools := Pool_List (New_Pool); Pool := New_Pool; end Do_Create; procedure Do_Allocate (Stream : out Stream_Id) is New_Stream : Stream_List; begin if Free_Streams = null then New_Stream := new Stream_Type; New_Stream.Unique := Next_Unique_Id; else New_Stream := Free_Streams; Free_Streams := New_Stream.Next; end if; New_Stream.Next := null; New_Stream.Pool := null; Initialize (New_Stream.Transmit); Initialize (New_Stream.Receive); Stream := (New_Stream, New_Stream.Unique); end Do_Allocate; procedure Do_Allocate (Stream : out Stream_Id; Pool : Pool_Id) is New_Stream : Stream_Id; begin if Pool.Idle = null then Do_Allocate (New_Stream); New_Stream.Stream.Pool := Pool; else New_Stream := (Pool.Idle, Pool.Idle.Unique); Pool.Idle := Pool.Idle.Next; pragma Assert (New_Stream.Stream.Pool = Pool); end if; Stream := New_Stream; end Do_Allocate; procedure Do_Allocate (Stream : out Stream_Id; Network : Transport_Defs.Network_Name; Remote_Host : Transport_Defs.Host_Id; Remote_Socket : Transport_Defs.Socket_Id) is Pool : Pool_List; begin Pool := All_Pools; loop exit when Pool = null; exit when Equals (Network, Pool.Network) and then Equals (Remote_Host, Pool.Remote_Host) and then Equals (Remote_Socket, Pool.Remote_Socket) and then Equals (Null_Socket_Id, Pool.Local_Socket); Pool := Pool.Next; end loop; if Pool = null then Do_Create (Pool_Id (Pool), Network, Remote_Host, Remote_Socket, Local_Socket => Null_Socket_Id); end if; Do_Allocate (Stream, Pool_Id (Pool)); end Do_Allocate; procedure Do_Scavenge (Stream : Stream_List) is begin Stream.Unique := Next_Unique_Id; -- invalidate dangling references. Transport.Close (Stream.Connection); Stream.Next := Free_Streams; Free_Streams := Stream; end Do_Scavenge; procedure Do_Deallocate (Stream : Stream_Id) is List : Stream_List; Pool : Pool_Id; begin if not Is_Null (Stream) then List := Stream.Stream; Pool := List.Pool; if Pool = null then Do_Scavenge (List); else List.Unique := Next_Unique_Id; -- invalidate references List.Referenced := True; List.Next := Pool.Idle; Pool.Idle := List; end if; end if; end Do_Deallocate; procedure Do_Scavenge (Stream : Stream_Id) is begin if not Is_Null (Stream) then Do_Scavenge (Stream.Stream); end if; end Do_Scavenge; procedure Do_Scavenge (Pool : Pool_Id) is X, Y : Stream_List; begin -- scavenge the beginning of the list: X := Pool.Idle; while X /= null loop if X.Referenced then X.Referenced := False; exit; else Pool.Idle := X.Next; Do_Scavenge (X); X := Pool.Idle; end if; end loop; -- scavenge the rest of the list: X := Pool.Idle; while X /= null loop Y := X.Next; exit when Y = null; if Y.Referenced then Y.Referenced := False; X := Y; else X.Next := Y.Next; Do_Scavenge (Y); end if; end loop; end Do_Scavenge; procedure Do_Scavenge is X : Pool_List; begin X := All_Pools; while X /= null loop Do_Scavenge (Pool_Id (X)); X := X.Next; end loop; end Do_Scavenge; begin loop begin loop select accept Create (Pool : out Pool_Id; Network : Transport_Defs.Network_Name; Remote_Host : Transport_Defs.Host_Id; Remote_Socket : Transport_Defs.Socket_Id; Local_Socket : Transport_Defs.Socket_Id) do Do_Create (Pool, Network, Remote_Host, Remote_Socket, Local_Socket); end Create; or accept Allocate (Stream : out Stream_Id) do Do_Allocate (Stream); end Allocate; or accept Allocate (Stream : out Stream_Id; Pool : Pool_Id) do Do_Allocate (Stream, Pool); end Allocate; or accept Allocate (Stream : out Stream_Id; Network : Transport_Defs.Network_Name; Remote_Host : Transport_Defs.Host_Id; Remote_Socket : Transport_Defs.Socket_Id) do Do_Allocate (Stream, Network, Remote_Host, Remote_Socket); end Allocate; or accept Deallocate (Stream : Stream_Id) do Do_Deallocate (Stream); end Deallocate; or accept Disconnect (Stream : Stream_Id) do Do_Scavenge (Stream); end Disconnect; or accept Scavenge (Pool : Pool_Id := null) do if Pool = null then Do_Scavenge; else Do_Scavenge (Pool); end if; end Scavenge; or accept Destroy (Pool : Pool_Id := null) do if Pool = null then Do_Scavenge; Do_Scavenge; else Do_Scavenge (Pool); Do_Scavenge (Pool); end if; end Destroy; or accept Finalize do Do_Scavenge; Do_Scavenge; end Finalize; exit; or terminate; end select; end loop; exit; exception when others => null; end; end loop; end Worker;