Руководство по Ada (Ada 2022)
C.6 Управление общими переменными
В этом подпункте определяются аспекты представления, которые управляют использованием общих переменных.
Абзацы с 2 по 6 были перемещены в Приложение J, «Устаревшие возможности».
Статическая семантика
Для объявления_объекта, объявления_компонента, полного_объявления_типа или формального_полного_объявления_типа могут быть указаны следующие аспекты представления:
Атомарный
Тип аспекта Атомарный — логический.
Независимый
Тип аспекта Независимый — логический.
Изменчивый
Тип аспекта Изменчивый — логический.
Только_полный_доступ
Тип аспекта Только_полный_доступ — логический.
Для полного_объявления_типа типа массива, объявления_объекта для объекта анонимного типа массива или формального_полного_объявления_типа формального типа массива могут быть указаны следующие аспекты представления:
Атомарные_компоненты
Тип аспекта Атомарные_компоненты — логический.
Изменчивые_компоненты
Тип аспекта Изменчивые_компоненты — логический.
Для полного_объявления_типа составного типа, объявления_объекта для объекта анонимного составного типа или формального_полного_объявления_типа формального составного типа может быть указан следующий аспект представления:
Независимые_компоненты
Тип аспекта Независимые_компоненты — логический.
Если любой из этих аспектов указан непосредственно, то определение_аспекта должно быть статическим выражением. Если для типа не указано (включая наследование), то аспекты Атомарный, Атомарные_компоненты и Только_полный_доступ равны False. Если любой из этих аспектов для типа указан как True, то соответствующий аспект равен True для всех объектов этого типа. Если аспект Атомарный указан как True, то аспекты Изменчивый, Независимый и Изменчивые_компоненты (если определены) равны True; если аспект Атомарные_компоненты указан как True, то аспекты Изменчивый, Изменчивые_компоненты и Независимые_компоненты равны True. Если аспект Изменчивый указан как True, то аспект Изменчивые_компоненты (если определён) равен True, и наоборот. Если не определено одним из других аспектов или для объекта типом, то аспекты Изменчивый, Изменчивые_компоненты, Независимый и Независимые_компоненты равны False.
Атомарный тип — это тип, для которого аспект Атомарный равен True. Атомарный объект (включая компонент) — это объект, для которого аспект Атомарный равен True, или компонент массива, для которого аспект Атомарные_компоненты равен True для связанного типа, или любой объект атомарного типа, кроме объектов, полученных путём вычисления среза.
Изменчивый тип — это тип, для которого аспект Изменчивый равен True. Изменчивый объект (включая компонент) — это объект, для которого аспект Изменчивый равен True, или компонент массива, для которого аспект Изменчивые_компоненты равен True для связанного типа, или любой объект изменчивого типа. Кроме того, каждый атомарный тип или объект также определяется как изменчивый. Наконец, если объект изменчив, то все его подкомпоненты также изменчивы (это не относится к атомарным).
При значении True аспекты Независимый и Независимые_компоненты определяют как независимые адресованные указанный объект или компонент(ы), или в случае типа — все объекты или компоненты этого типа. Все атомарные объекты и объекты с алиасами считаются независимо адресовываемыми.
Аспект Только_полный_доступ не должен быть указан, если соответствующий тип или объект не изменчив (или атомарный). Тип полного доступа — это любой атомарный тип или изменчивый тип, для которого аспект Только_полный_доступ равен True. Объект полного доступа (включая компонент) — это любой атомарный объект или изменчивый объект, для которого аспект Только_полный_доступ равен True для объекта или его типа. Аспект Только_полный_доступ является некорректным, если любой подкомпонент объекта или типа является объектом полного доступа или является формальным типом-параметром.
Абзац 9 был перемещен в Приложение J, «Устаревшие возможности».
Правила допустимости
Если аспект Независимые_компоненты указан для полного_объявления_типа, то объявление должно быть объявлением типа массива или записи.
Некорректно указывать аспекты Атомарный или Атомарные_компоненты со значением True для объекта или типа, если реализация не может поддерживать неделимые и независимые чтения и обновления, требуемые аспектом (см. ниже).
Некорректно указывать атрибут Размер атомарного объекта, атрибут Размер_компонента для типа массива с атомарными компонентами или атрибуты компоновки атомарного компонента таким образом, чтобы предотвратить выполнение реализацией требуемых неделимых и независимых чтений и обновлений.
Если атомарный объект передаётся в качестве параметра, то формальный параметр должен иметь атомарный тип или допускать передачу по значению. Если атомарный объект используется в качестве фактического для формального объекта-параметра типа вход-выход, то тип формального объекта-параметра должен быть атомарным. Если префикс ссылка_на_атрибут для атрибута Access обозначает атомарный объект (включая компонент), то тип результата типа доступа должен быть атомарным. Соответствующие правила применяются к изменчивым объектам и объектам полного доступа.
Если подкомпонент неатомарного объекта полного доступа передаётся в качестве фактического параметра в вызове, то формальный параметр должен допускать передачу по значению (и во время выполнения параметр должен передаваться по значению). Подкомпонент неатомарного объекта полного доступа не должен использоваться в качестве фактического для формального параметра типа вход-выход. Префикс ссылка_на_атрибут для атрибута Access не должен обозначать подкомпонент неатомарного объекта полного доступа.
Если аспект Атомарный, Атомарные_компоненты, Изменчивый, Изменчивые_компоненты, Независимый, Независимые_компоненты или Только_полный_доступ имеет значение True для формального типа-параметра, то этот аспект должен быть True для фактического типа. Если атомарный тип используется в качестве фактического для формального типа-параметра, производного типа, то предок формального типа должен быть атомарным. Соответствующее правило применяется к изменчивым типам и аналогично типам полного доступа.
Если тип с изменчивыми компонентами используется в качестве фактического для формального типа массива, то компоненты формального типа должны быть изменчивыми. Кроме того, если фактический тип имеет атомарные компоненты, а формальный тип массива имеет алиасированные компоненты, то компоненты формального типа массива также должны быть атомарными. Соответствующее правило применяется, когда фактический тип имеет изменчивые компоненты полного доступа.
Если аспект Изменчивый, Изменчивые_компоненты, Атомарный или Атомарные_компоненты прямо указан как True для отдельного объекта-константы, то аспект Импорт также должен быть указан как True для него.
Некорректно указывать аспект Независимый или Независимые_компоненты как True для компонента, объекта или типа, если реализация не может обеспечить независимую адресовываемость, требуемую аспектом (см. 9.10).
Некорректно указывать аспект представления для компонента, объекта или типа, для которого аспект Независимый или Независимые_компоненты равен True, таким образом, чтобы реализация не могла предоставить независимую адресовываемость, требуемую аспектом.
Абзац 14 был перемещён в Приложение J, «Устаревшие возможности».
Динамическая семантика
Для атомарного объекта (включая атомарный компонент) все чтения и обновления объекта в целом неделимы.
Все задачи программы (на всех процессорах), которые читают или обновляют изменчивые переменные, видят один и тот же порядок обновлений переменных. Может потребоваться использование атомарной переменной или другого механизма, чтобы избежать ошибочного выполнения и гарантировать, что доступ к неатомарным изменчивым переменным последователен (см. 9.10).
Два действия последовательны (см. 9.10), если каждое из них является чтением или обновлением того же атомарного объекта.
Если тип атомарный или изменчивый и он не является типом по значению, то тип определяется как тип по ссылке. Если любой подкомпонент типа атомарный или изменчивый, то тип определяется как тип по ссылке.
Если фактический параметр атомарный или изменчивый, а соответствующий формальный параметр нет, то параметр передаётся по значению.
Все чтения или записи в любой неатомарной подкомпоненте объекта полного доступа выполняются путем чтения и/или записи всех ближайших окружающих объектов полного доступа.
Требования к реализации
Внешнее воздействие программы (см. 1.1.3) определяется как включающее каждое чтение и обновление объекта volatile или атомарного объекта. Реализация не должна генерировать никакие чтение или обновления памяти атомарных или volatile объектов, кроме тех, которые указаны программой. Однако могут быть зависящие от целевой платформы случаи, когда чтение или запись volatile, но неатомарного объекта (обычно компонента) обязательно влечёт чтение и/или запись соседнего хранилища, и это соседнее хранилище может перекрывать volatile объект.
Этот абзац был удалён.
Разрешения реализации
В теле экземпляра обобщенного блока, имеющего формальный тип T, который не является атомарным, и фактический тип, который является атомарным, если объект O типа T объявлен и явно указан как атомарный, реализация может ввести дополнительную копию при передаче O подпрограмме с параметром типа T, который обычно передаётся по ссылке. Соответствующее разрешение распространяется на передачу параметров volatile.
Рекомендации по реализации
Загрузка или сохранение volatile объекта, размер которого кратен System.Storage_Unit, а выравнивание которого не равно нулю, должно выполняться путём доступа только к битам объекта, и ни к каким другим, за исключением случая volatile, но неатомарной подкомпоненты атомарного объекта.
Загрузка или сохранение атомарного объекта должно, по возможности, быть реализовано с помощью одной инструкции загрузки или сохранения.
ПРИМЕЧАНИЕ 1 Импортированная volatile или атомарная константа ведет себя как константа (т.е. только для чтения) по отношению к другим частям программы Ada, но всё равно может быть изменена «внешним источником».
ПРИМЕЧАНИЕ 2 Указание аспекта Pack не может переопределить эффект указания аспектов Atomic или Atomic_Components.
ПРИМЕЧАНИЕ 3 При сопоставлении объекта Ada с отображаемым в памяти аппаратным регистром, объект Ada можно объявить атомарным, чтобы гарантировать, что компилятор будет читать и записывать точно те биты регистра, как указано в исходном коде, и никакие другие.