Contents Index Previous Next
9.6 Delay Statements, Duration, and Time
1
[
{expiration time [partial]}
A
delay_statement
is used to block further execution until a specified
expiration time
is reached. The expiration time can be specified either as a particular
point in time (in a
delay_until_statement),
or in seconds from the current time (in a
delay_relative_statement).
The language-defined package Calendar provides definitions for a type
Time and associated operations, including a function Clock that returns
the current time.
{timing: See delay_statement}
]
Syntax
2
delay_statement
::= delay_until_statement |
delay_relative_statement
3
delay_until_statement
::= delay until delay_expression;
4
delay_relative_statement
::= delay delay_expression;
Name Resolution Rules
5
{expected type (delay_relative_statement
expression) [partial]} The expected type
for the
delay_expression
in a
delay_relative_statement is
the predefined type Duration.
{expected type (delay_until_statement
expression) [partial]} The
delay_expression
in a
delay_until_statement is expected
to be of any nonlimited type.
Legality Rules
6
{time type}
{time base} {clock}
There can be multiple time bases, each with a corresponding
clock, and a corresponding
time type. The type of the
delay_expression
in a
delay_until_statement shall be a time
type -- either the type Time defined in the language-defined package Calendar
(see below), or some other implementation-defined time type (see
D.8).
6.a
Implementation defined: Any
implementation-defined time types.
Static Semantics
7
[There is a predefined fixed point type named
Duration, declared in the visible part of package Standard;] a value
of type Duration is used to represent the length of an interval of time,
expressed in seconds. [The type Duration is not specific to a particular
time base, but can be used with any time base.]
8
A value of the type Time in package Calendar,
or of some other implementation-defined time type, represents a time
as reported by a corresponding clock.
9
The following language-defined
library package exists:
10
package Ada.Calendar is
type Time is private;
11
subtype Year_Number is Integer range 1901 .. 2099;
subtype Month_Number is Integer range 1 .. 12;
subtype Day_Number is Integer range 1 .. 31;
subtype Day_Duration is Duration range 0.0 .. 86_400.0;
12
function Clock return Time;
13
function Year (Date : Time) return Year_Number;
function Month (Date : Time) return Month_Number;
function Day (Date : Time) return Day_Number;
function Seconds(Date : Time) return Day_Duration;
14
procedure Split (Date : in Time;
Year : out Year_Number;
Month : out Month_Number;
Day : out Day_Number;
Seconds : out Day_Duration);
15
function Time_Of(Year : Year_Number;
Month : Month_Number;
Day : Day_Number;
Seconds : Day_Duration := 0.0)
return Time;
16
function "+" (Left : Time; Right : Duration) return Time;
function "+" (Left : Duration; Right : Time) return Time;
function "-" (Left : Time; Right : Duration) return Time;
function "-" (Left : Time; Right : Time) return Duration;
17
function "<" (Left, Right : Time) return Boolean;
function "<="(Left, Right : Time) return Boolean;
function ">" (Left, Right : Time) return Boolean;
function ">="(Left, Right : Time) return Boolean;
18
19
private
... -- not specified by the language
end Ada.Calendar;
Dynamic Semantics
20
{execution (delay_statement)
[partial]} For the execution of a
delay_statement,
the
delay_expression is first evaluated.
{expiration time (for a delay_until_statement)}
For a
delay_until_statement,
the expiration time for the delay is the value of the
delay_expression,
in the time base associated with the type of the
expression.
{expiration time (for a delay_relative_statement)}
For a
delay_relative_statement,
the expiration time is defined as the current time, in the time base associated
with relative delays, plus the value of the
delay_expression
converted to the type Duration, and then rounded up to the next clock tick.
{implicit subtype conversion (delay expression) [partial]}
The time base associated with relative delays is as defined
in
D.9, ``
Delay Accuracy''
or is implementation defined.
20.a
Implementation defined: The
time base associated with relative delays.
20.b
Ramification: Rounding
up to the next clock tick means that the reading of the delay-relative
clock when the delay expires should be no less than the current reading
of the delay-relative clock plus the specified duration.
21
{blocked (on a delay_statement)
[partial]} The task executing a
delay_statement
is blocked until the expiration time is reached, at which point it becomes
ready again. If the expiration time has already passed, the task is not
blocked.
21.a
Discussion: For a delay_relative_statement,
this case corresponds to when the value of the delay_expression
is zero or negative.
21.b
Even though the task is not blocked, it
might be put back on the end of its ready queue. See D.2,
``Priority Scheduling''.
22
{cancellation (of
a delay_statement)} If an attempt is made to
cancel the
delay_statement [(as
part of an
asynchronous_select or abort
-- see
9.7.4 and
9.8)],
the
_statement is cancelled if the expiration
time has not yet passed, thereby completing the
delay_statement.
22.a
Reason: This is worded
this way so that in an asynchronous_select
where the triggering_statement is
a delay_statement, an attempt to
cancel the delay when the abortable_part
completes is ignored if the expiration time has already passed, in which
case the optional statements of the triggering_alternative
are executed.
23
The time base associated with the
type Time of package Calendar is implementation defined. The function Clock
of package Calendar returns a value representing the current time for this time
base. [The implementation-defined value of the named number System.Tick (see
13.7) is an approximation of the length of the real-time
interval during which the value of Calendar.Clock remains constant.]
23.a
Implementation defined: The
time base of the type Calendar.Time.
24
The functions Year, Month, Day, and Seconds return
the corresponding values for a given value of the type Time, as appropriate
to an implementation-defined timezone; the procedure Split returns all
four corresponding values. Conversely, the function Time_Of combines
a year number, a month number, a day number, and a duration, into a value
of type Time. The operators "+" and "-" for addition
and subtraction of times and durations, and the relational operators
for times, have the conventional meaning.
24.a
Implementation defined: The
timezone used for package Calendar operations.
25
If Time_Of is called with a seconds value of
86_400.0, the value returned is equal to the value of Time_Of for the
next day with a seconds value of 0.0. The value returned by the function
Seconds or through the Seconds parameter of the procedure Split is always
less than 86_400.0.
26/1
{
8652/0030}
The exception Time_Error is raised by the function Time_Of if the actual parameters
do not form a proper date. This exception is also raised by the operators "+"
and "-" if the result is not representable in the type Time or Duration,
as appropriate. This exception is also raised by the function
s Year
,
Month, Day, and Seconds andor the procedure Split if the year number
of the given date is outside of the range of the subtype Year_Number.
26.a/1
To be honest: {8652/0106}
By "proper date" above we mean that the given year has a month with
the given day. For example, February 29th is a proper date only for a leap year.
We do not mean to include the Seconds in this notion; in particular, we do
not mean to require implementations to check for the ``missing hour'' that occurs
when Daylight Savings Time starts in the spring.
26.b/1
Reason: {8652/0030}
We allow Year and Split to raise Time_Error because the arithmetic operators
are allowed (but not required) to produce times that are outside the range of
years from 1901 to 2099. This is similar to the way integer operators may return
values outside the base range of their type so long as the value is mathematically
correct. We allow the functions Month, Day and Seconds to raise Time_Error
so that they can be implemented in terms of Split.
Implementation Requirements
27
The implementation of the type Duration shall
allow representation of time intervals (both positive and negative) up
to at least 86400 seconds (one day); Duration'Small shall not be greater
than twenty milliseconds. The implementation of the type Time shall allow
representation of all dates with year numbers in the range of Year_Number[;
it may allow representation of other dates as well (both earlier and
later).]
Implementation Permissions
28
An implementation may define additional
time types (see
D.8).
29
An implementation may raise Time_Error if the
value of a delay_expression
in a delay_until_statement of a
select_statement represents a time
more than 90 days past the current time. The actual limit, if any, is
implementation-defined.
29.a
Implementation defined: Any
limit on delay_until_statements
of select_statements.
29.b
Implementation Note: This
allows an implementation to implement select_statement
timeouts using a representation that does not support the full range
of a time type. In particular 90 days of seconds can be represented in
23 bits, allowing a signed 24-bit representation for the seconds part
of a timeout. There is no similar restriction allowed for stand-alone
delay_until_statements, as these
can be implemented internally using a loop if necessary to accommodate
a long delay.
Implementation Advice
30
Whenever possible in an implementation, the value
of Duration'Small should be no greater than 100 microseconds.
30.a
Implementation Note: This
can be satisfied using a 32-bit 2's complement representation with a
small of 2.0**(-14) -- that is, 61 microseconds -- and a range
of ± 2.0**17 -- that is, 131_072.0.
31
The time base for delay_relative_statements
should be monotonic; it need not be the same time base as used for Calendar.Clock.
32
31 A delay_relative_statement
with a negative value of the delay_expression
is equivalent to one with a zero value.
33
32 A delay_statement
may be executed by the environment task; consequently delay_statements
may be executed as part of the elaboration of a library_item
or the execution of the main subprogram. Such statements delay the environment
task (see 10.2).
34
33 {potentially
blocking operation (delay_statement) [partial]} {blocking,
potentially (delay_statement) [partial]} A
delay_statement is an abort completion
point and a potentially blocking operation, even if the task is not actually
blocked.
35
34 There is no necessary
relationship between System.Tick (the resolution of the clock of package
Calendar) and Duration'Small (the small of type Duration).
35.a
Ramification: The inaccuracy
of the delay_statement has no relation
to System.Tick. In particular, it is possible that the clock used for
the delay_statement is less accurate
than Calendar.Clock.
35.b
We considered making Tick a run-time-determined
quantity, to allow for easier configurability. However, this would not be upward
compatible, and the desired configurability can be achieved using functionality
defined in Annex D, ``Real-Time
Systems''.
36
35 Additional requirements associated
with delay_statements are given in D.9,
``Delay Accuracy''.
Examples
37
Example of a
relative delay statement:
38
delay 3.0; -- delay 3.0 seconds
39
{periodic
task (example)} {periodic
task: See delay_until_statement} Example
of a periodic task:
40
declare
use Ada.Calendar;
Next_Time : Time := Clock + Period;
-- Period is a global constant of type Duration
begin
loop -- repeated every Period seconds
delay until Next_Time;
... -- perform some actions
Next_Time := Next_Time + Period;
end loop;
end;
Inconsistencies With Ada 83
40.a
{inconsistencies with Ada 83}
For programs that raise Time_Error on "+"
or "-" in Ada 83,the exception might be deferred until a call
on Split or Year_Number, or might not be raised at all (if the offending
time is never Split after being calculated). This should not affect typical
programs, since they deal only with times corresponding to the relatively
recent past or near future.
Extensions to Ada 83
40.b
{extensions to Ada 83}
The syntax rule for delay_statement
is modified to allow delay_until_statements.
40.c
The type Time may represent dates
with year numbers outside of Year_Number. Therefore, the operations "+"
and "-" need only raise Time_Error if the result is not representable
in Time (or Duration); also, Split or Year will now raise Time_Error
if the year number is outside of Year_Number. This change is intended
to simplify the implementation of "+" and "-" (allowing
them to depend on overflow for detecting when to raise Time_Error) and
to allow local timezone information to be considered at the time of Split
rather than Clock (depending on the implementation approach). For example,
in a POSIX environment, it is natural for the type Time to be based on
GMT, and the results of procedure Split (and the functions Year, Month,
Day, and Seconds) to depend on local time zone information. In other
environments, it is more natural for the type Time to be based on the
local time zone, with the results of Year, Month, Day, and Seconds being
pure functions of their input.
40.d
We anticipate that implementations
will provide child packages of Calendar to provide more explicit control
over time zones and other environment-dependent time-related issues.
These would be appropriate for standardization in a given environment
(such as POSIX).
Contents Index Previous Next Legal