Справочник по Ada (Ada 2022)
C.7.2 Пакет Task_Attributes
Статическая семантика
Существует следующий определяемый языком обобщённый пакет библиотеки:
с Ada.Task_Identification; использование Ada.Task_Identification;
обобщённый
тип Attribute является частным;
Initial_Value : вход Attribute;
пакет Ada.Task_Attributes
с Nonblocking, Global => вход-выход синхронизированный является
обобщённый
тип Attribute является частным;
Initial_Value : вход Attribute;
пакет Ada.Task_Attributes
с Nonblocking, Global => вход-выход синхронизированный является
тип Attribute_Handle является доступ к всему Attribute;
функция Value(T : Task_Id := Current_Task)
возвращает Attribute;
возвращает Attribute;
функция Reference(T : Task_Id := Current_Task)
возвращает Attribute_Handle;
возвращает Attribute_Handle;
процедура Set_Value(Val : вход Attribute;
T : вход Task_Id := Current_Task);
процедура Reinitialize(T : вход Task_Id := Current_Task);
T : вход Task_Id := Current_Task);
процедура Reinitialize(T : вход Task_Id := Current_Task);
конец Ada.Task_Attributes;
Динамическая семантика
При разработке экземпляра Task_Attributes в заданном активном разделе неявно создаётся объект фактического типа, соответствующего формальному типу Attribute, для каждой задачи (этого раздела), которая существует и ещё не завершена. Этот объект служит пользовательским атрибутом задачи. Задача, созданная ранее в разделе и ещё не завершённая, получает этот атрибут с этого момента. Каждая задача, созданная впоследствии в разделе, будет иметь этот атрибут при создании. Во всех этих случаях начальное значение данного атрибута равно Initial_Value.
Операция Value возвращает значение соответствующего атрибута T.
Операция Reference возвращает значение доступа, указывающее на соответствующий атрибут T.
Операция Set_Value выполняет любое завершение старого значения атрибута T и присваивает Val этому атрибуту (см. 5.2 и 7.6).
Действие операции Reinitialize такое же, как Set_Value, где параметр Val заменяется на Initial_Value.
Для всех операций, объявленных в этом пакете, Tasking_Error поднимается, если задача, идентифицированная T, завершена. Program_Error поднимается, если значение T равно Null_Task_Id.
После завершения задачи все её атрибуты завершаются, если они не были завершены ранее. При завершении главного экземпляра Ada.Task_Attributes соответствующий атрибут каждой задачи завершается, если он не был завершён ранее.
Ограниченные (временные) ошибки
Если пакет Ada.Task_Attributes инстанцирован с контролируемым типом, а контролируемый тип имеет пользовательские операции Adjust или Finalize, которые в свою очередь обращаются к атрибутам задач с помощью любой из вышеперечисленных операций, то вызов Set_Value инстанцированного пакета является ограниченной ошибкой. Вызов может выполняться как ожидается, или может привести к вечному блокированию вызывающей задачи и впоследствии некоторых или всех задач раздела.
Ошибка выполнения
Неправильно выполнять обращение к значению доступа, возвращаемому заданным вызовом Reference после последующего вызова Reinitialize для того же атрибута задачи или после завершения связанной задачи.
Если значение Task_Id передаётся в качестве параметра любой из операций, объявленных в этом пакете, и соответствующий объект задачи больше не существует, выполнение программы является ошибочным.
Доступ к атрибуту задачи через значение типа Attribute_Handle является ошибочным, если он выполняется одновременно с другим таким доступом или вызовом любой из операций, объявленных в пакете Task_Attributes. Доступ к атрибуту задачи является ошибочным, если он выполняется одновременно с или после завершения атрибута задачи.
Требования к реализации
Для заданного атрибута заданной задачи реализация должна выполнять объявленные в этом пакете операции атомарно по отношению к любой из этих операций того же атрибута той же задачи. Грань любого механизма блокировки, необходимого для достижения такой атомарности, определяется реализацией.
После завершения атрибутов задачи реализация должна вернуть любой хранилище, связанное с атрибутами.
Требования к документации
Реализация должна документировать ограничение на количество атрибутов на задачу, если таковое имеется, и ограничение на общее хранилище для значений атрибутов на задачу, если такое ограничение существует.
Кроме того, если эти ограничения могут быть настроены, реализация должна документировать способ их настройки.
Метрики
Реализация должна документировать следующие метрики: Задача, вызывающая следующие подпрограммы, должна выполняться с достаточно высоким приоритетом, чтобы не прерываться в течение периода измерения. Этот период начинается непосредственно перед вызовом и заканчивается непосредственно после завершения вызова. Если атрибуты задачи T используются в тестах измерения, никакая другая задача не должна обращаться к атрибутам этой задачи в течение периода измерения. Для всех измерений, описанных здесь, тип Attribute должен быть скалярным типом, размер которого равен размеру предопределённого типа Integer. Для каждого измерения должны быть задокументированы два случая: один, где доступные атрибуты принадлежат вызывающей задаче (то есть используется значение по умолчанию для параметра T), и другой, где T идентифицирует другую, незавершенную, задачу.
Следующие вызовы (к подпрограммам в пакете Task_Attributes) должны быть измерены:
- вызов Value, где возвращаемое значение равно Initial_Value;
- вызов Value, где возвращаемое значение не равно Initial_Value;
- вызов Reference, где возвращаемое значение указывает на значение, равное Initial_Value;
- вызов Reference, где возвращаемое значение указывает на значение, не равное Initial_Value;
- вызов Set_Value, где параметр Val не равен Initial_Value, а старое значение атрибута равно Initial_Value;
- вызов Set_Value, где параметр Val не равен Initial_Value, а старое значение атрибута не равно Initial_Value.
Разрешения реализации
Реализация может избежать фактического создания объекта, соответствующего атрибуту задачи, до тех пор, пока его значение не будет установлено на значение, отличное от Initial_Value, или пока для атрибута задачи не будет вызван Reference. Аналогично, при необходимости повторной инициализации значения атрибута в Initial_Value, объект может быть завершён и его хранилище возвращено, чтобы быть пересозданным по мере необходимости позже. Пока объект не существует, функция Value может просто возвращать Initial_Value, а не неявно создавать объект.
Реализация имеет право устанавливать ограничения на максимальное количество атрибутов задачи, максимальный размер каждого атрибута и общий размер хранилища, выделенного для всех атрибутов задачи.
Рекомендации по реализации
Некоторые реализации предназначены для областей, в которых использование памяти во время выполнения должно быть полностью детерминированным. Для таких реализаций рекомендуется, чтобы хранилище для атрибутов задач было предварительно выделено статически, а не из кучи. Это можно сделать, либо установив ограничения на количество и размер атрибутов задачи, либо используя предварительно выделенное хранилище для первых N объектов атрибутов, а кучу - для остальных. В последнем случае N должен быть задокументирован.
Завершение атрибутов задач и возврат связанного хранилища должны выполняться как можно скорее после завершения задачи.
ПРИМЕЧАНИЕ 1 Атрибут всегда существует (после инстанцирования) и имеет начальное значение. Реализация может избежать использования памяти для хранения значения атрибута до тех пор, пока первая операция, изменяющая значение атрибута, не будет выполнена. То же самое верно и после Reinitialize.
ПРИМЕЧАНИЕ 2 Результат функции Reference всегда безопасен для использования в теле задачи, чьё атрибут обращается. Однако, когда результат используется другой задачей, программист захочет убедиться, что задача, атрибут которой обращается, ещё не завершена. Невыполнение этого может привести к ошибке выполнения программы.