/*
This file is part of JOP, the Java Optimized Processor
see <http://www.jopdesign.com/>
This subset of javax.realtime is provided for the JSR 302
Safety Critical Specification for Java
Copyright (C) 2008-2011, Martin Schoeberl (martin@jopdesign.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package javax.realtime;
import javax.safetycritical.annotate.Allocate;
//import javax.safetycritical.annotate.Level;
import javax.safetycritical.annotate.SCJAllowed;
import javax.safetycritical.annotate.SCJRestricted;
import static javax.safetycritical.annotate.Allocate.Area.CURRENT;
import static javax.safetycritical.annotate.Allocate.Area.THIS;
import static javax.safetycritical.annotate.Level.LEVEL_1;
/**
* A clock marks the passing of time. It has a concept of now that can
* be queried
* through Clock.getTime(), and it can have events queued on it which will be
* fired when their appointed time is reached.
*
* The Clock instance returned by getRealtimeClock() may be used in any
* context that requires a clock.
*
* TBD: is the following still true for us? I (MS) assume that Kelvin would
* like to drive scheduling with user defined clocks.
*
* HighResolutionTime instances that use
* other clocks are not valid for any purpose that involves sleeping
* or waiting, including in members of the
* RealtimeThread.waitForNextPeriod() family. They may,
* however, be used in the fire time and the period of OneShotTimer
* and PeriodicTimer.
*/
@SCJAllowed
public abstract class Clock {
// it is in the concrete implementation
// static Clock single = null; // new RealtimeClock();
/**
* There is always at least one clock object available: the
* system real-time clock. This is the default Clock.
* @return The singleton instance of the default Clock.
*/
@SCJAllowed
@SCJRestricted(maySelfSuspend = false)
public static Clock getRealtimeClock() {
return RealtimeClock.single;
}
/**
* Gets the current time in a newly allocated object. Note: This
* method will return an absolute time value that represents the
* clock's notion of an absolute time. For clocks that do not
* measure calendar time this absolute time may not represent a wall
* clock time.
* @return A newly allocated instance of AbsoluteTime in the current
* allocation context, representing the current time. The returned
* object is associated with this clock.
*/
@Allocate( { CURRENT })
@SCJAllowed
@SCJRestricted(maySelfSuspend = false)
public abstract AbsoluteTime getTime();
/**
* Gets the current time in an existing object. The time represented by the
* given AbsoluteTime is changed at some time between the invocation of the
* method and the return of the method. Note: This method will return an
* absolute time value that represents the clock's notion of an absolute
* time. For clocks that do not measure calendar time this absolute time may
* not represent a wall clock time.
*
* @param dest
* The instance of AbsoluteTime object which will be updated in
* place. The clock association of the dest parameter is ignored.
* When dest is not null the returned object is associated with
* this clock. If dest is null, then nothing happens.
* @return The instance of AbsoluteTime passed as parameter, representing
* the current time, associated with this clock, or null if dest was
* null.
*/
@SCJAllowed
@SCJRestricted(mayAllocate = false, maySelfSuspend = false)
public abstract AbsoluteTime getTime(AbsoluteTime dest);
/**
* Constructor for the abstract class.
*
* Allocates resolution here.
*/
@Allocate( { THIS })
@SCJAllowed
@SCJRestricted(maySelfSuspend = false)
public Clock() {
}
/**
* Gets the resolution of the clock, the nominal interval between ticks.
*
* @return previously allocated resolution object.
*/
@SCJAllowed
@SCJRestricted(maySelfSuspend = false)
public abstract RelativeTime getResolution();
/**
* Gets the resolution of the clock, the nominal interval between ticks.
*
* TBD: getTime with a destination null will ignore it and return null. This
* method (getResolution) will allocated a new object when dest is null.
*
* @param dest return the relative time value in dest. If dest is
* null, allocate a new RelativeTime instance to hold the returned
* value.
* @return dest set to values representing the resolution of
* this. The returned object is associated with this clock.
*/
@SCJAllowed
@SCJRestricted(mayAllocate = false, maySelfSuspend = false)
public abstract RelativeTime getResolution(RelativeTime dest);
/**
* Returns the relative time of the offset of the epoch of this
* clock from the Epoch. For the real-time clock it will return a
* RelativeTime value equal to 0. An UnsupportedOperationException
* is thrown if the clock does not support the concept of date.
* @return A newly allocated RelativeTime object in the current
* execution context with the offset past the Epoch for this
* clock. The returned object is associated with this clock.
*/
@Allocate( { CURRENT })
@SCJAllowed
@SCJRestricted(maySelfSuspend = false)
public abstract RelativeTime getEpochOffset();
/**
* Returns true if and only if this Clock is able to trigger the
* execution of time-driven activities. Some user-defined clocks may
* be read-only, meaning the clock can be used to obtain timestamps,
* but the clock cannot be used to trigger the execution of
* events. If a clock that does not return drivesEvents()
* equal true is used to configure a Timer or a sleep() request,
* an IllegalArgumentException will be thrown by the infrastructure.
*
* The default real-time clock does drive events.
*
* @return true if the clock can drive events.
*/
@SCJAllowed
@SCJRestricted(mayAllocate = false, maySelfSuspend = false)
protected abstract boolean drivesEvents();
/**
* Code in the abstract base Clock class makes this call to the
* subclass. The method is expected to implement a mechanism that
* will invoke atTime() in ClockCallBack at time time, and if this
* clock is subject to discontinuities, invoke
* ClockCallBack.discontinuity(javax.realtime.Clock,
* javax.realtime.RelativeTime) each time a clock discontinuity is
* detected.
*
* This method behaves effectively as if it and invocations of clock
* events by this clock hold a common lock.
* @param time The absolute time value on this clock at which
* ClockCallBack.atTime(Clock) should be invoked.
* @param clockEvent The object that should be notified at time. If
* clockEvent is null, unregister the current clock event.
*/
@SCJAllowed(LEVEL_1)
@SCJRestricted(maySelfSuspend = false)
protected abstract void registerCallBack(AbsoluteTime time,
ClockCallBack clockEvent);
/**
* Replace the target time being used by the ClockCallBack registered by
* registerCallBack(AbsoluteTime, ClockCallBack).
*
* @param time The new target time.
* @return false if no ClockEvent is currently registered.
*/
@SCJAllowed(LEVEL_1)
@SCJRestricted(maySelfSuspend = false)
protected abstract boolean resetTargetTime(AbsoluteTime time);
}