package GNATCOLL.Memory is
type size_t is mod 2 ** Standard'Address_Size;
-- Same as System.Memory.size_t, but defined here to avoid elaboration
-- circularity issues
type ssize_t is
range -(2**(Standard'Address_Size - 1)) ..
2**(Standard'Address_Size - 1) - 1;
-- Signed version of size_t.
function Alloc (Size : size_t) return System.Address;
-- This is the low level allocation routine. Given a size in storage
-- units, it returns the address of a maximally aligned block of
-- memory. The implementation of this routine is guaranteed to be
-- task safe, and also aborts are deferred if necessary.
--
-- If size_t is set to size_t'Last on entry, then a Storage_Error
-- exception is raised with a message "object too large".
--
-- If size_t is set to zero on entry, then a minimal (but non-zero)
-- size block is allocated.
--
-- Note: this is roughly equivalent to the standard C malloc call
-- with the additional semantics as described above.
procedure Free (Ptr : System.Address);
-- This is the low level free routine. It frees a block previously
-- allocated with a call to Alloc. As in the case of Alloc, this
-- call is guaranteed task safe, and aborts are deferred.
--
-- Note: this is roughly equivalent to the standard C free call
-- with the additional semantics as described above.
function Realloc
(Ptr : System.Address;
Size : size_t) return System.Address;
-- This is the low level reallocation routine. It takes an existing
-- block address returned by a previous call to Alloc or Realloc,
-- and reallocates the block. The size can either be increased or
-- decreased. If possible the reallocation is done in place, so that
-- the returned result is the same as the value of Ptr on entry.
-- However, it may be necessary to relocate the block to another
-- address, in which case the information is copied to the new
-- block, and the old block is freed. The implementation of this
-- routine is guaranteed to be task safe, and also aborts are
-- deferred as necessary.
--
-- If size_t is set to size_t'Last on entry, then a Storage_Error
-- exception is raised with a message "object too large".
--
-- If size_t is set to zero on entry, then a minimal (but non-zero)
-- size block is allocated.
--
-- Note: this is roughly equivalent to the standard C realloc call
-- with the additional semantics as described above.
-------------
-- Monitor --
-------------
procedure Configure
(Activate_Monitor : Boolean := False;
Disable_Free : Boolean := False;
Stack_Trace_Depth : Natural := 30;
Maximum_Logically_Freed_Memory : Long_Long_Integer := 50_000_000;
Minimum_To_Free : Long_Long_Integer := 0;
Reset_Content_On_Free : Boolean := True;
Raise_Exceptions : Boolean := False;
Advanced_Scanning : Boolean := False;
Errors_To_Stdout : Boolean := True;
Low_Level_Traces : Boolean := False);
-- Configure this package (these are global settings, not task-specific).
--
-- If Activate_Monitor is true, GPS will monitor all memory allocations and
-- deallocations, and through the Dump procedure below be able to report
-- the memory usage. The overhead is almost null when the monitor is
-- disabled.
--
-- If Disable_Free is true, no deallocation is ever performed. This can be
-- temporarily useful when investigating memory issues.
--
-- Stack_Trace_Depth. This parameter controls the maximum depth of stack
-- traces that are output to indicate locations of actions for error
-- conditions such as bad allocations. If set to zero, the debug pool
-- will not try to compute backtraces. This is more efficient but gives
-- less information on problem locations (and in particular, this
-- disables the tracking of the biggest users of memory).
--
-- Maximum_Logically_Freed_Memory: maximum amount of memory (bytes)
-- that should be kept before starting to physically deallocate some.
-- This value should be non-zero, since having memory that is logically
-- but not physically freed helps to detect invalid memory accesses.
--
-- Minimum_To_Free is the minimum amount of memory that should be freed
-- every time the pool starts physically releasing memory. The algorithm
-- to compute which block should be physically released needs some
-- expensive initialization (see Advanced_Scanning below), and this
-- parameter can be used to limit the performance impact by ensuring
-- that a reasonable amount of memory is freed each time. Even in the
-- advanced scanning mode, marked blocks may be released to match this
-- Minimum_To_Free parameter.
--
-- Reset_Content_On_Free: If true, then the contents of the freed memory
-- is reset to the pattern 16#DEADBEEF#, following an old IBM convention.
-- This helps in detecting invalid memory references from the debugger.
--
-- Raise_Exceptions: If true, the exceptions below will be raised every
-- time an error is detected. If you set this to False, then the action
-- is to generate output on standard error or standard output, depending
-- on Errors_To_Stdout, noting the errors, but to
-- keep running if possible (of course if storage is badly damaged, this
-- attempt may fail. This helps to detect more than one error in a run.
--
-- Advanced_Scanning: If true, the pool will check the contents of all
-- allocated blocks before physically releasing memory. Any possible
-- reference to a logically free block will prevent its deallocation.
-- Note that this algorithm is approximate, and it is recommended
-- that you set Minimum_To_Free to a non-zero value to save time.
--
-- Errors_To_Stdout: Errors messages will be displayed on stdout if
-- this parameter is True, or to stderr otherwise.
--
-- Low_Level_Traces: Traces all allocation and deallocations on the
-- stream specified by Errors_To_Stdout. This can be used for
-- post-processing by your own application, or to debug the
-- debug_pool itself. The output indicates the size of the allocated
-- block both as requested by the application and as physically
-- allocated to fit the additional information needed by the debug
-- pool.
type Report_Type is new GNAT.Debug_Pools.Report_Type;
generic
with procedure Put_Line (S : String) is <>;
with procedure Put (S : String) is <>;
procedure Redirectable_Dump
(Size : Positive;
Report : Report_Type := All_Reports);
-- Dump information about memory usage to configurable output
-- Size is the number of the biggest memory users we want to show. Report
-- indicates which sorting order is used in the report
procedure Dump (Size : Positive; Report : Report_Type := All_Reports);
-- Dump information about memory usage.
-- Size is the number of the biggest memory users we want to show
-- (requires that the Debug_Pool has been configured with Stack_Trace_Depth
-- greater than zero). Also, for efficiency reasons, tracebacks with
-- a memory allocation below 1_000 bytes are not shown in the "biggest
-- memory users" part of the report.
-- Report indicates which sorting order is used in the report.
procedure Reset;
-- Reset all internal data. This is in general not needed, unless you want
-- to know what memory is used by specific parts of your application
procedure Mark_Traceback;
-- Add a special chunk in the monitor for the current traceback. This is
-- a convenient way to check how many times we go through a given path,
-- and where this is called from.
-- Nothing is done if the memory monitor has not been activated
type Byte_Count is new GNAT.Debug_Pools.Byte_Count;
type Watermark_Info is record
High : Byte_Count;
Current : Byte_Count;
end record;
function Get_Ada_Allocations return Watermark_Info;
-- Return information about the allocations done from Ada.
-- This does not include allocations done from other languages.
function Get_Allocations return Watermark_Info;
-- Return information about the allocations done in any language.
-- This uses system calls to find out the program's resident size (RSS)
-- information, both the peak and the current size.
end GNATCOLL.Memory;