Ada Reference Manual (Ada 2022) — Legal Information

# 13.11.4 Storage Subpools

1/3
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

2/3
The following language-defined library package exists:
3/5
package System.Storage_Pools.Subpools
with Preelaborate, Global => in out synchronized is
4/5
type Root_Storage_Pool_With_Subpools is
abstract new Root_Storage_Pool with private
with Preelaborable_Initialization;
5/5
type Root_Subpool is abstract tagged limited private
with Preelaborable_Initialization;
6/3
type Subpool_Handle is access all Root_Subpool'Class;
for Subpool_Handle'Storage_Size use 0;
7/3
function Create_Subpool (Pool : in out Root_Storage_Pool_With_Subpools)
return not null Subpool_Handle is abstract;
8/3
-- The following operations are intended for pool implementers:
9/3
function Pool_of_Subpool (Subpool : not null Subpool_Handle)
return access Root_Storage_Pool_With_Subpools'Class;
10/5
procedure Set_Pool_of_Subpool (
Subpool : in not null Subpool_Handle;
To : in out Root_Storage_Pool_With_Subpools'Class)
with Global => overriding in out Subpool;
11/5
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,
Global => overriding in out Subpool;
12/3
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;
13/3
function Default_Subpool_for_Pool (
Pool : in out Root_Storage_Pool_With_Subpools)
return not null Subpool_Handle;
14/3
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);
15/3
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;
16/3
overriding
function Storage_Size (Pool : Root_Storage_Pool_With_Subpools)
return Storage_Elements.Storage_Count
is (Storage_Elements.Storage_Count'Last);
17/3
private
... -- not specified by the language
end System.Storage_Pools.Subpools;
18/3
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.
19/5
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 have to be exposed to clients of the storage pool. Subpool objects are designated by subpool handles, and are the run-time representation of a subpool.
20/4
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.
21/3
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

22/3
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.
23/3
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

24/3
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:
25/3
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
26/3
the accessibility level of the access type is not deeper than that of the storage pool object.
27/3
Program_Error is raised if either of these checks fail.
28/3
A call to Subpools.Allocate(P, Addr, Size, Align) does the following:
29/3
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)));
30/3
An allocator that allocates in a subpool raises Program_Error if the allocated object has task parts.
31/3
Unless overridden, Default_Subpool_for_Pool propagates Program_Error.

#### Erroneous Execution

31.1/4
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

32/3
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/5
NOTE 1 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 is expected to call Set_Pool_Of_Subpool before returning the subpool handle. To make use of such a pool, a user can declare an object of the type extension, can use it to define the Storage_Pool attribute of one or more access types, and then can invoke Create_Subpool to obtain subpool handles associated with the pool.
34/5
NOTE 2 A user-defined storage pool type that supports subpools can define additional subpool constructors similar to Create_Subpool (these typically will have additional parameters).
35/5
NOTE 3 The pool implementor can override Default_Subpool_For_Pool if they want the pool 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 desire for nontrivial initialization and finalization for the pool as a whole. For example, Finalize can reclaim blocks of storage that are allocated over and above the space occupied by the pool object itself. The pool implementor can 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