1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- S Y S T E M . S T O R A G E _ P O O L S . S U B P O O L S --
9 -- Copyright (C) 2011-2014, Free Software Foundation, Inc. --
11 -- This specification is derived from the Ada Reference Manual for use with --
12 -- GNAT. The copyright notice above, and the license provisions that follow --
13 -- apply solely to the contents of the part following the private keyword. --
15 -- GNAT is free software; you can redistribute it and/or modify it under --
16 -- terms of the GNU General Public License as published by the Free Soft- --
17 -- ware Foundation; either version 3, or (at your option) any later ver- --
18 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
19 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
20 -- or FITNESS FOR A PARTICULAR PURPOSE. --
22 -- As a special exception under Section 7 of GPL version 3, you are granted --
23 -- additional permissions described in the GCC Runtime Library Exception, --
24 -- version 3.1, as published by the Free Software Foundation. --
26 -- You should have received a copy of the GNU General Public License and --
27 -- a copy of the GCC Runtime Library Exception along with this program; --
28 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
29 -- <http://www.gnu.org/licenses/>. --
31 -- GNAT was originally developed by the GNAT team at New York University. --
32 -- Extensive contributions were provided by Ada Core Technologies Inc. --
34 ------------------------------------------------------------------------------
36 with Ada
.Finalization
;
37 with System
.Finalization_Masters
;
38 with System
.Storage_Elements
;
40 package System
.Storage_Pools
.Subpools
is
43 type Root_Storage_Pool_With_Subpools
is abstract
44 new Root_Storage_Pool
with private;
45 -- The base for all implementations of Storage_Pool_With_Subpools. This
46 -- type is Limited_Controlled by derivation. To use subpools, an access
47 -- type must be associated with an implementation descending from type
48 -- Root_Storage_Pool_With_Subpools.
50 type Root_Subpool
is abstract tagged limited private;
51 -- The base for all implementations of Subpool. Objects of this type are
52 -- managed by the pool_with_subpools.
54 type Subpool_Handle
is access all Root_Subpool
'Class;
55 for Subpool_Handle
'Storage_Size use 0;
56 -- Since subpools are limited types by definition, a handle is instead used
57 -- to manage subpool abstractions.
59 overriding
procedure Allocate
60 (Pool
: in out Root_Storage_Pool_With_Subpools
;
61 Storage_Address
: out System
.Address
;
62 Size_In_Storage_Elements
: System
.Storage_Elements
.Storage_Count
;
63 Alignment
: System
.Storage_Elements
.Storage_Count
);
64 -- Allocate an object described by Size_In_Storage_Elements and Alignment
65 -- on the default subpool of Pool. Controlled types allocated through this
66 -- routine will NOT be handled properly.
68 procedure Allocate_From_Subpool
69 (Pool
: in out Root_Storage_Pool_With_Subpools
;
70 Storage_Address
: out System
.Address
;
71 Size_In_Storage_Elements
: System
.Storage_Elements
.Storage_Count
;
72 Alignment
: System
.Storage_Elements
.Storage_Count
;
73 Subpool
: not null Subpool_Handle
) is abstract;
75 -- ??? This precondition causes errors in simple tests, disabled for now
77 -- with Pre'Class => Pool_Of_Subpool (Subpool) = Pool'Access;
78 -- This routine requires implementation. Allocate an object described by
79 -- Size_In_Storage_Elements and Alignment on a subpool.
81 function Create_Subpool
82 (Pool
: in out Root_Storage_Pool_With_Subpools
)
83 return not null Subpool_Handle
is abstract;
84 -- This routine requires implementation. Create a subpool within the given
85 -- pool_with_subpools.
87 overriding
procedure Deallocate
88 (Pool
: in out Root_Storage_Pool_With_Subpools
;
89 Storage_Address
: System
.Address
;
90 Size_In_Storage_Elements
: System
.Storage_Elements
.Storage_Count
;
91 Alignment
: System
.Storage_Elements
.Storage_Count
)
94 procedure Deallocate_Subpool
95 (Pool
: in out Root_Storage_Pool_With_Subpools
;
96 Subpool
: in out Subpool_Handle
)
98 -- This precondition causes errors in simple tests, disabled for now???
99 -- with Pre'Class => Pool_Of_Subpool (Subpool) = Pool'Access;
101 -- This routine requires implementation. Reclaim the storage a particular
102 -- subpool occupies in a pool_with_subpools. This routine is called by
103 -- Ada.Unchecked_Deallocate_Subpool.
105 function Default_Subpool_For_Pool
106 (Pool
: in out Root_Storage_Pool_With_Subpools
)
107 return not null Subpool_Handle
;
108 -- Return a common subpool which is used for object allocations without a
109 -- Subpool_Handle_name in the allocator. The default implementation of this
110 -- routine raises Program_Error.
112 function Pool_Of_Subpool
113 (Subpool
: not null Subpool_Handle
)
114 return access Root_Storage_Pool_With_Subpools
'Class;
115 -- Return the owner of the subpool
117 procedure Set_Pool_Of_Subpool
118 (Subpool
: not null Subpool_Handle
;
119 To
: in out Root_Storage_Pool_With_Subpools
'Class);
120 -- Set the owner of the subpool. This is intended to be called from
121 -- Create_Subpool or similar subpool constructors. Raises Program_Error
122 -- if the subpool already belongs to a pool.
124 overriding
function Storage_Size
125 (Pool
: Root_Storage_Pool_With_Subpools
)
126 return System
.Storage_Elements
.Storage_Count
128 (System
.Storage_Elements
.Storage_Count
'Last);
132 -- Pool_With_Subpools SP_Node SP_Node SP_Node
133 -- +-->+--------------------+ +-----+ +-----+ +-----+
134 -- | | Subpools -------->| ------->| ------->| ------->
135 -- | +--------------------+ +-----+ +-----+ +-----+
136 -- | |Finalization_Started|<------ |<------- |<------- |<---
137 -- | +--------------------+ +-----+ +-----+ +-----+
138 -- +--- Controller.Encl_Pool| | nul | | + | | + |
139 -- | +--------------------+ +-----+ +--|--+ +--:--+
142 -- | Root_Subpool V |
143 -- | +-------------+ |
144 -- +-------------------------------- Owner | |
145 -- FM_Node FM_Node +-------------+ |
146 -- +-----+ +-----+<-- Master.Objects| |
147 -- <------ |<------ | +-------------+ |
148 -- +-----+ +-----+ | Node -------+
149 -- | ------>| -----> +-------------+
150 -- +-----+ +-----+ : :
155 -- SP_Nodes are created on the heap. FM_Nodes and associated objects are
156 -- created on the pool_with_subpools.
158 type Any_Storage_Pool_With_Subpools_Ptr
159 is access all Root_Storage_Pool_With_Subpools
'Class;
160 for Any_Storage_Pool_With_Subpools_Ptr
'Storage_Size use 0;
162 -- A pool controller is a special controlled object which ensures the
163 -- proper initialization and finalization of the enclosing pool.
165 type Pool_Controller
(Enclosing_Pool
: Any_Storage_Pool_With_Subpools_Ptr
)
166 is new Ada
.Finalization
.Limited_Controlled
with null record;
168 -- Subpool list types. Each pool_with_subpools contains a list of subpools.
169 -- This is an indirect doubly linked list since subpools are not supposed
170 -- to be allocatable by language design.
173 type SP_Node_Ptr
is access all SP_Node
;
175 type SP_Node
is record
176 Prev
: SP_Node_Ptr
:= null;
177 Next
: SP_Node_Ptr
:= null;
178 Subpool
: Subpool_Handle
:= null;
181 -- Root_Storage_Pool_With_Subpools internal structure. The type uses a
182 -- special controller to perform initialization and finalization actions
183 -- on itself. This is necessary because the end user of this package may
184 -- decide to override Initialize and Finalize, thus disabling the desired
187 -- Pool_With_Subpools SP_Node SP_Node SP_Node
188 -- +-->+--------------------+ +-----+ +-----+ +-----+
189 -- | | Subpools -------->| ------->| ------->| ------->
190 -- | +--------------------+ +-----+ +-----+ +-----+
191 -- | |Finalization_Started| : : : : : :
192 -- | +--------------------+
193 -- +--- Controller.Encl_Pool|
194 -- +--------------------+
198 type Root_Storage_Pool_With_Subpools
is abstract
199 new Root_Storage_Pool
with
201 Subpools
: aliased SP_Node
;
202 -- A doubly linked list of subpools
204 Finalization_Started
: Boolean := False;
205 pragma Atomic
(Finalization_Started
);
206 -- A flag which prevents the creation of new subpools while the master
207 -- pool is being finalized. The flag needs to be atomic because it is
208 -- accessed without Lock_Task / Unlock_Task.
210 Controller
: Pool_Controller
211 (Root_Storage_Pool_With_Subpools
'Unchecked_Access);
212 -- A component which ensures that the enclosing pool is initialized and
213 -- finalized at the appropriate places.
216 -- A subpool is an abstraction layer which sits on top of a pool. It
217 -- contains links to all controlled objects allocated on a particular
220 -- Pool_With_Subpools SP_Node SP_Node SP_Node
221 -- +-->+----------------+ +-----+ +-----+ +-----+
222 -- | | Subpools ------>| ------->| ------->| ------->
223 -- | +----------------+ +-----+ +-----+ +-----+
224 -- | : :<------ |<------- |<------- |
225 -- | : : +-----+ +-----+ +-----+
226 -- | |null | | + | | + |
227 -- | +-----+ +--|--+ +--:--+
229 -- | Root_Subpool V |
230 -- | +-------------+ |
231 -- +---------------------------- Owner | |
233 -- .......... Master | |
240 type Root_Subpool
is abstract tagged limited record
241 Owner
: Any_Storage_Pool_With_Subpools_Ptr
:= null;
242 -- A reference to the master pool_with_subpools
244 Master
: aliased System
.Finalization_Masters
.Finalization_Master
;
245 -- A heterogeneous collection of controlled objects
247 Node
: SP_Node_Ptr
:= null;
248 -- A link to the doubly linked list node which contains the subpool.
249 -- This back pointer is used in subpool deallocation.
252 procedure Adjust_Controlled_Dereference
253 (Addr
: in out System
.Address
;
254 Storage_Size
: in out System
.Storage_Elements
.Storage_Count
;
255 Alignment
: System
.Storage_Elements
.Storage_Count
);
256 -- Given the memory attributes of a heap-allocated object that is known to
257 -- be controlled, adjust the address and size of the object to include the
258 -- two hidden pointers inserted by the finalization machinery.
260 -- ??? Once Storage_Pools.Allocate_Any is removed, this should be renamed
263 procedure Allocate_Any_Controlled
264 (Pool
: in out Root_Storage_Pool
'Class;
265 Context_Subpool
: Subpool_Handle
;
266 Context_Master
: Finalization_Masters
.Finalization_Master_Ptr
;
267 Fin_Address
: Finalization_Masters
.Finalize_Address_Ptr
;
268 Addr
: out System
.Address
;
269 Storage_Size
: System
.Storage_Elements
.Storage_Count
;
270 Alignment
: System
.Storage_Elements
.Storage_Count
;
271 Is_Controlled
: Boolean;
272 On_Subpool
: Boolean);
273 -- Compiler interface. This version of Allocate handles all possible cases,
274 -- either on a pool or a pool_with_subpools, regardless of the controlled
275 -- status of the allocated object. Parameter usage:
277 -- * Pool - The pool associated with the access type. Pool can be any
278 -- derivation from Root_Storage_Pool, including a pool_with_subpools.
280 -- * Context_Subpool - The subpool handle name of an allocator. If no
281 -- subpool handle is present at the point of allocation, the actual
284 -- * Context_Master - The finalization master associated with the access
285 -- type. If the access type's designated type is not controlled, the
286 -- actual would be null.
288 -- * Fin_Address - TSS routine Finalize_Address of the designated type.
289 -- If the designated type is not controlled, the actual would be null.
291 -- * Addr - The address of the allocated object.
293 -- * Storage_Size - The size of the allocated object.
295 -- * Alignment - The alignment of the allocated object.
297 -- * Is_Controlled - A flag which determines whether the allocated object
298 -- is controlled. When set to True, the machinery generates additional
301 -- * On_Subpool - A flag which determines whether the a subpool handle
302 -- name is present at the point of allocation. This is used for error
305 procedure Deallocate_Any_Controlled
306 (Pool
: in out Root_Storage_Pool
'Class;
307 Addr
: System
.Address
;
308 Storage_Size
: System
.Storage_Elements
.Storage_Count
;
309 Alignment
: System
.Storage_Elements
.Storage_Count
;
310 Is_Controlled
: Boolean);
311 -- Compiler interface. This version of Deallocate handles all possible
312 -- cases, either from a pool or a pool_with_subpools, regardless of the
313 -- controlled status of the deallocated object. Parameter usage:
315 -- * Pool - The pool associated with the access type. Pool can be any
316 -- derivation from Root_Storage_Pool, including a pool_with_subpools.
318 -- * Addr - The address of the allocated object.
320 -- * Storage_Size - The size of the allocated object.
322 -- * Alignment - The alignment of the allocated object.
324 -- * Is_Controlled - A flag which determines whether the allocated object
325 -- is controlled. When set to True, the machinery generates additional
328 procedure Detach
(N
: not null SP_Node_Ptr
);
329 -- Unhook a subpool node from an arbitrary subpool list
331 overriding
procedure Finalize
(Controller
: in out Pool_Controller
);
332 -- Buffer routine, calls Finalize_Pool
334 procedure Finalize_Pool
(Pool
: in out Root_Storage_Pool_With_Subpools
);
335 -- Iterate over all subpools of Pool, detach them one by one and finalize
336 -- their masters. This action first detaches a controlled object from a
337 -- particular master, then invokes its Finalize_Address primitive.
339 function Header_Size_With_Padding
340 (Alignment
: System
.Storage_Elements
.Storage_Count
)
341 return System
.Storage_Elements
.Storage_Count
;
342 -- Given an arbitrary alignment, calculate the size of the header which
343 -- precedes a controlled object as the nearest multiple rounded up of the
346 overriding
procedure Initialize
(Controller
: in out Pool_Controller
);
347 -- Buffer routine, calls Initialize_Pool
349 procedure Initialize_Pool
(Pool
: in out Root_Storage_Pool_With_Subpools
);
350 -- Setup the doubly linked list of subpools
352 procedure Print_Pool
(Pool
: Root_Storage_Pool_With_Subpools
);
353 -- Debug routine, output the contents of a pool_with_subpools
355 procedure Print_Subpool
(Subpool
: Subpool_Handle
);
356 -- Debug routine, output the contents of a subpool
358 end System
.Storage_Pools
.Subpools
;