File : s-secsta-static.adb


   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 --          Copyright (C) 1992-2012, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- GNAT was originally developed  by the GNAT team at  New York University. --
  28 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 with Unchecked_Conversion;
  33 
  34 package body System.Secondary_Stack is
  35 
  36    use type SSE.Storage_Offset;
  37 
  38    type Memory is array (Mark_Address range <>) of SSE.Storage_Element;
  39 
  40    type Stack_Id is record
  41       Top  : Mark_Address;
  42       Last : Mark_Address;
  43       Mem  : Memory (1 .. Mark_Address'Last);
  44    end record;
  45    pragma Suppress_Initialization (Stack_Id);
  46 
  47    type Stack_Ptr is access Stack_Id;
  48 
  49    function From_Addr is new Unchecked_Conversion (Address, Stack_Ptr);
  50 
  51    function Get_Sec_Stack return Stack_Ptr;
  52 
  53    -----------------
  54    -- SS_Allocate --
  55    -----------------
  56 
  57    procedure SS_Allocate
  58      (Address      : out System.Address;
  59       Storage_Size : SSE.Storage_Count)
  60    is
  61       Max_Align    : constant Mark_Address :=
  62                        Mark_Address (Standard'Maximum_Alignment);
  63       Max_Size     : constant Mark_Address :=
  64                        ((Mark_Address (Storage_Size) + Max_Align - 1)
  65                           / Max_Align) * Max_Align;
  66       Sec_Stack    : constant Stack_Ptr := Get_Sec_Stack;
  67 
  68    begin
  69       if Sec_Stack.Top + Max_Size > Sec_Stack.Last then
  70          raise Storage_Error;
  71       end if;
  72 
  73       Address := Sec_Stack.Mem (Sec_Stack.Top)'Address;
  74       Sec_Stack.Top := Sec_Stack.Top + Max_Size;
  75    end SS_Allocate;
  76 
  77    -------------
  78    -- SS_Init --
  79    -------------
  80 
  81    procedure SS_Init
  82      (Stk  : System.Address;
  83       Size : Natural := Default_Secondary_Stack_Size)
  84    is
  85       Stack : constant Stack_Ptr := From_Addr (Stk);
  86    begin
  87       pragma Assert (Size >= 2 * Mark_Address'Max_Size_In_Storage_Elements);
  88       Stack.Top := Stack.Mem'First;
  89       Stack.Last :=
  90         Mark_Address (Size) - 2 * Mark_Address'Max_Size_In_Storage_Elements;
  91    end SS_Init;
  92 
  93    -------------
  94    -- SS_Mark --
  95    -------------
  96 
  97    function SS_Mark return Mark_Id is
  98    begin
  99       return (Mark_Addr => Get_Sec_Stack.Top, Unused => Null_Address);
 100    end SS_Mark;
 101 
 102    ----------------
 103    -- SS_Release --
 104    ----------------
 105 
 106    procedure SS_Release (M : Mark_Id) is
 107    begin
 108       Get_Sec_Stack.Top := M.Mark_Addr;
 109    end SS_Release;
 110 
 111    -------------------------
 112    -- Package Elaboration --
 113    -------------------------
 114 
 115    --  Allocate a secondary stack for the main program to use
 116 
 117    --  We make sure that the stack has maximum alignment. Some systems require
 118    --  this (e.g. Sun), and in any case it is a good idea for efficiency.
 119 
 120    Stack : aliased Memory (1 .. Mark_Address (Default_Secondary_Stack_Size));
 121    for Stack'Alignment use Standard'Maximum_Alignment;
 122 
 123    Stack_Address : constant Address := Stack'Address;
 124 
 125    function Get_Sec_Stack return Stack_Ptr is
 126    begin
 127       return From_Addr (Stack_Address);
 128    end Get_Sec_Stack;
 129 
 130 begin
 131    SS_Init (Stack_Address, Default_Secondary_Stack_Size);
 132 end System.Secondary_Stack;