blob: f65bdef08cf576f5c6d21eac5769f5cb84333e0e [file] [log] [blame]
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- S Y S T E M . S E C O N D A R Y _ S T A C K --
-- --
-- S p e c --
-- --
-- Copyright (C) 1992-2018, 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 3, 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. --
-- --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception, --
-- version 3.1, as published by the Free Software Foundation. --
-- --
-- You should have received a copy of the GNU General Public License and --
-- a copy of the GCC Runtime Library Exception along with this program; --
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
-- <http://www.gnu.org/licenses/>. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
pragma Compiler_Unit_Warning;
with System.Parameters;
with System.Storage_Elements;
package System.Secondary_Stack is
pragma Preelaborate;
package SP renames System.Parameters;
package SSE renames System.Storage_Elements;
type SS_Stack (Size : SP.Size_Type) is private;
-- Data structure for secondary stacks
type SS_Stack_Ptr is access all SS_Stack;
-- Pointer to secondary stack objects
procedure SS_Init
(Stack : in out SS_Stack_Ptr;
Size : SP.Size_Type := SP.Unspecified_Size);
-- Initialize the secondary stack Stack. If Stack is null allocate a stack
-- from the heap or from the default-sized secondary stack pool if the
-- pool exists and the requested size is Unspecified_Size.
procedure SS_Allocate
(Addr : out Address;
Storage_Size : SSE.Storage_Count);
-- Allocate enough space for a 'Storage_Size' bytes object with Maximum
-- alignment. The address of the allocated space is returned in Addr.
procedure SS_Free (Stack : in out SS_Stack_Ptr);
-- Release the memory allocated for the Stack. If the stack was statically
-- allocated the SS_Stack record is not freed.
type Mark_Id is private;
-- Type used to mark the stack for mark/release processing
function SS_Mark return Mark_Id;
-- Return the Mark corresponding to the current state of the stack
procedure SS_Release (M : Mark_Id);
-- Restore the state of the stack corresponding to the mark M
function SS_Get_Max return Long_Long_Integer;
-- Return the high water mark of the secondary stack for the current
-- secondary stack in bytes.
generic
with procedure Put_Line (S : String);
procedure SS_Info;
-- Debugging procedure used to print out secondary Stack allocation
-- information. This procedure is generic in order to avoid a direct
-- dependance on a particular IO package.
private
SS_Pool : Integer;
-- Unused entity that is just present to ease the sharing of the pool
-- mechanism for specific allocation/deallocation in the compiler
-------------------------------------
-- Secondary Stack Data Structures --
-------------------------------------
-- This package provides fixed and dynamically sized secondary stack
-- implementations centered around a common data structure SS_Stack. This
-- record contains an initial secondary stack allocation of the requested
-- size, and markers for the current top of the stack and the high-water
-- mark of the stack. A SS_Stack can be either pre-allocated outside the
-- package or SS_Init can allocate a stack from the heap or the
-- default-sized secondary stack from a pool generated by the binder.
-- For dynamically allocated secondary stacks, the stack can grow via a
-- linked list of stack chunks allocated from the heap. New chunks are
-- allocated once the initial static allocation and any existing chunks are
-- exhausted. The following diagram illustrated the data structures used
-- for a dynamically allocated secondary stack:
--
-- +------------------+
-- | Next |
-- +------------------+
-- | | Last (300)
-- | |
-- | |
-- | |
-- | |
-- | |
-- | | First (201)
-- +------------------+
-- +-----------------+ +------> | | |
-- | | (100) | +--------- | ------+
-- | | | ^ |
-- | | | | |
-- | | | | V
-- | | | +------ | ---------+
-- | | | | | |
-- | | | +------------------+
-- | | | | | Last (200)
-- | | | | C |
-- | | (1) | | H |
-- +-----------------+ | +---->| U |
-- | Current_Chunk ---------+ | | N |
-- +-----------------+ | | K |
-- | Top ------------+ | | First (101)
-- +-----------------+ +------------------+
-- | Size | | Prev |
-- +-----------------+ +------------------+
--
-- The implementation used by the runtime is controlled via the constant
-- System.Parameter.Sec_Stack_Dynamic. If True, the implementation is
-- permitted to grow the secondary stack at runtime. The implementation is
-- designed for the compiler to include only code to support the desired
-- secondary stack behavior.
subtype SS_Ptr is SP.Size_Type;
-- Stack pointer value for the current position within the secondary stack.
-- Size_Type is used as the base type since the Size discriminate of
-- SS_Stack forms the bounds of the internal memory array.
type Memory is array (SS_Ptr range <>) of SSE.Storage_Element;
for Memory'Alignment use Standard'Maximum_Alignment;
-- The region of memory that holds the stack itself. Requires maximum
-- alignment for efficient stack operations.
-- Chunk_Id
-- Chunk_Id is a contiguous block of dynamically allocated stack. First
-- and Last indicate the range of secondary stack addresses present in the
-- chunk. Chunk_Ptr points to a Chunk_Id block.
type Chunk_Id (First, Last : SS_Ptr);
type Chunk_Ptr is access all Chunk_Id;
type Chunk_Id (First, Last : SS_Ptr) is record
Prev, Next : Chunk_Ptr;
Mem : Memory (First .. Last);
end record;
-- Secondary stack data structure
type SS_Stack (Size : SP.Size_Type) is record
Top : SS_Ptr;
-- Index of next available location in the stack. Initialized to 1 and
-- then incremented on Allocate and decremented on Release.
Max : SS_Ptr;
-- Contains the high-water mark of Top. Initialized to 1 and then
-- may be incremented on Allocate but never decremented. Since
-- Top = Size + 1 represents a fully used stack, Max - 1 indicates
-- the size of the stack used in bytes.
Current_Chunk : Chunk_Ptr;
-- A link to the chunk containing the highest range of the stack
Freeable : Boolean;
-- Indicates if an object of this type can be freed
Internal_Chunk : aliased Chunk_Id (1, Size);
-- Initial memory allocation of the secondary stack
end record;
type Mark_Id is record
Sec_Stack : SS_Stack_Ptr;
Sptr : SS_Ptr;
end record;
-- Contains the pointer to the secondary stack object and the stack pointer
-- value corresponding to the top of the stack at the time of the mark
-- call.
------------------------------------
-- Binder Allocated Stack Support --
------------------------------------
-- When the No_Implicit_Heap_Allocations or No_Implicit_Task_Allocations
-- restrictions are in effect the binder statically generates secondary
-- stacks for tasks who are using default-sized secondary stack. Assignment
-- of these stacks to tasks is handled by SS_Init. The following variables
-- assist SS_Init and are defined here so the runtime does not depend on
-- the binder.
Binder_SS_Count : Natural;
pragma Export (Ada, Binder_SS_Count, "__gnat_binder_ss_count");
-- The number of default sized secondary stacks allocated by the binder
Default_SS_Size : SP.Size_Type;
pragma Export (Ada, Default_SS_Size, "__gnat_default_ss_size");
-- The default size for secondary stacks. Defined here and not in init.c/
-- System.Init because these locations are not present on ZFP or
-- Ravenscar-SFP run-times.
Default_Sized_SS_Pool : System.Address;
pragma Export (Ada, Default_Sized_SS_Pool, "__gnat_default_ss_pool");
-- Address to the secondary stack pool generated by the binder that
-- contains default sized stacks.
Num_Of_Assigned_Stacks : Natural := 0;
-- The number of currently allocated secondary stacks
end System.Secondary_Stack;