Руководство по Ada (Ada 2022)
D.7 Ограничения для задач
Этот подпункт определяет ограничения, которые могут быть использованы с пragma Restrictions (см. 13.12), чтобы облегчить создание высокоэффективных систем выполнения задач.
Статическая семантика
Скалярное выражение внутри защищенной единицы называется подходящим для чистого барьера, если оно является одним из следующих:
- статическое выражение;
- имя идентификатора, статически обозначающее (см. 4.9) скалярную подкомпоненту непосредственно вложенной защищенной единицы;
- атрибут Count ссылка_на_атрибут, чей префикс статически обозначает объявление входа непосредственно вложенной единицы;
- вызов предопределенного реляционного оператора или булевого логического оператора (и, или, исключающее или, не), где каждый операнд является подходящим для чистого барьера;
- тест на принадлежность, где tested_простое_выражение подходит для чистого барьера, а список_выборов_принадлежности удовлетворяет требованиям для статического теста на принадлежность (см. 4.9);
- краткая форма управления с коротким замыканием, у обоих операндов которой есть возможность применения чистого барьера;
- условное_выражение все условия, выбирающие_выражения и зависимые_выражения которого являются подходящими для чистого барьера; или
- выражение, подходящее для чистого барьера, заключенное в скобки.
Следующие ограничения_идентификаторы определены языком:
No_Task_Hierarchy
Ни одна задача не зависит от мастера, отличного от мастера на уровне библиотеки.
No_Nested_Finalization
Объекты типа, которому требуется окончательная обработка (см. 7.6), объявляются только на уровне библиотеки. Если у типа доступа нет доступа на уровне библиотеки, то нет аллокаторов типа, где тип, определяемый меткой_подтипа указаний_подтипа или квалифицированного_выражения, требует окончательной обработки.
No_Abort_Statements
No_Terminate_Alternatives
No_Task_Allocators
Нет аллокаторов для типов задач или типов, содержащих подкомпоненты задач.
В случае инициализированного аллокатора типа доступа, назначенный тип которого является классово-широким и ограниченным, проверяется, что конкретный тип выделенного объекта не содержит подкомпоненты задач. Если проверка завершится неудачно, генерируется Program_Error.
No_Implicit_Heap_Allocations
Нет операций, которые неявно требуют выполнения выделения памяти в куче реализацией. Операции, которые неявно требуют выделения памяти в куче, определяются реализацией.
No_Dynamic_Priorities
Нет семантических зависимостей от пакета Dynamic_Priorities, и нет случаев использования атрибута Priority.
No_Dynamic_Attachment
Нет использования идентификатора, обозначающего какие-либо операции, определенные в пакете Interrupts (Is_Reserved, Is_Attached, Current_Handler, Attach_Handler, Exchange_Handler, Detach_Handler и Reference).
No_Dynamic_CPU_Assignment
Ни одна задача не имеет аспект CPU, указанный как нестатическое выражение. Каждой задаче (включая задачу среды) с аспектом CPU, указанным как Not_A_Specific_CPU, будет назначен конкретный, определённый реализацией, процессор. То же самое относится к задаче среды, когда аспект CPU не указан. Любая другая задача без аспекта CPU активируется и выполняется на том же процессоре, что и активирующая её задача.
No_Local_Protected_Objects
Защищенные объекты объявляются только на уровне библиотеки.
No_Local_Timing_Events
Timing_Events объявляются только на уровне библиотеки.
No_Protected_Type_Allocators
Нет аллокаторов для типов защищенных объектов или типов, содержащих подкомпоненты защищенных типов.
В случае инициализированного аллокатора типа доступа, назначенный тип которого является классово-широким и ограниченным, проверяется, что конкретный тип выделенного объекта не содержит защищенных подкомпонентов. Если проверка завершится неудачно, генерируется Program_Error.
No_Relative_Delay
Нет операции_задержки_относительно и нет использования идентификатора, который обозначает подпрограмму Timing_Events.Set_Handler, имеющую параметр Time_Span.
No_Requeue_Statements
Нет операции_переупорядоченияов.
No_Select_Statements
Нет операции_выбораов.
No_Specific_Termination_Handlers
Нет использования идентификатора, обозначающего подпрограммы Set_Specific_Handler и Specific_Handler в Task_Termination.
No_Tasks_Unassigned_To_CPU
Аспект CPU указан для задачи среды. Ни один аспект CPU не указан как статически равный Not_A_Specific_CPU. Если аспект CPU указан (динамически) в значение Not_A_Specific_CPU, генерируется Program_Error. Если вызываются Set_CPU или Delay_Until_And_Set_CPU с параметром CPU равным Not_A_Specific_CPU, генерируется Program_Error.
Pure_Barriers
Булево выражение в каждом барьере защищенного входа является подходящим для чистого барьера.
Simple_Barriers
Булевое выражение в каждом барьере входа является либо статическим выражением, либо именем, которое статически называет (см. 4.9) подкомпоненту вложенного защищенного объекта.
Следующие параметры_ограничения_идентификаторы определены языком:
Max_Select_Alternatives
Указывает максимальное количество альтернатив в выборочном_приеме.
Max_Task_Entries
Указывает максимальное количество входов на задачу. Границы каждой семейства входов в единицу задачи должны быть статическими или определяться дискриминантой подтипа, соответствующая граница которого является статической. Значение нуля указывает на то, что согласования невозможны.
Max_Protected_Entries
Указывает максимальное количество входов для каждого типа защищенных объектов. Границы каждой семейства входов в защищенную единицу должны быть статическими или определяться дискриминантой подтипа, соответствующая граница которого является статической.
Динамическая семантика
Следующий ограничения_идентификатор определён языком:
No_Task_Termination
Все задачи не завершаются. Реализация определяет, что произойдёт, если задача попытается завершиться. Если для раздела задан обработчик по умолчанию (см. C.7.3), он должен вызываться, когда первая задача попытается завершиться.
Следующие параметры_ограничения_идентификаторы определены языком:
Max_Storage_At_Blocking
Указывает максимальную часть (в элементах хранения) размера хранения задачи Storage_Size, которую может сохранить заблокированная задача. Если реализация выбирает обнаружить нарушение этого ограничения, должно быть поднято Storage_Error; в противном случае поведение определяется реализацией.
Max_Asynchronous_Select_Nesting
Указывает максимальный динамический уровень вложенности asynchronous_select. Значение ноль предотвращает использование asynchronous_select, и если программа содержит asynchronous_select, это является недопустимым. Если реализация выбирает обнаружить нарушение этого ограничения для значений, отличных от нуля, должно быть поднято Storage_Error; в противном случае поведение определяется реализацией.
Max_Tasks
Указывает максимальное количество созданий задач, которое может быть выполнено за время существования раздела, не считая создания задачи среды. Значение ноль предотвращает любое создание задач, и если программа содержит создание задачи, это является недопустимым. Если реализация выбирает обнаружить нарушение этого ограничения, должно быть поднято Storage_Error; в противном случае поведение определяется реализацией.
Max_Entry_Queue_Length
Max_Entry_Queue_Length определяет максимальное количество вызовов, которые очередиваются на входе. Нарушение этого ограничения приводит к поднятию Program_Error в момент вызова или повторного помещения в очередь.
No_Standard_Allocators_After_Elaboration
Указывает, что аллокатор, использующий стандартный пул памяти (см. 13.11), не должен появляться внутри параметризированной библиотечной подпрограммы, ни внутри handled_sequence_of_statements тела задачи. Для целей этой правила аллокатор типа, производного от формального типа доступа, не использует стандартный пул памяти.
Во время выполнения, Storage_Error поднимается, если аллокатор, использующий стандартный пул памяти, оценивается после завершения разработки library_itemов раздела.
Определяется ли использование псевдонима Restrictions в уменьшении размера исполняемой программы, требованиях к памяти или времени выполнения - зависит от реализации. Если это возможно, реализация должна предоставить количественные описания таких эффектов для каждого ограничения.
Рекомендации по реализации
В случае возможности, реализация должна использовать указанные ограничения для создания более эффективной реализации.
ПРИМЕЧАНИЕ Вышеупомянутые Storage_Checks могут быть подавлены с помощью псевдонима Suppress.