Time Manager Versions
version released. The three versions are all upwardly compatible-that is, each
succeeding Time Manager version is a functional superset of the previous one, and code written for a version of the
Time Manager executes on any later version. The reverse, however, is not true, and code written for the extended Time Manager may not execute properly on either the original or revised version. As a result, it is sometimes
important to know which Time Manager version is available on a specific machine. You can use the Gestalt function to determine which version is present.
The Original Time Manager
(which are also contained in the Macintosh 512K enhanced) and was intended
for use internally by the Operating System. Volume IV of Inside Macintosh
documented the routines in the original Time Manager, and thereafter some
applications used them to schedule tasks to be executed at later times. The
original Time Manager allows delays as small as 1 millisecond, resulting in a
maximum range of about 24 days.
To schedule a task for later execution, you place an entry into the
manipulate elements of the Time Manager queue, which are stored in a struct TMTask // original and revised Time Manager task record {
short qType ; // queue type
Of the four fields in this record, your application needs to supply only the
tmAddr field, which contains a pointer to the routine that is to be executed at
some time in the future. The remaining fields are used internally by the
Time Manager or are reserved by Apple. Your application should set these remaining fields to 0 when you set up a task record.
The original Time Manager includes three routines:
• The InsTime procedure installs a task record into the • The PrimeTime procedure schedules a previously queued task record for future execution.
• The RmvTime procedure removes a task record from the Note that installing a request into the Time Manager queue (using the InsTime procedure) does not by itself schedule the specified routine for future execution. After you queue a request, you still need to activate (or
prime) the request by specifying the desired delay until execution (using the
PrimeTime procedure). Note also that the task record is not automatically removed from the Time Manager queue after the routine executes. As a result, the task may be reactivated when you subsequently call PrimeTime; you do not have to reinstall the task record. To remove a task record from the
record from the Time Manager queue whether or not that task was ever activated and whether or not its specified time delay has expired.
The Revised Time Manager
System software version 6.0.3 contains a revised version of the
Time Manager. This version provides better time resolution and the ability to perform measurements of elapsed time with much greater accuracy. You can
represent time delays in the revised Time Manager as microseconds as well as milliseconds, with a maximum resolution of 20 microseconds. The external
programming interface did not change from the original to the revised
Time Manager, although the revised version provides a means to distinguish microsecond delays from millisecond delays. The revised
Time Manager interprets negative time values (which were not formerly allowed) as negated microseconds. For example, a value of -50 is interpreted
as a delay of 50 microseconds. Positive time values continue to represent
milliseconds. When you specify delays as microseconds, the maximum delay is
about 35 minutes. When you specify delays as milliseconds in the revised
Time Manager, the maximum delay is about 1 day. The delay specified to PrimeTime is converted to an internal form, so it makes no difference which unit you use if the delay falls within the ranges of both.
The principal change concerns the tmCount field of the Time Manager task record (previously reserved for use by Apple). When you remove an active
task from the revised Time Manager queue, any time remaining until the scheduled execution time is returned in the tmCount field. This change allows
you to use the Time Manager to compute elapsed times (as explained in the task record is now a flag to indicate whether the task timer is active. The
cleared when the time expires or when your application calls RmvTime. Although the revised Time Manager supports delay times specified in microseconds, you should use this feature primarily for the more accurate
measurement of elapsed times. Applications that specify very small delay times
in order to execute a routine at a high frequency may use a considerable
amount of processor time. The amount of processor time consumed by such
timing services varies, depending largely on the performance of the CPU. With
low- performance CPUs, little or no time may be left for other processing on
the system (for instance, moving the mouse or running the application).
The Extended Time Manager
The extended Time Manager (available with System 7.0) contains all the features of earlier Time Managers, with several extensions intended
primarily to provide drift-free, fixed-frequency timing services. These
services ensure that a routine executes promptly after a specified delay and
are important for sound and multimedia applications that require precise
timing and real-time synchronization among different events.
In the original and revised Time Managers, the delay time passed to
PrimeTime indicates a delay that is relative to the current time (that is, the time at which you execute PrimeTime). This presents problems when you need a fixed-frequency timing service and attempt to implement it by
having the task reissue a PrimeTime call. The problem is that the time consumed by the Time Manager and by any interrupt latency (which is not predic table) causes the task to be called at a slightly slower and unpredic table
frequency, which drifts over time. In the following figure, a fixed frequency of
1000 microseconds is desired but cannot be achieved because the
Time Manager overhead and interrupt latency cause a small and unpredictable delay each time the task is reactivated.
Original and revised Time Managers (drifting, unpredictable frequency)
The extended Time Manager solves this problem by allowing you to reinstall a task with an execution time that is relative to the time when the
task last expired-not relative to the time when the task is re installed. The
extended Time Manager compensates for the delay between the time when the task last expired and the time at which it was re installed, thereby providing a
truly drift-free, fixed-frequency timing service.
For example, if an application needs to execute a routine periodically at
1-millisecond intervals, it can reactivate the existing Time Manager queue element by calling PrimeTime in the task with a specified delay of 1 millisecond. When the Time Manager receives this new execution request, it determines how long ago the previous PrimeTime task expired and then decrements the specified delay by that amount. For instance, if the
previous task expired 100 microseconds ago, then the Time Manager installs the new task with a delay of 900 microseconds. This is illustrated in the
following figure.
The extended Time Manager (drift-free, fixed frequency)
The extended Time Manager implements these features by recognizing an expanded task record and providing a new procedure, InsXTime. The Short qType // queue type
Long tmCount // unused time Long tmWakeUp // wakeup time Long tmReserved // reserved for future use Once again, your application provides the tmAddr field. You should set
tmWakeUp and tmReserved to 0 when you first install an extended
Time Manager task. The remaining fields are used internally by the the time remaining until the scheduled execution of the task (this field is set
The tmWakeUp field contains the time at which the
Time Manager task specified by tmAddr last executed or contains 0 if it has not yet executed. Its principal intended use is to provide drift-free,
fixed-frequency timing services, which are available only when you use the
extended
new InsXTime procedure. When your application installs an extended PrimeTime procedure changes slightly, as described earlier in this section. If the tmWakeUp field is zero when PrimeTime is called, the delay parameter to PrimeTime is interpreted as relative to the current time (just sets the tmWakeUp field to a nonzero value that indicates when the delay time
should expire. When your application calls PrimeTime on a Time Manager task that has a nonzero value in the tmWakeUp field, the Time Manager interprets the specified delay as relative to the time that the last call to PrimeTime on this task was supposed to expire. Note: Nonzero values in tmWakeUp are in a format that is used internally
by the Time Manager and is subject to change. Your application should never use the value stored in this field and should either set it to 0 or leave
it un changed. When you first create an extended task record, you must
ensure that the tmWakeUp field is 0; otherwise, the Time Manager may interpret it as a prior execution time.
The extended Time Manager allows for a situation that was previously impossible and that may lead to undesirable results. It is possible to call
PrimeTime with an execution time that is in the past instead of in the future. (With the original and revised Time Managers, only future execution
times are possible.) This situation arises when the time in the tmWakeUp field
is sometime in the past (which is most common in the tmAddr service routine)
and you issue a new PrimeTime request with a delay value that is not large enough to cause the execution time to be in the future. This may occur when
fixed, high-frequency execution is required and the time needed to process
each execution, including the
Time Manager overhead, is greater than the delay time between requests. When your application issues a PrimeTime request with a tmWakeUp value that would result in a negative delay, the actual delay time is set to 0. The
Time Manager updates the tmWakeUp field to indicate the time when the task should have awakened (in the past). Because the actual delay time is set to
0, the task executes immediately. If your application continually issues
tmAddr tasks consume all of the processor cycles. As a result, no time is left
for the application to run. This situation is a function of processor speed, so
you should test applications that use extended Time Manager features on the slowest processors to ensure compatibility. Another solution to this problem
is to vary the wakeup frequency according to the processing power of the
machine.
Other Time-Related Facilities
The Operating System and Toolbox include several other time-related
facilities that complement the services provided by the Time Manager. There are three principal facilities: the TickCount function, the Delay may be more appropriate for your particular timing needs than