Справочник Ada 95
D.8 Монотонное время
В этом разделе описан пакет высокоточного монотонного таймера.
Статическая семантика
Существует следующий определяемый языком библиотечный пакет:
package Ada.Real_Time is
type Time is private;
Time_First : constant Time;
Time_Last : constant Time;
Time_Unit : constant := определяемое реализацией действительное число;
Time_First : constant Time;
Time_Last : constant Time;
Time_Unit : constant := определяемое реализацией действительное число;
type Time_Span is private;
Time_Span_First : constant Time_Span;
Time_Span_Last : constant Time_Span;
Time_Span_Zero : constant Time_Span;
Time_Span_Unit : constant Time_Span;
Time_Span_First : constant Time_Span;
Time_Span_Last : constant Time_Span;
Time_Span_Zero : constant Time_Span;
Time_Span_Unit : constant Time_Span;
Tick : constant Time_Span;
function Clock return Time;
function Clock return Time;
function "+" (Left : Time; Right : Time_Span) return Time;
function "+" (Left : Time_Span; Right : Time) return Time;
function "-" (Left : Time; Right : Time_Span) return Time;
function "-" (Left : Time; Right : Time) return Time_Span;
function "+" (Left : Time_Span; Right : Time) return Time;
function "-" (Left : Time; Right : Time_Span) return Time;
function "-" (Left : Time; Right : Time) return Time_Span;
function "<" (Left, Right : Time) return Boolean;
function "<="(Left, Right : Time) return Boolean;
function ">" (Left, Right : Time) return Boolean;
function ">="(Left, Right : Time) return Boolean;
function "<="(Left, Right : Time) return Boolean;
function ">" (Left, Right : Time) return Boolean;
function ">="(Left, Right : Time) return Boolean;
function "+" (Left, Right : Time_Span) return Time_Span;
function "-" (Left, Right : Time_Span) return Time_Span;
function "-" (Right : Time_Span) return Time_Span;
function "*" (Left : Time_Span; Right : Integer) return Time_Span;
function "*" (Left : Integer; Right : Time_Span) return Time_Span;
function "/" (Left, Right : Time_Span) return Integer;
function "/" (Left : Time_Span; Right : Integer) return Time_Span;
function "-" (Left, Right : Time_Span) return Time_Span;
function "-" (Right : Time_Span) return Time_Span;
function "*" (Left : Time_Span; Right : Integer) return Time_Span;
function "*" (Left : Integer; Right : Time_Span) return Time_Span;
function "/" (Left, Right : Time_Span) return Integer;
function "/" (Left : Time_Span; Right : Integer) return Time_Span;
function "abs"(Right : Time_Span) return Time_Span;
Этот абзац был удалён.
function "<" (Left, Right : Time_Span) return Boolean;
function "<="(Left, Right : Time_Span) return Boolean;
function ">" (Left, Right : Time_Span) return Boolean;
function ">="(Left, Right : Time_Span) return Boolean;
function "<="(Left, Right : Time_Span) return Boolean;
function ">" (Left, Right : Time_Span) return Boolean;
function ">="(Left, Right : Time_Span) return Boolean;
function To_Duration (TS : Time_Span) return Duration;
function To_Time_Span (D : Duration) return Time_Span;
function To_Time_Span (D : Duration) return Time_Span;
function Nanoseconds (NS : Integer) return Time_Span;
function Microseconds (US : Integer) return Time_Span;
function Milliseconds (MS : Integer) return Time_Span;
function Microseconds (US : Integer) return Time_Span;
function Milliseconds (MS : Integer) return Time_Span;
type Seconds_Count is range определяемое реализацией;
procedure Split(T : in Time; SC : out Seconds_Count; TS : out Time_Span);
function Time_Of(SC : Seconds_Count; TS : Time_Span) return Time;
function Time_Of(SC : Seconds_Count; TS : Time_Span) return Time;
private
... -- не задано языком
end Ada.Real_Time;
... -- не задано языком
end Ada.Real_Time;
В этом приложении реальное время определяется как физическое время, наблюдаемое во внешней среде. Тип Time является типом времени, как определено в 9.6; значения этого типа могут использоваться в операторе delay_until_statement. Значения этого типа представляют отрезки идеальной временной шкалы. Множество значений типа Time соответствует одному значению диапазона определяемых реализацией математических целых чисел.
Значение Time I представляет полуоткрытый интервал реального времени, который начинается с E+I*Time_Unit и ограничен E+(I+1)*Time_Unit, где Time_Unit — определяемое реализацией действительное число, а E — неопределённая начальная точка, эпоха, которая одинакова для всех значений типа Time. Языком не указано, синхронизированы ли временные значения с какой-либо стандартной временной отметкой. Например, E может соответствовать времени запуска системы или эпохе некоторого временного стандарта.
Значения типа Time_Span представляют длительность реального времени. Множество значений этого типа соответствует одному значению диапазона определяемых реализацией математических целых чисел. Значение Time_Span, соответствующее целому числу I, представляет длительность реального времени I*Time_Unit.
Time_First и Time_Last — соответственно наименьшее и наибольшее значения типа Time. Аналогично, Time_Span_First и Time_Span_Last — соответственно наименьшее и наибольшее значения типа Time_Span.
Значение типа Seconds_Count представляет прошедшее время, измеренное в секундах, с момента эпохи.
Динамическая семантика
Time_Unit — наименьшая единица реального времени, представимая типом Time; она выражается в секундах. Time_Span_Unit — разница между двумя последовательными значениями типа Time. Это также наименьшее положительное значение типа Time_Span. Time_Unit и Time_Span_Unit представляют одну и ту же продолжительность реального времени. Такт таймера — интервал реального времени, в течение которого значение таймера (как наблюдается при вызове функции Clock) остаётся постоянным. Tick — средняя длительность таких интервалов.
Функция To_Duration преобразует значение TS в значение типа Duration. Аналогично, функция To_Time_Span преобразует значение D в значение типа Time_Span. В обоих случаях результат округляется до ближайшего представимого значения (в сторону от нуля, если точно между двумя представимыми значениями).
To_Duration(Time_Span_Zero) возвращает 0.0, а To_Time_Span(0.0) возвращает Time_Span_Zero.
Функции Nanoseconds, Microseconds и Milliseconds преобразуют входной параметр в значение типа Time_Span. NS, US и MS интерпретируются как количество наносекунд, микросекунд и миллисекунд соответственно. Результат округляется до ближайшего представимого значения (в сторону от нуля, если точно между двумя представимыми значениями).
Эффекты операторов на Time и Time_Span соответствуют эффектам операторов, определённых для целочисленных типов.
Функция Clock возвращает время, прошедшее с момента эпохи.
Эффекты операций Split и Time_Of определяются следующим образом, рассматривая значения типа Time, Time_Span и Seconds_Count как математические целые числа. Эффект Split(T,SC,TS) состоит в том, чтобы установить SC и TS в значения, такие что T*Time_Unit = SC*1.0 + TS*Time_Unit, и 0.0 <= TS*Time_Unit < 1.0. Возвращаемое значение Time_Of(SC,TS) — это значение T такое, что T*Time_Unit = SC*1.0 + TS*Time_Unit.
Требования к реализации
Диапазон значений Time должен быть достаточным для уникального представления диапазона реального времени от запуска программы до 50 лет спустя. Tick не должен превышать 1 миллисекунды. Time_Unit должно быть меньше или равно 20 микросекунд.
Time_Span_First не должно быть больше -3600 секунд, а Time_Span_Last не должно быть меньше 3600 секунд.
Скачок таймера — это разница между двумя последовательными различными значениями таймера (наблюдаемыми при вызове функции Clock). Не должно быть обратных скачков таймера.
Требования к документации
Реализация должна документировать значения Time_First, Time_Last, Time_Span_First, Time_Span_Last, Time_Span_Unit и Tick.
Реализация должна документировать свойства лежащего в основе временного базиса, используемого для таймера и типа Time, такие как поддерживаемый диапазон значений и любые соответствующие аспекты используемого базового оборудования или операционной системы.
Реализация должна документировать, существует ли синхронизация с внешними временными отметками, и если такая синхронизация существует, источники синхронизирующей информации, частоту синхронизации и применяемый метод синхронизации.
Реализация должна документировать любые аспекты внешней среды, которые могут повлиять на поведение таймера, как определено в этом разделе.
Метрики
Для целей метрик, определённых в этом разделе, реальное время определяется как Международное атомное время (TAI).
Реализация должна документировать следующие метрики:
- Верхняя граница продолжительности реального времени такта таймера. Это значение D такое, что если t1 и t2 — любые реальные моменты времени такие, что t1 < t2 и Clockt1 = Clockt2, тогда t2 - t1 ≤ D.
- Верхняя граница размера скачка таймера.
- Верхняя граница скорости дрейфа Clock относительно реального времени. Это действительное число D такое, что
E*(1-D) ≤ (Clockt+E - Clockt) ≤ E*(1+D)
при условии: Clockt + E*(1+D) ≤ Time_Last.
при условии: Clockt + E*(1+D) ≤ Time_Last.
- где Clockt — значение Clock в момент времени t, а E — продолжительность реального времени не менее 24 часов. Используемое значение E для этой метрики должно быть указано.
- Верхняя граница времени выполнения вызова функции Clock в тактах процессора.
- Верхние границы времени выполнения операторов типов Time и Time_Span в тактах процессора.
Разрешения для реализации
Реализации, ориентированные на машины с размером слова меньше 32 бит, не обязаны поддерживать весь диапазон и точность типов Time и Time_Span.
END_OF_DOCUMENT_MARKER Рекомендации по реализации
В тех случаях, когда это целесообразно, реализации должны предоставлять механизмы конфигурации для изменения значения Tick.
Рекомендуется реализовывать Calendar.Clock и Real_Time.Clock как преобразования одного и того же временного базиса.
Рекомендуется, чтобы «лучший» временной базис, существующий в базовой системе, был доступен приложению через Clock. «Лучший» может означать наибольшую точность или наибольший диапазон.
ПРИМЕЧАНИЯ
30 Правила в этом пункте не подразумевают, что реализация может защитить пользователя от ошибок оператора или установки, которые могут привести к неправильной настройке часов.
31 Time_Unit — это гранулярность типа Time. В отличие от этого, Tick представляет гранулярность Real_Time.Clock. Нет требования, чтобы они были одинаковыми.