Справочник по Ada (Ada 2022)
D.10 Синхронизация задач
В этом подпункте описывается определяемый языком частный семафор (объект приостановки), который может использоваться для операций двухэтапного приостановления и как простой строительный блок для реализации очередей более высокого уровня.
Статическая семантика
Существует следующий определяемый языком пакет:
package Ada.Synchronous_Task_Control
with Preelaborate, Nonblocking, Global => in out synchronized is
with Preelaborate, Nonblocking, Global => in out synchronized is
type Suspension_Object is limited private;
procedure Set_True(S : in out Suspension_Object);
procedure Set_False(S : in out Suspension_Object);
function Current_State(S : Suspension_Object) return Boolean;
procedure Suspend_Until_True(S : in out Suspension_Object)
with Nonblocking => False;
private
... -- не определено языком
end Ada.Synchronous_Task_Control;
procedure Set_True(S : in out Suspension_Object);
procedure Set_False(S : in out Suspension_Object);
function Current_State(S : Suspension_Object) return Boolean;
procedure Suspend_Until_True(S : in out Suspension_Object)
with Nonblocking => False;
private
... -- не определено языком
end Ada.Synchronous_Task_Control;
Тип Suspension_Object является типом по ссылке.
Существует следующий определяемый языком пакет:
with Ada.Real_Time;
package Ada.Synchronous_Task_Control.EDF
with Nonblocking, Global => in out synchronized is
procedure Suspend_Until_True_And_Set_Deadline
(S : in out Suspension_Object;
TS : in Ada.Real_Time.Time_Span)
with Nonblocking => False;
end Ada.Synchronous_Task_Control.EDF;
package Ada.Synchronous_Task_Control.EDF
with Nonblocking, Global => in out synchronized is
procedure Suspend_Until_True_And_Set_Deadline
(S : in out Suspension_Object;
TS : in Ada.Real_Time.Time_Span)
with Nonblocking => False;
end Ada.Synchronous_Task_Control.EDF;
Динамическая семантика
Объект типа Suspension_Object имеет два видимых состояния: True и False. При инициализации его значение устанавливается в False.
Операции Set_True и Set_False являются атомарными относительно друг друга и относительно Suspend_Until_True; они устанавливают состояние в True и False соответственно.
Current_State возвращает текущее состояние объекта.
Процедура Suspend_Until_True блокирует вызывающую задачу до тех пор, пока состояние объекта S не станет True; в этот момент задача становится готовой, а состояние объекта становится False.
Ошибка Program_Error возникает при вызове Suspend_Until_True, если другая задача уже ожидает этого объекта приостановки.
Процедура Suspend_Until_True_And_Set_Deadline блокирует вызывающую задачу до тех пор, пока состояние объекта S не станет True; в этот момент задача становится готовой со сроком выполнения Ada.Real_Time.Clock + TS, а состояние объекта становится False. Ошибка Program_Error возникает при вызове Suspend_Until_True_And_Set_Deadline, если другая задача уже ожидает этого объекта приостановки.
Ограниченные (временные) ошибки
Ошибка возникает, если две или более задачи вызывают Suspend_Until_True на одном и том же объекте Suspension_Object одновременно. Для каждой задачи может быть поднята ошибка Program_Error, задача может продолжить выполнение без приостановки или задача может приостановиться, потенциально на неопределённое время. Состояние объекта приостановки может оказаться либо True, либо False.
Требования к реализации
Реализация должна допускать вызов Set_False и Set_True во время любой защищённой операции, даже той, у которой приоритет потока находится в диапазоне Interrupt_Priority.
ПРИМЕЧАНИЕ Более сложные схемы, такие как установка срока выполнения относительно момента вызова Set_True, могут быть запрограммированы с помощью защищённого объекта.