home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / ada / s-secsta.adb < prev    next >
Text File  |  1996-09-28  |  10KB  |  294 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --               S Y S T E M . S E C O N D A R Y _ S T A C K                --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.24 $                             --
  10. --                                                                          --
  11. --           Copyright (c) 1992,1993,1994 NYU, All Rights Reserved          --
  12. --                                                                          --
  13. -- The GNAT library is free software; you can redistribute it and/or modify --
  14. -- it under terms of the GNU Library General Public License as published by --
  15. -- the Free Software  Foundation; either version 2, or (at your option) any --
  16. -- later version.  The GNAT library is distributed in the hope that it will --
  17. -- be useful, but WITHOUT ANY WARRANTY;  without even  the implied warranty --
  18. -- of MERCHANTABILITY  or  FITNESS FOR  A PARTICULAR PURPOSE.  See the  GNU --
  19. -- Library  General  Public  License for  more  details.  You  should  have --
  20. -- received  a copy of the GNU  Library  General Public License  along with --
  21. -- the GNAT library;  see the file  COPYING.LIB.  If not, write to the Free --
  22. -- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        --
  23. --                                                                          --
  24. ------------------------------------------------------------------------------
  25.  
  26. with System.Task_Specific_Data;
  27. with System.Tasking_Soft_Links;
  28. with Unchecked_Conversion;
  29. with Unchecked_Deallocation;
  30.  
  31. package body System.Secondary_Stack is
  32.  
  33.  
  34.  
  35.    --                                      +------------------+
  36.    --                                      |       Next       |
  37.    --                                      +------------------+
  38.    --                                      |                  | Last (200)
  39.    --                                      |                  |
  40.    --                                      |                  |
  41.    --                                      |                  |
  42.    --                                      |                  |
  43.    --                                      |                  |
  44.    --                                      |                  | First (101)
  45.    --                                      +------------------+
  46.    --                         +----------> |          |       |
  47.    --                         |            +----------+-------+
  48.    --                         |                    |  |
  49.    --                         |                    ^  V
  50.    --                         |                    |  |
  51.    --                         |            +-------+----------+
  52.    --                         |            |       |          |
  53.    --                         |            +------------------+
  54.    --                         |            |                  | Last (100)
  55.    --                         |            |         C        |
  56.    --                         |            |         H        |
  57.    --    +-----------------+  |  +-------->|         U        |
  58.    --    |  Current_Chunk -|--+  |         |         N        |
  59.    --    +-----------------+     |         |         K        |
  60.    --    |       Top      -|-----+         |                  | First (1)
  61.    --    +-----------------+               +------------------+
  62.    --    | Default_Size    |               |       Prev       |
  63.    --    +-----------------+               +------------------+
  64.    --
  65.    --
  66.  
  67.    type Memory is array (Mark_Id range <>) of Storage_Element;
  68.  
  69.    type Chunk_Id (First, Last : Mark_Id);
  70.    type Chunk_Ptr is access Chunk_Id;
  71.  
  72.    type Chunk_Id (First, Last : Mark_Id) is record
  73.       Prev, Next : Chunk_Ptr;
  74.       Mem        : Memory (First .. Last);
  75.    end record;
  76.  
  77.    type Stack_Id is record
  78.       Top           : Mark_Id;
  79.       Current_Chunk : Chunk_Ptr;
  80.       Default_Size  : Storage_Count;
  81.    end record;
  82.  
  83.    type Stack_Ptr is access Stack_Id;
  84.  
  85.    function From_Addr is new Unchecked_Conversion (Address, Stack_Ptr);
  86.    function To_Addr   is new Unchecked_Conversion (Stack_Ptr, System.Address);
  87.  
  88.    ------------------
  89.    -- Storage_Size --
  90.    ------------------
  91.  
  92.    function Storage_Size (Pool : Secondary_Stack_Pool) return Storage_Count is
  93.       Stack : constant Stack_Ptr
  94.         := From_Addr (System.Task_Specific_Data.Get_Sec_Stack_Addr);
  95.       Chunk : Chunk_Ptr := Stack.Current_Chunk;
  96.  
  97.    begin
  98.       while Chunk.Next /= null loop
  99.          Chunk := Chunk.Next;
  100.       end loop;
  101.  
  102.       return Storage_Count (Chunk.Last);
  103.    end Storage_Size;
  104.  
  105.    --------------
  106.    -- Allocate --
  107.    --------------
  108.  
  109.    procedure Allocate
  110.      (Pool         : in out Secondary_Stack_Pool;
  111.       Address      : out System.Address;
  112.       Storage_Size : Storage_Count;
  113.       Alignment    : Storage_Count)
  114.    is
  115.       Stack        : constant Stack_Ptr :=
  116.                        From_Addr
  117.                          (System.Task_Specific_Data.Get_Sec_Stack_Addr);
  118.       Chunk        : Chunk_Ptr := Stack.Current_Chunk;
  119.       Max_Size     : constant Mark_Id := Mark_Id (Storage_Size + Alignment);
  120.       Align_Offset : Storage_Count;
  121.  
  122.    begin
  123.       --  The Current_Chunk may not be the good one if a lot of release
  124.       --  operations have taken place. So go down the stack if necessary
  125.  
  126.       while  Chunk.First > Stack.Top loop
  127.          Chunk := Chunk.Prev;
  128.       end loop;
  129.  
  130.       --  Find out if the available memory in the current chunk is sufficient.
  131.       --  if not, go to the next one and eventally create the necessary room
  132.  
  133.       while Chunk.Last - Stack.Top + 1 < Max_Size loop
  134.          if Chunk.Next /= null then
  135.             Chunk := Chunk.Next;
  136.  
  137.          --  Create new chunk of the default size unless it is not sufficient
  138.  
  139.          elsif Storage_Count (Max_Size) <= Stack.Default_Size then
  140.             Chunk.Next := new Chunk_Id (
  141.               First => Chunk.Last + 1,
  142.               Last  => Chunk.Last + Mark_Id (Stack.Default_Size));
  143.  
  144.             Chunk.Next.Prev := Chunk;
  145.  
  146.          else
  147.             Chunk.Next := new Chunk_Id (
  148.               First => Chunk.Last + 1,
  149.               Last  => Chunk.Last + Max_Size);
  150.  
  151.             Chunk.Next.Prev := Chunk;
  152.          end if;
  153.  
  154.          Stack.Top := Chunk.First;
  155.       end loop;
  156.  
  157.       --  Resulting address is the address pointed by Stack.Top
  158.  
  159.       Address      := Chunk.Mem (Stack.Top)'Address;
  160.       Align_Offset := Address mod Alignment;
  161.       Stack.Top    := Stack.Top + Mark_Id (Storage_Size);
  162.  
  163.       if Align_Offset /= 0 then
  164.          Address := Address + Alignment - Align_Offset;
  165.          Stack.Top := Stack.Top + Mark_Id (Alignment - Align_Offset);
  166.       end if;
  167.  
  168.       Stack.Current_Chunk := Chunk;
  169.    end Allocate;
  170.  
  171.    ----------------
  172.    -- Deallocate --
  173.    ----------------
  174.  
  175.    --  Nothing to do, since space is released by an unmark operation
  176.  
  177.    procedure Deallocate
  178.      (Pool         : in out Secondary_Stack_Pool;
  179.       Address      : System.Address;
  180.       Storage_Size : Storage_Count;
  181.       Alignment    : Storage_Count)
  182.    is
  183.    begin
  184.       null;
  185.    end Deallocate;
  186.  
  187.    -------------
  188.    -- SS_Init --
  189.    -------------
  190.  
  191.    procedure SS_Init (Stk : out System.Address; Size : Natural) is
  192.       Stack : Stack_Ptr;
  193.  
  194.    begin
  195.       Stack               := new Stack_Id;
  196.       Stack.Current_Chunk := new Chunk_Id (1, Mark_Id (Size));
  197.       Stack.Top           := 1;
  198.       Stack.Default_Size  := Storage_Count (Size);
  199.  
  200.       Stk := To_Addr (Stack);
  201.    end SS_Init;
  202.  
  203.    -------------
  204.    -- SS_Free --
  205.    -------------
  206.  
  207.    procedure SS_Free (Stk : System.Address) is
  208.       Stack : Stack_Ptr := From_Addr (Stk);
  209.       Chunk : Chunk_Ptr := Stack.Current_Chunk;
  210.  
  211.       procedure Free is new Unchecked_Deallocation (Stack_Id, Stack_Ptr);
  212.       procedure Free is new Unchecked_Deallocation (Chunk_Id, Chunk_Ptr);
  213.  
  214.    begin
  215.       while Chunk.Prev /= null loop
  216.          Chunk := Chunk.Prev;
  217.       end loop;
  218.  
  219.       while Chunk.Next /= null loop
  220.          Chunk := Chunk.Next;
  221.          Free (Chunk.Prev);
  222.       end loop;
  223.  
  224.       Free (Chunk);
  225.       Free (Stack);
  226.    end SS_Free;
  227.  
  228.    -------------
  229.    -- SS_Mark --
  230.    -------------
  231.  
  232.    function SS_Mark return Mark_Id is
  233.    begin
  234.       return From_Addr (System.Task_Specific_Data.Get_Sec_Stack_Addr).Top;
  235.    end SS_Mark;
  236.  
  237.    ----------------
  238.    -- SS_Release --
  239.    ----------------
  240.  
  241.    procedure SS_Release (M : Mark_Id) is
  242.    begin
  243.       From_Addr (System.Task_Specific_Data.Get_Sec_Stack_Addr).Top := M;
  244.    end SS_Release;
  245.  
  246.    -------------
  247.    -- SS_Info --
  248.    -------------
  249.  
  250.    procedure SS_Info is
  251.       Stack     : constant Stack_Ptr :=
  252.                     From_Addr
  253.                       (System.Task_Specific_Data.Get_Sec_Stack_Addr);
  254.       Nb_Chunks : Integer            := 1;
  255.       Chunk     : Chunk_Ptr          := Stack.Current_Chunk;
  256.  
  257.    begin
  258.       Put_Line ("Secondary Stack information:");
  259.  
  260.       while Chunk.Prev /= null loop
  261.          Chunk := Chunk.Prev;
  262.       end loop;
  263.  
  264.       while Chunk.Next /= null loop
  265.          Nb_Chunks := Nb_Chunks + 1;
  266.          Chunk := Chunk.Next;
  267.       end loop;
  268.  
  269.       --  Current Chunk information
  270.  
  271.       Put_Line (
  272.         "  Total size              : "
  273.         & Mark_Id'Image (Chunk.Last)
  274.         & " bytes");
  275.       Put_Line (
  276.         "  Current allocated space : "
  277.         & Mark_Id'Image (Stack.Top - 1)
  278.         & " bytes");
  279.  
  280.       Put_Line (
  281.         "  Number of Chunks       : "
  282.         & Integer'Image (Nb_Chunks));
  283.  
  284.       Put_Line (
  285.         "  Default size of Chunks : "
  286.         & Storage_Count'Image (Stack.Default_Size));
  287.    end SS_Info;
  288.  
  289. begin
  290.    System.Tasking_Soft_Links.SS_Init := SS_Init'Access;
  291.    System.Tasking_Soft_Links.SS_Free := SS_Free'Access;
  292.  
  293. end System.Secondary_Stack;
  294.