Spec-Zone.ru › Ada 2022
Руководство по Ada (Ada 2022)

13.11.4 Подпулы памяти

Этот подпункт определяет пакет для поддержки разбиения пула памяти на подпулы. Подпул может быть указан как по умолчанию для выделения из соответствующего пула памяти, или определенный подпул может быть указан как часть аллокатора (см. 4.8).

Статическая семантика

Существует следующий определённый в языке библиотечный пакет:
package System.Storage_Pools.Subpools
with Preelaborate, Global => in out synchronized is
type Root_Storage_Pool_With_Subpools is
abstract new Root_Storage_Pool with private
with Preelaborable_Initialization;
type Root_Subpool is abstract tagged limited private
with Preelaborable_Initialization;
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;
-- Следующие операции предназначены для разработчиков пулов:
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)
with Global => overriding in out Subpool;
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;
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
... -- не указано языком
end System.Storage_Pools.Subpools;
Подпул — это обособлённая, подлежащая повторному использованию часть пула памяти, идентифицируемая объектом типа Subpool_Handle (указатель на подпул). Указатель на подпул также идентифицирует окружающий пул памяти, пул памяти, поддерживающий подпулы, который является пулом памяти, тип которого происходит от Root_Storage_Pool_With_Subpools. Подпул создаётся путём вызова Create_Subpool или аналогичного конструктора; конструктор возвращает указатель на подпул.
Объект подпула — это объект типа, произошедшего от Root_Subpool. Обычно объекты подпулов управляются содержащим их пулом памяти; только указатели должны быть доступны клиентам пула памяти. Объекты подпулов обозначаются указателями на подпулы и представляют подпул во время выполнения.
Каждый подпул принадлежит одному пулу памяти (который всегда будет пулом, поддерживающим подпулы). Доступ к пулу, к которому принадлежит подпул, можно получить, вызвав Pool_of_Subpool с указателем на подпул. Set_Pool_of_Subpool устанавливает подпул указателя на подпул для данного пула; это предназначено для вызова из конструкторов подпулов, таких как Create_Subpool. Set_Pool_of_Subpool распространяет Program_Error, если подпул уже принадлежит пулу. Если для подпула ещё не был вызван Set_Pool_of_Subpool, Pool_of_Subpool возвращает null.
При оценке аллокатора для типа, чей пул памяти поддерживает подпулы, выполняется вызов Allocate_From_Subpool с передачей Subpool_Handle в дополнение к параметрам, определённым для вызовов Allocate (см. 13.11). Используется подпул, обозначенный указателем на подпул_имя, если он указан в аллокаторе. В противном случае используется Default_Subpool_for_Pool для пула. Все требования к процедуре Allocate также применимы к Allocate_from_Subpool.

Правила легальности

Если пул памяти, поддерживающий подпулы, указан как Storage_Pool для типа доступа, то тип доступа называется типом доступа к подпулу. Тип доступа к подпулу должен быть типом доступа, специфичным для пула.
Уровень доступности типа доступа к подпулу не должен быть статически глубже, чем у объекта пула памяти. Если указанный объект пула памяти является пулом памяти, поддерживающим подпулы, то имя, обозначающее объект, не должно обозначать часть формального параметра, а также часть ссылки на значение типа общего доступа, не относящегося к библиотечному уровню. В дополнение к местам, где обычно применяются Правила легальности (см. 12.3), эти правила также применяются в частях private экземпляра генерируемого блока.

Динамическая семантика

При заморозке типа доступа с указанным пулом памяти (см. 13.14), если метка объекта пула памяти идентифицирует пул памяти, поддерживающий подпулы, выполняются следующие проверки:
  • используемое для указания объекта пула памяти имя не обозначает часть формального параметра или часть ссылки на значение типа общего доступа, не относящегося к библиотечному уровню; и
  • уровень доступности типа доступа не глубже, чем у объекта пула памяти.
Program_Error генерируется, если любая из этих проверок завершается неудачно.
Вызов Subpools.Allocate(P, Addr, Size, Align) выполняет следующее:
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)));
Аллокатор, выделяющий память в подпуле, вызывает Program_Error, если выделенный объект имеет части задачи.
Если Default_Subpool_for_Pool не переопределён, он вызывает Program_Error.

Ошибка выполнения

Если Allocate_From_Subpool не соответствует одному или нескольким требованиям к процедуре Allocate, как указано в правилах выполнения ошибок 13.11, то выполнение программы будет ошибочным.

Разрешения для реализации

При оценке аллокатора для типа, пул памяти которого является типа Root_Storage_Pool'Class, но поддерживает подпулы, реализация может вызвать Allocate вместо Allocate_From_Subpool. Это будет иметь тот же эффект, пока Allocate не будет переопределён.
ПРИМЕЧАНИЕ 1 Пользовательский тип пула памяти, поддерживающий подпулы, может быть реализован путём расширения типа Root_Storage_Pool_With_Subpools и переопределения примитивных подпрограмм Create_Subpool, Allocate_From_Subpool и Deallocate_Subpool. Ожидается, что Create_Subpool вызовет Set_Pool_Of_Subpool перед возвращением указателя на подпул. Чтобы использовать такой пул, пользователь может объявить объект типа расширения, использовать его для определения атрибута Storage_Pool одного или нескольких типов доступа, а затем вызвать Create_Subpool, чтобы получить указатели на подпулы, связанные с пулом.
ПРИМЕЧАНИЕ 2 Пользовательский тип пула памяти, поддерживающий подпулы, может определить дополнительные конструкторы подпулов, аналогичные Create_Subpool (обычно они будут иметь дополнительные параметры).
ПРИМЕЧАНИЕ 3 Разработчик пула может переопределить Default_Subpool_For_Pool, если он хочет, чтобы пул поддерживал подпул по умолчанию для этого пула. Разработчик может переопределить Deallocate, если требуется поддержка индивидуального возврата памяти, и может переопределить Storage_Size, если имеется ограничение на общий размер пула памяти. Разработчик может переопределить Initialize и Finalize, если требуется нетривиальная инициализация и завершение работы для пула в целом. Например, Finalize может вернуть блоки памяти, выделенные сверх пространства, занимаемого объектом пула. Разработчик пула может расширить тип Root_Subpool по мере необходимости, чтобы каждый подпул, предоставляемый Create_Subpool, содержал дополнительную информацию.


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API