Time constructs

Absolute time

Timber allows explicit expression of time constraints on reactions in a program. As a basis for this, we assume a notion of absolute or real time, which progresses independently of program executions. With each action call in a program is associated two absolute time instants, the baseline and the deadline. The intuition is that execution of the action must not start before the baseline and must be finished by the deadline. The time interval between these two instants is the time window of the action.

Timber programs cannot express or access absolute time, but the runtime system has access to a realtime clock and can obtain the current time.The resolution of this clock is platform-dependent.

The type Time

There is, instead, a primitive type Time of durations, or lengths of time intervals, that may occur in programs. Time values can also be computed by the runtime system as the duration of the time interval between two instants.

The type is abstract; Time values can be constructed using the primitive functions

sec, millisec, microsec :: Int -> Time

which expect a non-negative argument. Of course, e.g., sec 1 and millisec 1000 denote the same time value.

There is a predefined instance numTime :: Num Time, so time durations can be added and subtracted using arithmetic notation, as in sec 2 + millisec 500. Subtraction of a larger value from a smaller yields time 0 and multiplication is undefined (an attempt to multiply two time values raises an exception).

To deconstruct time values, one uses the primitive functions

secOf, microsecOf :: Time -> Int

secOf rounds downwards to whole seconds and microsecOf returns the fraction, a value between 0 and 999999.

Time constraints

Time windows of reactions are assigned as follows:

The class timer

As mentioned above, programs cannot access absolute time, but they can measure durations of time intervals. For this, they make use of the primitive class timer, where

timer :: Class Timer

struct Timer where
   reset  :: Request ()
   sample :: Request Time

When a new object of class timer is created, it stores the baseline of the current reaction. When, later, sample is called, the duration from the stored time to the current baseline is returned. Calls to reset updates the stored time to the current baseline.

Scheduling

Baselines and deadlines provide the basis for scheduling of Timber programs. The scheduler is preemptive and uses the EDF strategy (Earliest Deadline First):

At each interrupt (from external sources or internal runtime system timers) or method termination, the reaction to execute next is chosen as follows: Messages with future baselines cannot yet execute and are stored in a list sorted by baseline with a running timer that expires at the earliest baseline. Eligible messages are sorted by deadline and the message with the earliest deadline is chosen for execution.