The RTSJ was first published in mid-2000, as RTSJ version 0.9. Version 0.9 was the result of the Expert Group's work between early 1999 and shortly before Java One in 2000. This document was not intended as a usable specification, but rather as a "draft for discussion."
Vigorous work on the specification continued after the publication of version 0.9, especially creation of the reference implementation and first use of the reference implementation. That work resulted in the first official version of RTSJ, which emerged from the Java Community Process (JCP) in January of 2002.
Work on the RTSJ hardly slowed when the specification was formally released. Several members of the Expert Group joined some interested members of the RTSJ community as the Technical Interpretation Committee (TIC) and continued to improve the specification.
The RTSJ TIC
|
|
---|---|
Ben Brosgol | Ada Core |
David Holmes | DLTeCH Pty |
Rudy Belliardi | Schneider Automation |
Doug Locke | TimeSys |
Peter Dibble | TimeSys |
Andy Wellings | University of York |
The main product of the TIC's work was RTSJ version 1.0.1, a much more complete version of the specification. The amount of additional detail is indicated by the increase in the size of the printed document from around 250 pages to around 500 pages between RTSJ version 1.0 and 1.0.1. The revised specification emerged from the JCP maintenance review process in March 2005, and the TIC continued work.
This document is RTSJ version 1.0.2. It continues the interpretation work of 1.0.1 with many of the changes between 1.0.1. and 1.0.2 motivated by requests for clarification by RTSJ implementors and users.
The next stage of the RTSJ's evolution is a new JSR. The Expert Group for RTSJ version 1.1 has already been formed, and the proposal for RTSJ version 1.1 can be found on the Java Community Process site in the JSR 282 page.
The latest information about the RTSJ is most easily found through the informal RTSJ web site. This site includes the latest version of the RTSJ in HTML, an archive of earlier versions of the specification, RTSJ example code, papers, useful links (such as a link to the download site for the Reference Implementation), and information about current implementations of the RTSJ.
NIST supports an RTSJ mailing list, rtj-discuss, which is an excellent place to exchange email with the RTSJ community. Instructions for joining this mailing list can be found on the informal RTSJ web site.
Version 1.0.2 is primarily a set of clarifications and changes derived from exchanges with several teams implementing RTSJ. Version 1.0.2 also tightens the specification a little where those changes will not greatly harm implementability.
The revised finalization semantics attempt to clarify the algorithm for finalizing objects in a scope in passes until there are no more finalizable objects or the finalizers create a schedulable object that references the scope. The revised semantics also require the schedulable object exiting the scope when it becomes finalizable to run the finalizers.
The concept of deferred suspension has been added to cost enforcement for schedulable objects, and enforced priority has been defined for processing groups.
A conflict between the 1.0.1 semantics, and the method documentation and RI was resolved by specifying that an async event handler's fire count is decremented before invoking handleAsyncEvent.
The semantics for the fire count manipulation methods have been specified for all callers.
Interruptible blocking methods are defined, as are the semantics for interrupting those methods.
In some cases where there was ambiguity about which exception should be thrown, the exception precedence has been clarified.
The primary objective of the 1.0.1 version of the RTSJ was clarification. That clarification resulted in a nearly complete re-write of the semantics and requirements sections, but those revisions were not intended to express different semantics. They were intended to express the original semantics:
Deprecation in this version should be treated as emphatic advice to avoid the deprecated feature. In RTSJ 1.0.1, deprecation usually means that the semantics for a class or method may not be actively dangerous, but for various reasons its semantics cannot be clarified in a reasonable and unambiguous way. These methods (and one class) are not necessary, and they will almost certainly be entirely removed soon. In any case, their semantics are not well-defined, they cannot be adequately tested, and any application that values portability should not use them.
The processing group enforcement option has been separated from the cost enforcement option, and support for processing group deadline less than period has been made optional.
A profile for development tools has been introduced. This permits a development tool to implement RTSJ classes without implementing all the RTSJ semantics.
As much as possible, semantics that relate to scheduling have been made attributes of the scheduler, this caused many semantics to move from the Threads chapter to the Scheduling chapter.
MemoryArea getMemoryArea()
to return the initial memory area of the RealtimeThread.
This method that was in the 1.0 reference implementation and the TCK, but was left out of the specification.
setPriority
in java.lang.Thread
are described.
waitForNextPeriod
is made static
since it would be dangerous for a thread to invoke the method on any other thread.
waitForNextPeriodInterruptible
because (especially for real-time systems) blocking methods should be interruptible.
setIfFeasible
methods (See the Schedulable interface.)
None
Let fireSchedulable
throw UnsupportedOperationException
because only specific classes (possibly no classes) that implement the Schedulable
interface can be fired by any given scheduler.
Add method
public abstract boolean setIfFeasible(Schedulable schedulable, SchedulingParameters scheduling, ReleaseParameters release, MemoryParameters memory, ProcessingGroupParameters group)
The following methods were made abstract:
public abstract boolean setIfFeasible (Schedulable schedulable, ReleaseParameters release, MemoryParameters memory)
public abstract boolean setIfFeasible (Schedulable schedulable, ReleaseParameters release, MemoryParameters memory, ProcessingGroupParameters group)
A number of methods were consistently present in classes that implement Schedulable
and should have been included in Schedulable
. They were added to the Schedulable
interface:
boolean addIfFeasible()
,
boolean setIfFeasible(ReleaseParameters release, MemoryParameters memory),
boolean setIfFeasible(ReleaseParameters release, MemoryParameters memory, ProcessingGroupParameters group),
boolean setIfFeasible(ReleaseParameters release, ProcessingGroupParameters group)
Two methods were added to improve the parallel construction of the Scheduler and the Schedulable interface. The new methods also make it possible to update the scheduling parameters considering feasibility:
boolean setIfFeasible(SchedulingParameters sched,
ReleaseParameters release,
MemoryParameters memory)
boolean setIfFeasible(SchedulingParameters sched,
ReleaseParameters release,
MemoryParameters memory,
ProcessingGroupParameters group)
IllegalThreadStateException
was removed from the throws
clause of the setScheduler
methods because there is no case where that exception will be thrown.
ReleaseParameters
now implements Cloneable
and has a public clone
method.
SchedulingParameters
now implements Cloneable
and has a public clone
method.
The constructor is changed to protected
to match similar classes, such as ReleaseParameters
.
Two new constructors,
PeriodicParameters(RelativeTime period)
PeriodicParameters(HighResolutionTime start, RelativeTime period)
were added to conveniently support common patterns, and as pro-active support for a safety-critical specification.
ProcessingGroupParameters
now implements Cloneable
and has a public clone
method.
The methods and constants that relate to the arrival time queue overflow behavior have been moved from SporadicParameters
to AperiodicParameters
because the arrival time queue is an aspect of aperiodic tasks. The implementation had to maintain the queue, but the application could not control it unless it used sporadic parameters. The list of moved methods and constants is:
String arrivalTimeQueueOverflowExcept
String arrivalTimeQueueOverflowIgnore
String arrivalTimeQueueOverflowReplace
String arrivalTimeQueueOverflowSave
int getInitialArrivalTimeQueueLength()
void setInitialArrivalTimeQueueLength(int length)
void setArrivalTimeQueueOverflowBehavior(String behavior)
String getArrivalTimeQueueOverflowBehavior()
A new constructor:
AperiodParameters()
has been added to make a common case easier to write, and to proactively support work on the safety critical Java specification.
The methods and constants listed as moved to AperiodicParameters
are moved from SporadicParameters
. They still appear in the sporadic parameters class, but now they are inherited from aperiodic parameters.
A new constructor:
SporadicParameters(RelativeTime minInterarrival)
has been added to make a common case easier to write, and to proactively support work on the safety critical Java specification.
The semantics for the REPLACE MIT violation policy for sporadic parameters has been revised to "If the last event has not been processed revise its release time to the current time. This will alter the deadline at any time up to completion of its processing or the time it misses its deadline. If event processing for the replaced release has been completed or it has already missed its deadline, the behavior of the REPLACE policy is equivalent to IGNORE."
The fireSchedulable
method is permitted to throw UnsupportedOperationException
if the scheduler does not support the method for parameter object. The base instance of the priority scheduler is expected to throw UnsupportedOperationException
in every case. The fireSchedulable
method has never worked, and its semantics are hard to clarify without significantly extending the semantics of schedulable objects. The method is not deprecated because the semantics of schedulable objects quite likely will be extended to make this method useful, but that goes beyond clarification.
SchedulingParameters
now implements Cloneable
and has a public clone
method.
The constructor is changed from public to protected.
No changes
No changes
ProcessingGroupParameters
now implements Cloneable
and has a public clone
method
MAX_PRIORITY,
and MIN_PRIORITY
are deprecated because they may bind the maximum and minimum priorities into an application at compile time and the available priority range is an attribute of the run-time platform.
The throws clause of:
newArray(Class type, int number)
has been changed from(IllegalAccessException InstantiationException)
to no exceptions to better reflect the checked exceptions thrown when the underlying platform creates a new array.
The throws clause of:
newInstance(reflect.Constructor c, Object[] args)
has been changed from(IllegalAccessException InstantiationException)
to (IllegalAccessException, InstantiationException, InvocationTargetException)
to reflect the checked exceptions thrown when the underlying platform creates a new instance.
The throws clause of:
newInstance(Class c)
has been changed from(IllegalAccessException InstantiationException)
to (IllegalAccessException, InstantiationException, NoSuchMethodException)
to reflect the checked exceptions thrown when the underlying platform creates a new instance.
None
The executeInArea method and the family of newInstance methods may be used by Java threads. Previously this was ambiguous, but since a Java thread can switch between heap and immortal without the full semantics of a scope stack, this limited access to RTSJ memory areas can be supported without modifying Java threads. Moreover, a mechanism to switch Java threads to "immortal mode" has always been implied by the memory area semantics of static initializers.
There was no way to estimate the size of an array object so
public void reserveArray(int dimension)
for arrays of references and
public void reserveArray(int dimension, Class type)
for arrays of primitive types were added.
The getPortal()
method now throws the (unchecked) exceptions MemoryAccessError
and IllegalAssignmentError
. These exceptions were implicit in the existing reference and assignment rules, but the exact rules for generating them from this method were unclear. They are declared to make their possibility clear to the caller.
The ScopedCycleException
exception has been removed from the throws clause of the joinAndEnter
methods that do not take a time parameter. There is no case where these methods need to throw that exception.
The joinAndEnter
methods are altered to throw IllegalArgumentException
immediately when they have no non-null logic value. Previously, this behavior was ambiguous with the possibilities to either return immediately (as stated explicitly) or throw IllegalArgumentException
as required to behave like indivisible join
and enter
.
Added four new constructors to simplify a common use case, and for symmetry with the LTPhysicalMemory
class:
LTMemory(long size)
LTMemory(long size, Runnable logic)
LTMemory(SizeEstimator size)
LTMemory(SizeEstimator size, Runnable logic)
Added four new constructors to simplify a common use case, and for symmetry with the VTPhysicalMemory
class:
VTMemory(long size)
VTMemory(long size, Runnable logic)
VTMemory(SizeEstimator size)
VTMemory(SizeEstimator size, Runnable logic)
The type of the static final
fields ALIGNED, BYTESWAP, SHARED
, and DMA
is changed from String
to Object
. This is a compatible change that supports more flexibility of implementation.
A new static final
field, IO_PAGE
, is added.
The methods
public static void onInsertion(long base, long size, AsyncEvent ae)
public static void onRemoval(long base, long size, AsyncEvent ae)
public static boolean unregisterInsertionEvent(long base, long size, AsyncEvent ae)
public static boolean unregisterRemovalEvent(long base, long size, AsyncEvent ae)
have been added to replace deprecated insertion and removal methods.
All methods now throw OffsetOutOfBoundsException
when the base is negative, and SizeOutOfBoundsException
when the extent of memory passes the physical or virtual addressing boundary. This brings them in line with the methods in the classes commonly used by applications (such as ImmortalPhysicalMemory
.)
The methods
public void onInsertion(long base, long size, AsyncEvent ae)
public void onRemoval(long base, long size, AsyncEvent ae)
public boolean unregisterInsertionEvent(long base, long size, AsyncEvent ae)
public boolean unregisterRemovalEvent(long base, long size, AsyncEvent ae)
have been added to replace deprecated insertion and removal methods.
All methods now throw OffsetOutOfBoundsException
when the base is negative, and SizeOutOfBoundsException
when the extent of memory passes the physical or virtual addressing boundary. This brings them in line with the methods in the classes commonly used by applications (such as ImmortalPhysicalMemory
.)
The constructors for this class now specifically mention the possibility of OutOfMemoryError
.
The constructors for this class now specifically mention the possibility of OutOfMemoryError
.
None
None
None
Changed setAllocationRateIfFeasible()
to accept a long
argument for consistency with all the other allocation rate methods that take and return long
.
The class now implements Cloneable
and includes public Object clone()
None
The public constructor for the GarbageCollector
is deprecated.
The onInsertion(long base, long size, AsyncEventHandler aeh)
and onRemoval(long base, long size, AsyncEventHandler aeh)
methods in both PhysicalMemoryManager
and PhysicalMemoryTypeFilter
are deprecated in favor of new methods. The deprecated methods use async event handlers in a unnecessarily clumsy way (without an async event), and causing special argument values to unregister handlers is not good Java practice.
Significant changes have been made to the way priority ceiling protocol interacts with priority inheritance protocol.
Priority ceiling emulation was essentially unworkable as specified in the 1.0 spec. The 1.0.1 revision has semantics that can be implemented, but several changes to the APIs have been necessary.
Made the constructor protected since MonitorControl
is abstract, and each subclass should be a singleton.
Changed both setMonitorControl()
methods to return the old policy instead of returning void
.
Added static PriorityCeilingEmulation instance(int ceiling
) to return a priority ceiling emulation object for each ceiling value. This lets the implementation check for equal ceilings by checking for equality of the object references.
Added getCeiling()
replacing getDefaultCeiling
. The getCeiling
method has the same semantics as getDefaultCeiling
. The name, getDefaultCeiling
is misleading because there is no value that can correctly be called the default ceiling.
Added static PriorityCeilingEmulation getMaxCeiling()
which returns a singleton universally usable priority ceiling emulation object. This object is usable in cases where an application wishes to make priority ceiling emulation the default monitor control policy.
None
There is little purpose for the reader and writer parameters for the constructor. The class can support multiple readers and writers, so these are at best hints. The constructor with the reader and writer parameters was retained, but two new constructors without those parameters were added to reduce the confusion caused by those parameters.
Added the constructor WaitFreeWriteQueue(int maximum) throws IllegalArgumentException
Added the constructor WaitFreeWriteQueue(int maximum, MemoryArea memory) throws IllegalArgumentException.
Added InterruptedException
to the throws
clause of read()
.
There is little purpose for the reader and writer parameters for the constructor. The class can support multiple readers and writers, so these are at best hints. The constructor with the reader and writer parameters was retained, but two new constructors without those parameters were added to reduce the confusion caused by those parameters.
Added the constructor WaitFreeReadQueue(int maximum, boolean notify) throws IllegalArgumentException
Added the constructor WaitFreeReadQueue(int maximum, MemoryArea memory, boolean notify) throws IllegalArgumentException
Changed the return type of write(Object object) from boolean
to void
because the method could never return anything but true,
and added InterruptedException
to its throws
clause because it is a general principle that all blocking methods should be interruptible.
Added InterruptedException
to the throws
clause of waitForData()
because it is a blocking method that should be interruptible.
This class has been deprecated because it does not do anything that the separate WaitFreeReadQueue
and WaitFreeWriteQueue
do not do as well, and proper use of the proper read
and write
methods is unnecessarily confusing.
Changed the return type of blockingWrite(Object object) from boolean
to void
because the method could never return anything but true
.
The public constructors from the PriorityCeilingEmulation
and PriorityInheritance
classes have been removed. An implementation that exposes constructors for these methods as specified in version 1.0 would be needlessly complicated and it must leak immortal memory. The revised APIs require the implementation to produce (possibly lazily) singleton instances for each distinct value of the monitor control classes
Removed the public constructor because this class is supposed to be able to generate a unique instance per ceiling value.
Deprecated getDefaultCeiling()
because the method name is misleading. The new getCeiling
method should be used instead.
Removed the public constructor because this is supposed to be a singleton.
Revised RelativeTime relative(Clock clock, HighResolutionTime time)
to require a RelativeTime
argument. Previously any HighResolutionTime
argument was syntactically correct, but only RelativeTime
could be used without causing the method to throw a runtime exception.
There was no way to recover the clock property of a HighResolutionTime
object, so the getClock()
method was added. There are many ways to alter (re-associate) the clock, so no symmetrical setClock()
method was required.
The signature of set(HighResolutionTime time)
is not changed, but its meaning is altered. Version 1.0 had it defined to set the value of the parameter to a value corresponding to the current date. This is completely at odds with Java conventions, and while the Javadoc in the reference implementation agrees with the 1.0 specification, the code alters the time value of this
to match the parameter. The TCK was consistent with the RI code. The most likely conclusion is that the semantics for the method were a cut-and-paste error. The error is so surprising and potentially destructive that instead of deprecating the method (as would be normal for a case like this) the semantics were corrected to agree with the RI and TCK and set the millis and nanos values of this
to the values from the parameter.
HighResolution
time now implements Cloneable
. It also has a public clone
method and public hashCode
and equals
methods that work correctly with clone
.
Added four new constructors that include the clock association:
AbsoluteTime(Clock clock)
AbsoluteTime(long millis, int nanos, Clock clock)
AbsoluteTime(AbsoluteTime time, Clock clock)
AbsoluteTime(java.util.Date date, Clock clock)
Changed several methods that were specified as final
to non-final. Some arithmetic methods were final
and some were not with no discernible rationale for the difference. Changing them all to non-final was the most compatible way to resolve the inconsistency.
add(RelativeTime time),
subtract(AbsoluteTime time)
subtract(AbsoluteTime time, RelativeTime destination)
subtract(RelativeTime time)
were specified as final
and now have that attribute removed.
One version of the relative
method:
RelativeTime relative (Clock clock, AbsoluteTime dest)
could not be implemented as specified since it called for returning a RelativeTime
value in an AbsoluteTime
object. It was changed to:
RelativeTime relative (Clock clock, RelativeTime dest)
Added three new constructors that include the clock association:
RelativeTime(Clock clock)
RelativeTime(long millis, int nanos, Clock clock)
RelativeTime(RelativeTime time, Clock clock)
Changed two methods that were specified as final
to non-final. Some arithmetic methods were final
and some were not with no discernible rationale for the difference. Changing them all not non-final was the most compatible way to resolve the inconsistency.
add(RelativeTime time)
subtract(RelativeTime time)
were specified as final
and now have that attribute removed.
None. The class is deprecated.
none
.
getInterarrivalTime(),
getInterarrivalTime(RelativeTime destination)
, and
addInterarrivalTo(AbsoluteTime timeAndDestination)
are deprecated because their only purpose is to support the deprecated RationalTime
class.
The RationalTime
class was defined so it has two reasonable and incompatible descriptions. Neither of them can be implemented well. We have deprecated the class and hope to revisit the underlying concepts and abstract them better in a future revision.
Added RelativeTime getEpochOffset() throws UnsupportedOperationException
to let applications compare clocks with different epochs, and to let them discover clocks that have no concept of an epoch.
Changed the return type of getTime(AbsoluteTime time)
from void
to AbsoluteTime
to make the method consistent with the RTSJ conventions of returning a reference to the destination parameter when it is provided. This is also required to give it consistent behavior when a null parameter is passed.
The fire()
method inherited from AsyncEventHandler
is now overridden in this class since this is the most appropriate place to note that it throws UnsupportedOperationException
if the class is Timer.
The void start(boolean disabled) throws IllegalStateException
method has been added because without such a method there would be no way to start a timer in the disabled state that does not have a possible race condition.
Added new method:
public AbsoluteTime getFireTime(AbsoluteTime fireTime)
No changes except those inherited from Timer
.
No changes except those inherited from Timer
.
Two methods were defined as final
with no justification when compared to other methods in the same class that were not final:
getAndClearPendingFireCount
getPendingFireCount
Their final
attribute was removed to make them consistent with other similar methods.
Two new methods were added:
boolean isDaemon()
void setDaemon(boolean on)
To control the "daemon nature" of the AEH.
The two methods added to the Schedulable
interface are also added here.
None.
The BoundAsyncEventHandler
class is no longer an abstract
class. Since the class includes a constructor with a logic
parameter, it could operate without being subclassed. There was no reason it should be abstract, and leaving it abstract was inconvenient for application developers.
None
Added the boolean clear()
method to implement the safe semantics of happened()
, but not offer to secretly throw AIE.
None.
Deprecated happened() and propagate()
. These methods are defined to throw the AsynchronouslyInterruptedException
and they do not include that checked exception in their throws clauses. They may be actively dangerous to methods up their call chain that are not expecting an exception, but the danger is not bad enough to justify deleting these methods without warning.
An application can achieve the effect of propagate
by throwing an AIE after it catches it, and it can achieve the effect of happened
by combining the new clear()
method with fire.
Deprecated many signal names that are not found in the POSIX 9945-1-1996 standard:
Removed the default no-arg constructor leaving the class with no public constructor.
Added methods
public void checkSetMonitorControl(MonitorControl policy) throws SecurityException
and
public void checkSetDaemon() throws SecurityException
because the specification already says that these operations are checked by the security manager.
The no-arg constructor was an artifact of javadoc. Since this class's implementation is entirely static, the constructor is pointless and has been removed.
If applications execute the method call, System.getProperty("javax.realtime.version"),
the return value will be a string of the form, "x.y.z". Where 'x' is the major version number and 'y' and 'z' are minor version numbers. These version numbers state to which version of the RTSJ the underlying implementation claims conformance. The first release of the RTSJ, dated 11/2001, is numbered as, 1.0.0. Since this property is required in only subsequent releases of the RTSJ implementations of the RTSJ which intend to conform to 1.0.0 may return the String "1.0.0" or null.
Added getInitialMonitorControl()
to support the monitor control classes.
Added the class ArrivalTimeQueueOverflowException
to indicate overflow of an async event handlers arrival queue, and CeilingViolationException
to signify that a thread has attempted to lock a priority ceiling lock when its base priority exceeds the priority of the lock.
The following exceptions have been changed from checked to unchecked:
MemoryScopeException
InnaccessibleAreaException
MemoryTypeConflictException
MITViolationException
OffsetOutOfBoundsException
SizeOutOfBoundsException
UnsupportedPhysicalMemoryException
Each of these exceptions is characteristic of a programming error, not a fault that a programmer should anticipate and handle.