File : s-secsta-zfp.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-2014, 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 --  This is the HI-E version of this package
  33 
  34 with Unchecked_Conversion;
  35 
  36 package body System.Secondary_Stack is
  37 
  38    use type SSE.Storage_Offset;
  39 
  40    type Memory is array (Mark_Id range <>) of SSE.Storage_Element;
  41 
  42    type Stack_Id is record
  43       Top  : Mark_Id;
  44       Last : Mark_Id;
  45       Mem  : Memory (1 .. Mark_Id'Last);
  46    end record;
  47    pragma Suppress_Initialization (Stack_Id);
  48 
  49    type Stack_Ptr is access Stack_Id;
  50 
  51    function From_Addr is new Unchecked_Conversion (Address, Stack_Ptr);
  52 
  53    function Get_Sec_Stack return Stack_Ptr;
  54    pragma Import (C, Get_Sec_Stack, "__gnat_get_secondary_stack");
  55    --  Return the address of the secondary stack.
  56    --  In a multi-threaded environment, Sec_Stack should be a thread-local
  57    --  variable.
  58    --
  59    --  Possible separate implementation of Get_Sec_Stack in a single-threaded
  60    --  environment:
  61    --
  62    --  with System;
  63 
  64    --  package Secondary_Stack is
  65    --     function Get_Sec_Stack return System.Address;
  66    --     pragma Export (C, Get_Sec_Stack, "__gnat_get_secondary_stack");
  67    --  end Secondary_Stack;
  68 
  69    --  pragma Warnings (Off);
  70    --  with System.Secondary_Stack; use System.Secondary_Stack;
  71    --  pragma Warnings (On);
  72 
  73    --  package body Secondary_Stack is
  74 
  75    --     Chunk : aliased String (1 .. Default_Secondary_Stack_Size);
  76    --     for Chunk'Alignment use Standard'Maximum_Alignment;
  77 
  78    --     Initialized : Boolean := False;
  79 
  80    --     function Get_Sec_Stack return System.Address is
  81    --     begin
  82    --        if not Initialized then
  83    --           Initialized := True;
  84    --           SS_Init (Chunk'Address);
  85    --        end if;
  86 
  87    --        return Chunk'Address;
  88    --     end Get_Sec_Stack;
  89 
  90    --  end Secondary_Stack;
  91 
  92    -----------------
  93    -- SS_Allocate --
  94    -----------------
  95 
  96    procedure SS_Allocate
  97      (Address      : out System.Address;
  98       Storage_Size : SSE.Storage_Count)
  99    is
 100       Max_Align    : constant Mark_Id := Mark_Id (Standard'Maximum_Alignment);
 101       Max_Size     : constant Mark_Id :=
 102                        ((Mark_Id (Storage_Size) + Max_Align - 1) / Max_Align)
 103                          * Max_Align;
 104       Sec_Stack    : constant Stack_Ptr := Get_Sec_Stack;
 105 
 106    begin
 107       if Sec_Stack.Top + Max_Size > Sec_Stack.Last then
 108          raise Storage_Error;
 109       end if;
 110 
 111       Address := Sec_Stack.Mem (Sec_Stack.Top)'Address;
 112       Sec_Stack.Top := Sec_Stack.Top + Max_Size;
 113    end SS_Allocate;
 114 
 115    -------------
 116    -- SS_Init --
 117    -------------
 118 
 119    procedure SS_Init
 120      (Stk  : System.Address;
 121       Size : Natural := Default_Secondary_Stack_Size)
 122    is
 123       Stack : constant Stack_Ptr := From_Addr (Stk);
 124 
 125    begin
 126       pragma Assert (Size >= 2 * Mark_Id'Max_Size_In_Storage_Elements);
 127       pragma Assert
 128         (Stk mod Standard'Maximum_Alignment = SSE.Storage_Offset'(0));
 129 
 130       Stack.Top := Stack.Mem'First;
 131       Stack.Last := Mark_Id (Size) - 2 * Mark_Id'Max_Size_In_Storage_Elements;
 132    end SS_Init;
 133 
 134    -------------
 135    -- SS_Mark --
 136    -------------
 137 
 138    function SS_Mark return Mark_Id is
 139    begin
 140       return Get_Sec_Stack.Top;
 141    end SS_Mark;
 142 
 143    ----------------
 144    -- SS_Release --
 145    ----------------
 146 
 147    procedure SS_Release (M : Mark_Id) is
 148    begin
 149       Get_Sec_Stack.Top := M;
 150    end SS_Release;
 151 
 152 end System.Secondary_Stack;