javax.realtime
Class Timer

java.lang.Object
  extended by javax.realtime.AsyncEvent
      extended by javax.realtime.Timer
Direct Known Subclasses:
OneShotTimer, PeriodicTimer

public abstract class Timer
extends AsyncEvent

A timer is a timed event that measures time according to a given Clock. This class defines basic functionality available to all timers. Applications will generally use either PeriodicTimer to create an event that is fired repeatedly at regular intervals, or OneShotTimer for an event that just fires once at a specific time. A timer is always associated with at least one Clock, which provides the basic facilities of something that ticks along following some time line (real-time, CPU-time, user-time, simulation-time, etc.). All timers are created disabled and do nothing until start() is called.

Pseudo-Code Representation of State Transitions for Timer

An implementation shall behave effectively as if it implemented the following pseudo-code. Only absolute and relative time behaviors are shown as rational time has been deprecated.

NOTE: The pseudo-code does not take into account any issue of synchronization, it just shows the functionality, and the intended behavior is obtained with groups of and'ed statements interpreted as atomic. This is relevant, for example, in cases where the firing of an AsyncEventHandler is part of the statements preceding a state transition. While the firing causes the release of the handler before the state transition, the execution of the handler does not take place until after the state transition has completed.

The pseudo-code is a model, it should be interpreted as running continuously, with instructions that take no time.

absolute construction state is {not-active, disabled, absolute}
with nextTargetTime = absoluteTime
last_rescheduled_with_AbsoluteTime = TRUE
[(if PeriodicTimer) period = interval]


relative construction state is {not-active, disabled, relative} with nextDurationTime = relativeTime last_rescheduled_with_AbsoluteTime = FALSE [(if PeriodicTimer) period = interval]
{not-active, disabled, absolute} [(if PeriodicTimer) set fired_or_skipped_in_current_activation = FALSE] enable -> no state change, do nothing disable -> no state change, do nothing stop -> no state change, return FALSE start -> [if last_rescheduled_with_AbsoluteTime then [set targetTime = nextTargetTime [if targetTime < currentTime then set targetTime = currentTime] then go to state {active, enabled, absolute}] else [set countingTime = 0 and set durationTime = nextDurationTime then go to state {active, enabled, relative}]] isRunning -> return FALSE reschedule -> [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and no state change] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and go to state {not-active, disabled, relative}]] getFireTime -> throws IllegalStateException destroy -> go to state {destroyed} startDisabled -> [if last_rescheduled_with_AbsoluteTime then [set targetTime = nextTargetTime [if targetTime < currentTime then set targetTime = currentTime] then go to state {active, disabled, absolute}] else [set countingTime = 0 and set durationTime = nextDurationTime then go to state {active, disabled, relative}]]
{not-active, disabled, relative} [(if PeriodicTimer) set fired_or_skipped_in_current_activation = FALSE] enable -> no state change, do nothing disable -> no state change, do nothing stop -> no state change, return FALSE start -> [if last_rescheduled_with_AbsoluteTime then [set targetTime = nextTargetTime [if targetTime < currentTime then set targetTime = currentTime] then go to state {active, enabled, absolute}] else [set countingTime = 0 and set durationTime = nextDurationTime then go to state {active, enabled, relative}]] isRunning -> return FALSE reschedule -> [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and go to state {not-active, disabled, absolute}] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and no state change]] getFireTime -> throws IllegalStateException destroy -> go to state {destroyed} startDisabled -> [if last_rescheduled_with_AbsoluteTime then [set targetTime = nextTargetTime [if targetTime < currentTime then set targetTime = currentTime] then go to state {active, disabled, absolute}] else [set countingTime = 0 and set durationTime = nextDurationTime then go to state {active, disabled, relative}]]
{active, enabled, absolute} [if currentTime >= targetTime then [if PeriodicTimer then [if period > 0 then [fire and set fired_or_skipped_in_current_activation = TRUE and self reschedule via targetTime = (targetTime + period) and re-enter current state] else [fire and go to state {not-active, disabled, absolute}]] else [it is a OneShotTimer so fire and go to state {not-active, disabled, absolute}]]] enable -> no state change, do nothing disable -> go to state {active, disabled, absolute} stop -> [go to state {not-active, disabled, absolute} and return TRUE] start -> throws IllegalStateException isRunning -> return TRUE reschedule -> [if NOT fired_or_skipped_in_current_activation then [if using an instance of AbsoluteTime then [reset the targetTime to absoluteTime arg and re-enter current state] else [reset the durationTime to relativeTime arg and set countingTime = 0 and go to state {active, enabled, relative}]] else [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and no state change] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and no state change]]] getFireTime -> return targetTime destroy -> go to state {destroyed} startDisabled -> throws IllegalStateException
{active, enabled, relative} [if countingTime >= durationTime then [if PeriodicTimer then [if period > 0 then [fire and set fired_or_skipped_in_current_activation = TRUE and self reschedule via durationTime = (durationTime + period) and re-enter current state] else [fire and go to state {not-active, disabled, relative}]] else [it is a OneShotTimer so fire and go to state {not-active, disabled, relative}]]] enable -> no state change, do nothing disable -> go to state {active, disabled, relative} stop -> [go to state {not-active, disabled, relative} and return TRUE] start -> throws IllegalStateException isRunning -> return TRUE reschedule -> [if NOT fired_or_skipped_in_current_activation then [if using an instance of AbsoluteTime then [reset the targetTime to absoluteTime arg and go to state {active, enabled, absolute}] else [reset the durationTime to relativeTime arg and set countingTime = 0 and re-enter current state]] else [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and no state change] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and no state change]]] getFireTime -> return (currentTime + durationTime - countingTime) destroy -> go to state {destroyed} startDisabled -> throws IllegalStateException
{active, disabled, absolute} [if currentTime >= targetTime then [if PeriodicTimer then [if period > 0 then [skip and set fired_or_skipped_in_current_activation = TRUE and self reschedule via targetTime = (targetTime + period) and re-enter current state] else [skip and go to state {not-active, disabled, absolute}]] else [it is a OneShotTimer so skip and go to state {not-active, disabled, absolute}]]] enable -> go to state {active, enabled, absolute} disable -> no state change, do nothing stop -> [go to state {not-active, disabled, absolute} and return TRUE] start -> throws IllegalStateException isRunning -> return FALSE reschedule -> [if NOT fired_or_skipped_in_current_activation then [if using an instance of AbsoluteTime then [reset the targetTime to absoluteTime arg and re-enter current state] else [reset the durationTime to relativeTime arg and set countingTime = 0 and go to state {active, disabled, relative}]] else [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and no state change] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and no state change]]] getFireTime -> return targetTime destroy -> go to state {destroyed} startDisabled -> throws IllegalStateException
{active, disabled, relative} [if countingTime >= durationTime then [if PeriodicTimer then [if period > 0 then [skip and set fired_or_skipped_in_current_activation = TRUE and self reschedule via durationTime = (durationTime + period) and re-enter current state] else [skip and go to state {not-active, disabled, relative}]] else [it is a OneShotTimer so skip and go to state {not-active, disabled, relative}]]] enable -> go to state {active, enabled, relative} disable -> no state change, do nothing stop -> [go to state {not-active, disabled, relative} and return TRUE] start -> throws IllegalStateException isRunning -> return FALSE reschedule -> [if NOT fired_or_skipped_in_current_activation then [if using an instance of AbsoluteTime then [reset the targetTime to absoluteTime arg and go to state {active, disabled, absolute}] else [reset the durationTime to relativeTime arg and set countingTime = 0 and re-enter current state]] else [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and no state change] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and no state change]]] getFireTime -> return (currentTime + durationTime - countingTime) destroy -> go to state {destroyed} startDisabled -> throws IllegalStateException
{destroyed} enable | disable | stop | start | isRunning | reschedule | getFireTime | destroy | startDisabled -> throws IllegalStateException
The following two methods, without loss of generality and to avoid clutter, have been omitted from the above Pseudo-code.
Every state but {destroyed} has: [(if PeriodicTimer) setInterval -> reset period = interval] [(if PeriodicTimer) getInterval -> return period]
The state {destroyed} has: [(if PeriodicTimer) setInterval -> throws IllegalStateException] [(if PeriodicTimer) getInterval -> throws IllegalStateException]

Compact Graphic Representation of State Transitions for Timer

The following compact graphic representation, while not as detailed, complements the State Transitions for Timer pseudo-code:


Constructor Summary
protected Timer(HighResolutionTime time, Clock clock, AsyncEventHandler handler)
          Create a timer that fires according to the given time, based on the Clock clock and is handled by the specified AsyncEventHandler handler.
 
Method Summary
 void addHandler(AsyncEventHandler handler)
          Add a handler to the set of handlers associated with this event.
 void bindTo(java.lang.String happening)
          Should not be called.
 ReleaseParameters createReleaseParameters()
          Create a ReleaseParameters object appropriate to the timing characteristics of this event.
 void destroy()
          Stop this from counting or comparing if active, remove from it all the associated handlers if any, and release as many of its resources as possible back to the system.
 void disable()
          Disable this timer, preventing it from firing.
 void enable()
          Re-enable this timer after it has been disabled.
 void fire()
          Should not be called.
 Clock getClock()
          Return the instance of Clock on which this timer is based.
 AbsoluteTime getFireTime()
          Get the time at which this Timer is expected to fire.
 AbsoluteTime getFireTime(AbsoluteTime dest)
          Get the time at which this Timer is expected to fire.
 boolean handledBy(AsyncEventHandler handler)
          Test to see if the handler given as the parameter is associated with this.
 boolean isRunning()
          Tests this to determine if this is active and is enabled such that when the given time occurs it will fire the event.
 void removeHandler(AsyncEventHandler handler)
          Remove a handler from the set associated with this event.
 void reschedule(HighResolutionTime time)
          Change the scheduled time for this event.
 void setHandler(AsyncEventHandler handler)
          Associate a new handler with this event and remove all existing handlers.
 void start()
          Start this timer.
 void start(boolean disabled)
          Start this timer.
 boolean stop()
          Stops a timer if it is active and changes its state to not-active and disabled.
 
Methods inherited from class javax.realtime.AsyncEvent
unbindTo
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Timer

protected Timer(HighResolutionTime time,
                Clock clock,
                AsyncEventHandler handler)
Create a timer that fires according to the given time, based on the Clock clock and is handled by the specified AsyncEventHandler handler.

Parameters:
time - The time used to determine when to fire the event. A time value of null is equivalent to a RelativeTime of 0, and in this case the Timer fires immediately upon a call to start().
clock - The clock on which to base this timer, overriding the clock associated with the parameter time. If null, the system Realtime clock is used. The clock associated with the parameter time is always ignored.
handler - The default handler to use for this event. If null, no handler is associated with the timer and nothing will happen when this event fires unless a handler is subsequently associated with the timer using the addHandler() or setHandler() method.
Throws:
java.lang.IllegalArgumentException - Thrown if time is a negative RelativeTime value.
java.lang.UnsupportedOperationException - Thrown if the timer functionality cannot be supported using the given clock.
IllegalAssignmentError - Thrown if this Timer cannot hold references to handler and clock.
Method Detail

createReleaseParameters

public ReleaseParameters createReleaseParameters()
Create a ReleaseParameters object appropriate to the timing characteristics of this event. The default is the most pessimistic: AperiodicParameters. This is typically called by code that is setting up a handler for this event that will fill in the parts of the release parameters for which it has values, e.g. cost.

Overrides:
createReleaseParameters in class AsyncEvent
Returns:
A newly created ReleaseParameters object.
Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.

disable

public void disable()
Disable this timer, preventing it from firing. It may subsequently be re-enabled. If the timer is disabled when its fire time occurs then it will not fire. However, a disabled timer created using an instance of RelativeTime for its time parameter continues to count while it is disabled, and no changes take place in a disabled timer created using an instance of AbsoluteTime, in both cases the potential firing is simply masked, or skipped. If the timer is subsequently re-enabled before its fire time and it is enabled when its fire time occurs, then it will fire. It is important to note that this method does not delay the time before a possible firing. For example, if the timer is set to fire at time 42 and the disable() is called at time 30 and enable() is called at time 40 the firing will occur at time 42 (not time 52). These semantics imply also that firings are not queued. Using the above example, if enable was called at time 43 no firing will occur, since at time 42 this was disabled. If the Timer is already disabled, whether it is active or not-active, this method does nothing.

Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.

enable

public void enable()
Re-enable this timer after it has been disabled. (See disable().) If the Timer is already enabled, this method does nothing. If the Timer is not-active, this method does nothing.

Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.

destroy

public void destroy()
Stop this from counting or comparing if active, remove from it all the associated handlers if any, and release as many of its resources as possible back to the system. Every method invoked on a Timer that has been destroyed will throw IllegalStateException.

Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.

getClock

public Clock getClock()
Return the instance of Clock on which this timer is based.

Returns:
The instance of Clock associated with this Timer.
Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.

getFireTime

public AbsoluteTime getFireTime()
Get the time at which this Timer is expected to fire. If the Timer is disabled, the returned time is that of the skipping of the firing. If the Timer is not-active it throws IllegalStateException.

Returns:
The absolute time at which this is expected to fire or to skip, in a newly allocated AbsoluteTime object. If the timer has been created or re-scheduled (see reschedule(HighResolutionTime time)) using an instance of RelativeTime for its time parameter then it will return the sum of the current time and the RelativeTime remaining time before the timer is expected to fire/skip. The clock association of the returned time is the clock on which this timer is based.
Throws:
java.lang.ArithmeticException - Thrown if the result does not fit in the normalized format.
java.lang.IllegalStateException - Thrown if this Timer has been destroyed, or if it is not-active.

getFireTime

public AbsoluteTime getFireTime(AbsoluteTime dest)
Get the time at which this Timer is expected to fire. If the Timer is disabled, the returned time is that of the skipping of the firing. If the Timer is not-active it throws IllegalStateException.

Parameters:
dest - The instance of AbsoluteTime which will be updated in place and returned. The clock association of the dest parameter is ignored. When dest is null a new object is allocated for the result.
Returns:
The instance of AbsoluteTime passed as parameter, with time values representing the absolute time at which this is expected to fire or to skip. If the dest parameter is null the result is returned in a newly allocated object. If the timer has been created or re-scheduled (see reschedule(HighResolutionTime time)) using an instance of RelativeTime for its time parameter then it will return the sum of the current time and the RelativeTime remaining time before the timer is expected to fire/skip. The clock association of the returned time is the clock on which this timer is based.
Throws:
java.lang.ArithmeticException - Thrown if the result does not fit in the normalized format.
java.lang.IllegalStateException - Thrown if this Timer has been destroyed, or if it is not-active.
Since:
1.0.1

isRunning

public boolean isRunning()
Tests this to determine if this is active and is enabled such that when the given time occurs it will fire the event. Given the Timer current state it answer the question "Is firing expected?".

Returns:
true if the timer is active and enabled; false, if the timer has either not been started, it has been started but it is disabled, or it has been started and is now stopped.
Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.

reschedule

public void reschedule(HighResolutionTime time)
Change the scheduled time for this event. This method can take either an AbsoluteTime or a RelativeTime for its argument, and the Timer will behave as if created using that type for its time parameter. The rescheduling will take place between the invocation and the return of the method.

NOTE: While the scheduled time is changed as described above, the rescheduling itself is applied only on the first firing (or on the first skipping if disabled) of a timer's activation. If reschedule is invoked after the current activation timer's firing, then the rescheduled time will be effective only upon the next start or startDisabled command (which may need to be preceded by a stop command).

If reschedule is invoked with a RelativeTime time on an active timer before its first firing/skipping, then the rescheduled firing/skipping time is relative to the time of invocation.

Parameters:
time - The time to reschedule for this event firing. If time is null, the previous time is still the time used for the Timer firing. The clock associated with the parameter time is always ignored.
Throws:
java.lang.IllegalArgumentException - Thrown if time is a negative RelativeTime value.
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.

start

public void start()
Start this timer. A timer starts measuring time from when it is started; this method makes the timer active and enabled.

Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed, or if this timer is already active.

start

public void start(boolean disabled)
Start this timer. A timer starts measuring time from when it is started. If disabled is true start the timer making it active in a disabled state. If disabled is false this method behaves like the start() method.

Parameters:
disabled - If true, the timer will be active but disabled after it is started. If false this method behaves like the start() method.
Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed, or if this timer is already active.
Since:
1.0.1

stop

public boolean stop()
Stops a timer if it is active and changes its state to not-active and disabled.

Returns:
true if this was active and false otherwise.
Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.

fire

public void fire()
Should not be called. The fire method is reserved for the use of the timer.

Overrides:
fire in class AsyncEvent
Throws:
java.lang.UnsupportedOperationException - Thrown if fire is called from outside the Timer implementation.
Since:
1.0.1 Throws UnsupportedOperationException instead of doing unspecified damage.

bindTo

public void bindTo(java.lang.String happening)
Should not be called.

Overrides:
bindTo in class AsyncEvent
Parameters:
happening - An implementation dependent value that binds this instance of AsyncEvent to a happening.
Throws:
java.lang.UnsupportedOperationException - Thrown if bindTo is called on a Timer.
Since:
1.0.1

addHandler

public void addHandler(AsyncEventHandler handler)
Description copied from class: AsyncEvent
Add a handler to the set of handlers associated with this event. An instance of AsyncEvent may have more than one associated handler. However, adding a handler to an event has no effect if the handler is already attached to the event.

The execution of this method is atomic with respect to the execution of the fire() method.

Since this affects the constraints expressed in the release parameters of an existing schedulable object, this may change the feasibility of the current system. This method does not change feasibility set of any scheduler, and no feasibility test is performed.

Note, there is an implicit reference to the handler stored in this. The assignment must be valid under any applicable memory assignment rules.

Overrides:
addHandler in class AsyncEvent
Parameters:
handler - The new handler to add to the list of handlers already associated with this.

If the handler is already associated with the event, the call has no effect.

Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.
IllegalAssignmentError - Thrown if this AsyncEvent cannot hold a reference to handler.
Since:
1.0.1

handledBy

public boolean handledBy(AsyncEventHandler handler)
Description copied from class: AsyncEvent
Test to see if the handler given as the parameter is associated with this.

Overrides:
handledBy in class AsyncEvent
Parameters:
handler - The handler to be tested to determine if it is associated with this.
Returns:
True if the parameter is associated with this. False if handler is null or the parameters is not associated with this.
Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.
Since:
1.0.1

removeHandler

public void removeHandler(AsyncEventHandler handler)
Description copied from class: AsyncEvent
Remove a handler from the set associated with this event. The execution of this method is atomic with respect to the execution of the fire() method.

A removed handler continues to execute until its fireCount becomes zero and it completes.

Since this affects the constraints expressed in the release parameters of an existing schedulable object, this may change the feasibility of the current system. This method does not change the feasibility set of any scheduler, and no feasibility test is performed.

Overrides:
removeHandler in class AsyncEvent
Parameters:
handler - The handler to be disassociated from this. If null nothing happens. If the handler is not already associated with this then nothing happens.
Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.
Since:
1.0.1

setHandler

public void setHandler(AsyncEventHandler handler)
Description copied from class: AsyncEvent
Associate a new handler with this event and remove all existing handlers. The execution of this method is atomic with respect to the execution of the fire() method.

Since this affects the constraints expressed in the release parameters of the existing schedulable objects, this may change the feasibility of the current system. This method does not change the feasibility set of any scheduler, and no feasibility test is performed.

Overrides:
setHandler in class AsyncEvent
Parameters:
handler - The new instance of AsyncEventHandler to be associated with this. If handler is null then no handler will be associated with this (i.e., remove all handlers).
Throws:
java.lang.IllegalStateException - Thrown if this Timer has been destroyed.
IllegalAssignmentError - Thrown if this AsyncEvent cannot hold a reference to handler.
Since:
1.0.1