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