13.11.4 Storage Subpools
This subclause defines a package to support the partitioning 
of a storage pool into subpools. A subpool may be specified as the default 
to be used for allocation from the associated storage pool, or a particular 
subpool may be specified as part of an 
allocator 
(see 
4.8). 
Static Semantics
The following language-defined library package exists:
package System.Storage_Pools.Subpools 
is
   pragma Preelaborate (Subpools);
 
   type Root_Storage_Pool_With_Subpools 
is
      abstract new Root_Storage_Pool 
with private;
 
   type Root_Subpool 
is abstract tagged limited private;
 
   type Subpool_Handle 
is access all Root_Subpool'Class;
   
for Subpool_Handle'Storage_Size 
use 0;
 
   function Create_Subpool (Pool : 
in out Root_Storage_Pool_With_Subpools)
      
return not null Subpool_Handle 
is abstract;
 
   -- The following operations are intended for pool implementers:
   function Pool_of_Subpool (Subpool : 
not null Subpool_Handle)
      
return access Root_Storage_Pool_With_Subpools'Class;
 
   procedure Set_Pool_of_Subpool (
      Subpool : 
in not null Subpool_Handle;
      To : 
in out Root_Storage_Pool_With_Subpools'Class);
 
   procedure Allocate_From_Subpool (
      Pool : 
in out Root_Storage_Pool_With_Subpools;
      Storage_Address : 
out Address;
      Size_In_Storage_Elements : 
in Storage_Elements.Storage_Count;
      Alignment : 
in Storage_Elements.Storage_Count;
      Subpool : 
in not null Subpool_Handle) 
is abstract
         with Pre'Class => Pool_of_Subpool(Subpool) = Pool'Access;
 
   procedure Deallocate_Subpool (
      Pool : 
in out Root_Storage_Pool_With_Subpools;
      Subpool : 
in out Subpool_Handle) 
is abstract
         with Pre'Class => Pool_of_Subpool(Subpool) = Pool'Access;
 
   function Default_Subpool_for_Pool (
      Pool : 
in out Root_Storage_Pool_With_Subpools)
         
return not null Subpool_Handle;
 
   overriding
   procedure Allocate (
      Pool : 
in out Root_Storage_Pool_With_Subpools;
      Storage_Address : 
out Address;
      Size_In_Storage_Elements : 
in Storage_Elements.Storage_Count;
      Alignment : 
in Storage_Elements.Storage_Count);
 
   overriding
   procedure Deallocate (
      Pool : 
in out Root_Storage_Pool_With_Subpools;
      Storage_Address : 
in Address;
      Size_In_Storage_Elements : 
in Storage_Elements.Storage_Count;
      Alignment : 
in Storage_Elements.Storage_Count) 
is null;
 
   overriding
   function Storage_Size (Pool : Root_Storage_Pool_With_Subpools)
      
return Storage_Elements.Storage_Count
          
is (Storage_Elements.Storage_Count'Last);
 
private
   ... -- not specified by the language
end System.Storage_Pools.Subpools;
 A 
subpool is a separately reclaimable portion of a storage pool, 
identified by an object of type Subpool_Handle (a 
subpool handle). 
A subpool handle also identifies the enclosing storage pool, a 
storage 
pool that supports subpools, which is a storage pool whose type is 
descended from Root_Storage_Pool_With_Subpools. A subpool is created 
by calling Create_Subpool or a similar constructor; the constructor returns 
the subpool handle.
 
 A subpool object is an object of a type descended 
from Root_Subpool. Typically, subpool objects are managed by the containing 
storage pool; only the handles need be exposed to clients of the storage 
pool. Subpool objects are designated by subpool handles, and are the 
run-time representation of a subpool.
 Each subpool 
belongs 
to a single storage pool (which will always be a pool that supports subpools). 
An access to the pool that a subpool belongs to can be obtained by calling 
Pool_of_Subpool with the subpool handle. Set_Pool_of_Subpool causes the 
subpool of the subpool handle to belong to the given pool; this is intended 
to be called from subpool constructors like Create_Subpool. Set_Pool_of_Subpool 
propagates Program_Error if the subpool already belongs to a pool. If 
Set_Pool_of_Subpool has not yet been called for a subpool, Pool_of_Subpool 
returns 
null.
 When an 
allocator 
for a type whose storage pool supports subpools is evaluated, a call 
is made on Allocate_From_Subpool passing in a Subpool_Handle, in addition 
to the parameters as defined for calls on Allocate (see 
13.11). 
The subpool designated by the 
subpool_handle_name 
is used, if specified in an 
allocator. 
Otherwise, Default_Subpool_for_Pool of the Pool is used to provide a 
subpool handle. All requirements on the Allocate procedure also apply 
to Allocate_from_Subpool.
Legality Rules
 If a storage pool that supports subpools is specified 
as the Storage_Pool for an access type, the access type is called a 
subpool 
access type.
 A subpool access 
type shall be a pool-specific access type.
 The accessibility level of a subpool access type 
shall not be statically deeper than that of the storage pool object. 
If the specified storage pool object is a storage pool that supports 
subpools, then the 
name 
that denotes the object shall not denote part of a formal parameter, 
nor shall it denote part of a dereference of a value of a non-library-level 
general access type. 
In addition to the places where 
Legality Rules normally apply (see 
12.3), 
these rules also apply in the private part of an instance of a generic 
unit. 
Dynamic Semantics
 When an access type 
with a specified storage pool is frozen (see 
13.14), 
if the tag of the storage pool object identifies a storage pool that 
supports subpools, the following checks are made:
the 
name 
used to specify the storage pool object does not denote part of a formal 
parameter nor part of a dereference of a value of a non-library-level 
general access type; and
the accessibility level of the access type is not 
deeper than that of the storage pool object.
 
 Program_Error is raised 
if either of these checks fail.
 A call to Subpools.Allocate(P, 
Addr, Size, Align) does the following:
Allocate_From_Subpool
  (Root_Storage_Pool_With_Subpools'Class(P),
   Addr, Size, Align,
   Subpool => Default_Subpool_for_Pool
                (Root_Storage_Pool_With_Subpools'Class(P)));
 An 
allocator 
that allocates in a subpool raises Program_Error if the allocated object 
has task parts.
 Unless overridden, Default_Subpool_for_Pool propagates 
Program_Error.
Erroneous Execution
   If Allocate_From_Subpool does 
not meet one or more of the requirements on the Allocate procedure as 
given in the Erroneous Execution rules of 
13.11, 
then the program execution is erroneous. 
 
Implementation Permissions
 When an allocator for a type whose storage pool 
is of type Root_Storage_Pool'Class is evaluated, but supports subpools, 
the implementation may call Allocate rather than Allocate_From_Subpool. 
This will have the same effect, so long as Allocate has not been overridden.
33  A user-defined storage pool type that 
supports subpools can be implemented by extending the Root_Storage_Pool_With_Subpools 
type, and overriding the primitive subprograms Create_Subpool, Allocate_From_Subpool, 
and Deallocate_Subpool. Create_Subpool should call Set_Pool_Of_Subpool 
before returning the subpool handle. To make use of such a pool, a user 
would declare an object of the type extension, use it to define the Storage_Pool 
attribute of one or more access types, and then call Create_Subpool to 
obtain subpool handles associated with the pool.
34  A user-defined storage pool type that 
supports subpools may define additional subpool constructors similar 
to Create_Subpool (these typically will have additional parameters).
35  The pool implementor should override 
Default_Subpool_For_Pool if the pool is to support a default subpool 
for the pool. The implementor can override Deallocate if individual object 
reclamation is to be supported, and can override Storage_Size if there 
is some limit on the total size of the storage pool. The implementor 
can override Initialize and Finalize if there is any need for nontrivial 
initialization and finalization for the pool as a whole. For example, 
Finalize might reclaim blocks of storage that are allocated over and 
above the space occupied by the pool object itself. The pool implementor 
may extend the Root_Subpool type as necessary to carry additional information 
with each subpool provided by Create_Subpool.
 Ada 2005 and 2012 Editions sponsored in part by Ada-Europe
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe