File: gnatcoll-memory.ads

package info (click to toggle)
libgnatcoll 18-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 5,068 kB
  • sloc: ada: 40,393; python: 354; ansic: 310; makefile: 245; sh: 31
file content (237 lines) | stat: -rw-r--r-- 11,604 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
------------------------------------------------------------------------------
--                             G N A T C O L L                              --
--                                                                          --
--                     Copyright (C) 2005-2017, AdaCore                     --
--                                                                          --
-- This library is free software;  you can redistribute it and/or modify it --
-- under terms of the  GNU General Public License  as published by the Free --
-- Software  Foundation;  either version 3,  or (at your  option) any later --
-- version. This library is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- --
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE.                            --
--                                                                          --
--                                                                          --
--                                                                          --
--                                                                          --
--                                                                          --
-- 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/>.                                          --
--                                                                          --
------------------------------------------------------------------------------

--  This package provides a reimplementation of GNAT's low-level memory
--  allocation mechanism. Its goal is to provide an additional monitoring
--  facility to check where your program allocates memory.
--
--  To activate this alternates implementation in your application, you
--  must provide your own s-memory.adb somewhere in your source directories.
--  Then simply recompile the modified body of that package with
--  gnatmake -u -a -g s-memory.adb (or use the -a switch when you compile
--  your own application) and make sure that the ali and object files for
--  this unit are found in the object search path.
--
--  Your version of System.Memory (in file s-memory.adb) should be:
--
--  with GNATCOLL.Memory;
--  package body System.Memory is
--     package M renames GNATCOLL.Memory;
--
--     function Alloc (Size : size_t) return System.Address is
--     begin
--        return M.Alloc (M.size_t (Size));
--     end Alloc;
--
--     procedure Free (Ptr : System.Address)
--        renames M.Free;
--
--     function Realloc
--        (Ptr  : System.Address;
--         Size : size_t)
--        return System.Address is
--     begin
--        return M.Realloc (Ptr, M.size_t (Size));
--     end Realloc;
--  end System.Memory;
--
--  As a child package of System, this package must be compiled with -gnatg
--  switch to the compiler.

with System; use System;
with GNAT.Debug_Pools; use GNAT.Debug_Pools;

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

   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
   --
   --    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. 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.

private

   pragma Convention (C, Alloc);
   pragma Convention (C, Free);
   pragma Convention (C, Realloc);

end GNATCOLL.Memory;