DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ B T

⟦a56b42029⟧ TextFile

    Length: 8047 (0x1f6f)
    Types: TextFile
    Names: »B«

Derivation

└─⟦149519bd4⟧ Bits:30000546 8mm tape, Rational 1000, !projects 93-07-13
    └─ ⟦124ff5788⟧ »DATA« 
        └─⟦this⟧ 
└─⟦f64eaa120⟧ Bits:30000752 8mm tape, Rational 1000, !projects 93 02 16
    └─ ⟦6f12a12be⟧ »DATA« 
        └─⟦this⟧ 

TextFile

WITH Pragma_Assert;

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);
         Pragma_Assert.Check (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;