diff options
Diffstat (limited to 'gcc/ada/1ssecsta.adb')
-rw-r--r-- | gcc/ada/1ssecsta.adb | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/gcc/ada/1ssecsta.adb b/gcc/ada/1ssecsta.adb new file mode 100644 index 00000000000..0bb1f2ac122 --- /dev/null +++ b/gcc/ada/1ssecsta.adb @@ -0,0 +1,145 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S Y S T E M . S E C O N D A R Y _ S T A C K -- +-- -- +-- B o d y -- +-- -- +-- $Revision$ +-- -- +-- Copyright (C) 1992-2001 Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 2, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- +-- for more details. You should have received a copy of the GNU General -- +-- Public License distributed with GNAT; see file COPYING. If not, write -- +-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, -- +-- MA 02111-1307, USA. -- +-- -- +-- As a special exception, if other files instantiate generics from this -- +-- unit, or you link this unit with other files to produce an executable, -- +-- this unit does not by itself cause the resulting executable to be -- +-- covered by the GNU General Public License. This exception does not -- +-- however invalidate any other reasons why the executable file might be -- +-- covered by the GNU Public License. -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). -- +-- -- +------------------------------------------------------------------------------ + +-- This is the HI-E version of this package. + +with Unchecked_Conversion; + +package body System.Secondary_Stack is + + use type SSE.Storage_Offset; + + type Memory is array (Mark_Id range <>) of SSE.Storage_Element; + + type Stack_Id is record + Top : Mark_Id; + Last : Mark_Id; + Mem : Memory (1 .. Mark_Id'Last); + end record; + pragma Suppress_Initialization (Stack_Id); + + type Stack_Ptr is access Stack_Id; + + function From_Addr is new Unchecked_Conversion (Address, Stack_Ptr); + + function Get_Sec_Stack return Stack_Ptr; + pragma Import (C, Get_Sec_Stack, "__gnat_get_secondary_stack"); + -- Return the address of the secondary stack. + -- In a multi-threaded environment, Sec_Stack should be a thread-local + -- variable. + + -- Possible implementation of Get_Sec_Stack in a single-threaded + -- environment: + -- + -- Chunk : aliased Memory (1 .. Default_Secondary_Stack_Size); + -- for Chunk'Alignment use Standard'Maximum_Alignment; + -- -- The secondary stack. + -- + -- function Get_Sec_Stack return Stack_Ptr is + -- begin + -- return From_Addr (Chunk'Address); + -- end Get_Sec_Stack; + -- + -- begin + -- SS_Init (Chunk'Address, Default_Secondary_Stack_Size); + -- end System.Secondary_Stack; + + ----------------- + -- SS_Allocate -- + ----------------- + + procedure SS_Allocate + (Address : out System.Address; + Storage_Size : SSE.Storage_Count) + is + Max_Align : constant Mark_Id := Mark_Id (Standard'Maximum_Alignment); + Max_Size : constant Mark_Id := + ((Mark_Id (Storage_Size) + Max_Align - 1) / Max_Align) + * Max_Align; + Sec_Stack : constant Stack_Ptr := Get_Sec_Stack; + + begin + if Sec_Stack.Top + Max_Size > Sec_Stack.Last then + raise Storage_Error; + end if; + + Address := Sec_Stack.Mem (Sec_Stack.Top)'Address; + Sec_Stack.Top := Sec_Stack.Top + Mark_Id (Max_Size); + end SS_Allocate; + + ------------- + -- SS_Free -- + ------------- + + procedure SS_Free (Stk : in out System.Address) is + begin + Stk := Null_Address; + end SS_Free; + + ------------- + -- SS_Init -- + ------------- + + procedure SS_Init + (Stk : System.Address; + Size : Natural := Default_Secondary_Stack_Size) + is + Stack : Stack_Ptr := From_Addr (Stk); + begin + pragma Assert (Size >= 2 * Mark_Id'Max_Size_In_Storage_Elements); + + Stack.Top := Stack.Mem'First; + Stack.Last := Mark_Id (Size) - 2 * Mark_Id'Max_Size_In_Storage_Elements; + end SS_Init; + + ------------- + -- SS_Mark -- + ------------- + + function SS_Mark return Mark_Id is + begin + return Get_Sec_Stack.Top; + end SS_Mark; + + ---------------- + -- SS_Release -- + ---------------- + + procedure SS_Release (M : Mark_Id) is + begin + Get_Sec_Stack.Top := M; + end SS_Release; + +end System.Secondary_Stack; |