Guardian Programmer's Guide

Table Of Contents
Managing Time
Guardian Programmer’s Guide 421922-014
18 - 20
Measuring Long Time Intervals
Measuring Long Time Intervals
The SIGNALTIMEOUT procedure measures elapsed time according to the internal
clock of the CPU in which the calling process is executing. Typically, the CPU clocks in
a system run at slightly different speeds. Recall that the system determines system
time by taking the average of all the CPU times in the system, and then establishes
adjustment values for the various CPU clocks in order to synchronize them.
Elapsed time, which is measured by a CPU clock, is not synchronized with system
time; that is, the adjustment value is not used. When measuring short intervals of
elapsed time, the difference between CPU time and system time is negligible.
However, when measuring long intervals of elapsed time (such as several hours or
more), the difference can be noticeable. Because of this possible “clock drift,” it is not
recommended that you make just one call to the SIGNALTIMEOUT procedure to
measure a long interval of elapsed time when you need a precise measurement that is
synchronized with system time. Instead, you should use a sequence of two or more
calls. The same applies to other procedures, such as DELAY, that also measure time
by a CPU clock.
For example, suppose that you want your application to be notified at a specific system
time, say 12:00 noon. Your program could compare Julian timestamps to compute the
interval between the current system time and 12:00 noon, and then set a timer for that
interval by calling the SIGNALTIMEOUT procedure. However, if 12:00 noon is several
hours away, the timer might miss it by a noticeable amount because of clock drift.
Instead, you could use the SIGNALTIMEOUT procedure to set a timer to expire shortly
before 12:00 noon. When the timer expires (that is, when the Time signal message is
delivered to $RECEIVE), your application could compute the remaining time (again, by
comparing Julian timestamps), and then set another timer for the short interval that
remains.
However, because the possibility of a discrepancy due to clock drift becomes greater
as the interval being timed becomes longer, it is even safer to measure a long time
interval by dividing it into a series of relatively short intervals. One method is to
compute the interval between the current time and the desired time and set a timer to
expire after half that interval. When the timer expires, compute the remaining time and
set another timer to expire after half that interval, and so on, approaching the desired
time by progressively smaller steps. The code example in the following subsection
uses this method.
A Sample Long-Range Timer
The following program, written in C, allows the user to specify a time of day, according
to system time, at which a timer will expire. The program uses Julian timestamps to
compute the interval between the current system time and the desired system time,
and then uses the SIGNALTIMEOUT procedure to set a timer to expire after half of that
interval. After that expiration, the program computes the time remaining and sets
another timer to expire after half that time, continuing this process reiteratively. The
program is able to wait for as little as one interval unit (0.01 second) if the