D.8 Monotonic Time
This subclause specifies a high-resolution, monotonic
clock package.
Static Semantics
The following language-defined
library package exists:
package Ada.Real_Time
with Nonblocking, Global =>
in out synchronized is
type Time
is private;
Time_First :
constant Time;
Time_Last :
constant Time;
Time_Unit :
constant :=
implementation-defined-real-number;
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;
Tick :
constant Time_Span;
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, 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 "abs"(Right : Time_Span) return Time_Span;
This paragraph
was deleted.
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 Nanoseconds (NS : Integer)
return Time_Span;
function Microseconds (US : Integer)
return Time_Span;
function Milliseconds (MS : Integer)
return Time_Span;
function Seconds (S : Integer)
return Time_Span;
function Minutes (M : Integer)
return Time_Span;
type Seconds_Count
is range implementation-defined;
procedure Split(T :
in Time; SC :
out Seconds_Count; TS :
out Time_Span);
function Time_Of(SC : Seconds_Count; TS : Time_Span)
return Time;
private
... -- not specified by the language
end Ada.Real_Time;
In this Annex,
real time
is defined to be the physical time as observed in the external environment.
The type Time is a
time type as defined by
9.6;
values of this type may be used in a
delay_until_statement.
Values of this type represent segments of an ideal time line. The set
of values of the type Time corresponds one-to-one with an implementation-defined
range of mathematical integers.
The Time
value I represents the half-open real time interval that starts with
E+I*Time_Unit and is limited by E+(I+1)*Time_Unit, where Time_Unit is
an implementation-defined real number and E is an unspecified origin
point, the
epoch, that is the same for all values of the type
Time. It is not specified by the language whether the time values are
synchronized with any standard time reference. For example, E can correspond
to the time of system initialization or it can correspond to the epoch
of some time standard.
Values of the type Time_Span represent length of
real time duration. The set of values of this type corresponds one-to-one
with an implementation-defined range of mathematical integers. The Time_Span
value corresponding to the integer I represents the real-time duration
I*Time_Unit.
Time_First and Time_Last are the smallest and largest
values of the Time type, respectively. Similarly, Time_Span_First and
Time_Span_Last are the smallest and largest values of the Time_Span type,
respectively.
A value of type Seconds_Count represents an elapsed
time, measured in seconds, since the epoch.
Dynamic Semantics
Time_Unit is the smallest amount of real time representable
by the Time type; it is expressed in seconds. Time_Span_Unit is the difference
between two successive values of the Time type. It is also the smallest
positive value of type Time_Span. Time_Unit and Time_Span_Unit represent
the same real time duration.
A
clock tick
is a real time interval during which the clock value (as observed by
calling the Clock function) remains constant. Tick is the average length
of such intervals.
The function To_Duration converts the value TS to
a value of type Duration. Similarly, the function To_Time_Span converts
the value D to a value of type Time_Span. For To_Duration, the result
is rounded to the nearest value of type Duration (away from zero if exactly
halfway between two values). If the result is outside the range of Duration,
Constraint_Error is raised. For To_Time_Span, the value of D is first
rounded to the nearest integral multiple of Time_Unit, away from zero
if exactly halfway between two multiples. If the rounded value is outside
the range of Time_Span, Constraint_Error is raised. Otherwise, the value
is converted to the type Time_Span.
To_Duration(Time_Span_Zero) returns 0.0, and To_Time_Span(0.0)
returns Time_Span_Zero.
The functions Nanoseconds, Microseconds, Milliseconds,
Seconds, and Minutes convert the input parameter to a value of the type
Time_Span. NS, US, MS, S, and M are interpreted as a number of nanoseconds,
microseconds, milliseconds, seconds, and minutes respectively. The input
parameter is first converted to seconds and rounded to the nearest integral
multiple of Time_Unit, away from zero if exactly halfway between two
multiples. If the rounded value is outside the range of Time_Span, Constraint_Error
is raised. Otherwise, the rounded value is converted to the type Time_Span.
The effects of the operators on Time and Time_Span
are as for the operators defined for integer types.
The function Clock returns the amount of time since
the epoch.
The effects of the Split and Time_Of operations are
defined as follows, treating values of type Time, Time_Span, and Seconds_Count
as mathematical integers. The effect of Split(T,SC,TS) is to set SC and
TS to values such that T*Time_Unit = SC*1.0 + TS*Time_Unit, and 0.0 <=
TS*Time_Unit < 1.0. The value returned by Time_Of(SC,TS) is the value
T such that T*Time_Unit = SC*1.0 + TS*Time_Unit.
Implementation Requirements
The range of Time values shall be sufficient to uniquely
represent the range of real times from program start-up to 50 years later.
Tick shall be no greater than 1 millisecond. Time_Unit shall be less
than or equal to 20 microseconds.
The value of Time_Span_First in seconds shall be
no greater than –3600, and the value of Time_Span_Last in seconds
shall be no less than 3600.
A
clock jump is the difference
between two successive distinct values of the clock (as observed by calling
the Clock function). There shall be no backward clock jumps.
Documentation Requirements
The implementation shall document the values of Time_First,
Time_Last, Time_Span_First, Time_Span_Last, Time_Span_Unit, and Tick.
The implementation shall document the properties
of the underlying time base used for the clock and for type Time, such
as the range of values supported and any relevant aspects of the underlying
hardware or operating system facilities used.
The implementation shall document whether or not
there is any synchronization with external time references, and if such
synchronization exists, the sources of synchronization information, the
frequency of synchronization, and the synchronization method applied.
The implementation shall document any aspects of
the external environment that can interfere with the clock behavior as
defined in this subclause.
Metrics
For the purpose of the metrics defined in this subclause,
real time is defined to be the International Atomic Time (TAI).
The implementation
shall document the following metrics:
An upper bound on the real-time duration of a clock
tick. This is a value D such that if t1 and t2 are any real times such
that t1 < t2 and Clockt1
= Clockt2
then t2 – t1 <= D.
An upper bound on the size of a clock jump.
An upper bound on the
drift
rate of Clock with respect to real time. This is a real number D
such that
E*(1–D) <= (Clockt+E – Clockt) <= E*(1+D)
provided that: Clockt + E*(1+D) <= Time_Last.
where Clockt
is the value of Clock at time t, and E is a real time duration not less
than 24 hours. The value of E used for this metric shall be reported.
An upper bound on the execution time of a call
to the Clock function, in processor clock cycles.
Upper bounds on the execution times of the operators
of the types Time and Time_Span, in processor clock cycles.
Implementation Permissions
Implementations targeted to machines with word size
smaller than 32 bits may omit support for the full range and granularity
of the Time and Time_Span types.
Implementation Advice
When appropriate, implementations should provide
configuration mechanisms to change the value of Tick.
It is recommended that Calendar.Clock and Real_Time.Clock
be implemented as transformations of the same time base.
It is recommended that the “best” time
base which exists in the underlying system be available to the application
through Clock. “Best” may mean highest accuracy or largest
range.
NOTE 1 The rules in this subclause
do not imply that the implementation can protect the user from operator
or installation errors that can result in the clock being set incorrectly.
NOTE 2 Time_Unit is the granularity
of the Time type. In contrast, Tick represents the granularity of Real_Time.Clock.
There is no requirement that these be the same.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe