The Real-Time Specification for Java promises to bring the benefits of Java to real-time developers. David examines the requirements and design decisions that led to the Real-Time Specification for Java, and provides practical examples of its use.
February 01, 2000
URL:http://www.drdobbs.com/jvm/the-real-time-specification-for-java/184404005
David is chief technical officer for aJile Systems and can be contacted at david.hardin@ ajile.com.
Java technologies, including the Java programming language and the Java Virtual Machine (JVM), have achieved broad acceptance in the developer community since their introduction in 1995. Java's simplified object model, strong notions of safety and security, integral multithreading support, and promise of Write Once, Run Anywhere (WORA) have much to offer real-time and embedded developers. However, the large size, nondeterministic behavior and poor performance of most Java implementations have hampered the acceptance of Java in the real-time and embedded communities.
The recently announced Real-Time Specification for Java (RTSJ) promises to address these problem areas and bring the benefits of Java to real-time software developers. In this article, I'll examine the requirements and design decisions that led to the RTSJ, as well as provide practical examples of its use.
Recognizing Java's potential in the real-time space, a group of real-time and Java experts convened in a series of workshops sponsored by the National Institute of Standards and Technology (NIST) beginning in June 1998 to develop requirements for real-time Java. These requirements were intended to drive the development of a real-time Java specification, but would not mandate a particular set of APIs or semantic extensions to the Java language; this would be left to the specification phase.
The NIST workshops drew participation from well over 50 organizations. The workshops were informed by the early implementation experience of pioneers in this field, notably the PERC virtual machine by NewMonics (see "Issues in the Design and Implementation of Real-Time Java," http:// www.newmonics.com/pdf/RTJI.pdf/; "Java and Embedded Real-Time Control," Dr. Dobb's Java Sourcebook, 1996; and "picoPERC: A Small-Footprint Dialect of Java," DDJ March 1998, all by Kelvin Nilsen) and the JEM family of direct-execution Java microprocessors from Rockwell Collins (see "The Rockwell JEM Microprocessor Family: An Efficient Platform for Real-Time Embedded Java," by David Hardin, Proceedings of the 1998 IEEE Workshop on Programming Languages for Real-Time Industrial Applications, December 1998; http://www.ajile.com/ people/hardin/writings/jem-plrtia-1998.html). Additionally, academic real-time researchers and members of the Ada community provided guidance in the provision of real-time capabilities in a programming language context. Most usefully, end-user organizations provided guidance as to the most important requirements for real-time Java. The NIST workshops produced nine core requirements for a Real-Time Java specification, as well as a number of derived requirements. The requirements are documented in "Requirements for Real-Time Extensions for the Java Platform," edited by Lisa Carnahan and Marcus Ruark (NIST, September 1999; http://www.nist.gov/rt-java/).
Prior to the real-time specification, Java specifications were jointly developed by Sun Microsystems and its Java source-code licensees. Responding to pressures to provide broader participation in Java standards development, Sun instituted the Java Community Process in December 1998 (http:// java.sun.com/aboutJava/communityprocess/ java_community_process.html). Under the terms of the Java Community Process, anyone can institute a Java Specification Request (JSR). If a specification request in a particular field is accepted by Sun, then a Call for Experts (CAFE) in that field is issued. Sun then selects a specification lead from amongst the CAFE nominees; the specification lead is responsible for convening an expert group to author the specification, as well as developing a reference implementation and conformance tests.
The RTSJ effort was launched with the first Java Specification Request, JSR-000001. The Real Time for Java Expert Group (RTJEG) convened in March 1999. It consisted of representatives from 21 organizations in industry, academia, and government, working under the leadership of IBM's Greg Bollella. To reach a specification more quickly, the group was divided into a primary team of eight engineers (including James Gosling of Sun, the inventor of Java, as well as the author) and a consulting team. The primary team was tasked with developing the draft specification, which the consulting team would critique and refine.
The draft RTSJ was made available for participant review, as well as public view, on September 27, 1999 (public review followed the participant review period, beginning in December, 1999).
Given that there were many design alternatives for real-time Java that would meet the NIST requirements, the first task of the RTJEG was to produce a set of guiding principles for the design. These principles are enumerated in the current RTSJ draft (http://www.rtj.org/ rtj.pdf) as follows:
Unlike most Java specifications that merely define new APIs, the real-time specification provides modifications to the Java Language Specification and the JVM Specification, as well as new APIs to enable the creation, verification, analysis, execution, and management of real-time Java threads. The new APIs reside in a new standard extension package, javax.realtime.
A fundamental design decision facing the RTJEG was whether classes in javax.realtime should inherit from standard Java classes (for example, whether a real-time thread should be a subclass of java.lang.Thread or a new class that parallels java.lang.Thread in the class hierarchy). A completely parallel hierarchy would, in some sense, be simpler, but would render large parts of the Java environment essentially inaccessible to real-time developers. Another problem with the parallel class hierarchy approach is that Java includes a number of features, such as threads and the "synchronized" keyword, that would be useful to real-time developers if the underlying semantics were strengthened. The RTJEG decided on a more integrated approach and took on the detailed design of the RTSJ as a series of modifications of the standard Java environment. Real-Time Java applications would need a special JVM on which to execute, but could use many of the features of the standard Java programming model.
Figure 1 is the class hierarchy for javax.realtime. As you can see, classes in javax.realtime descend from standard Java classes java.lang.Object, java.lang.Thread, and java.lang.Throwable. javax.realtime provides two new interface classes, Interruptible and Schedulable.
The RTJEG identified seven areas of the standard Java environment for modification. These are summarized in the RTSJ as:
I'll now demonstrate the use of the RTSJ in a number of practical examples. Many of these examples provide explicit access to underlying hardware and would be rejected by the Security Manager if downloaded from an untrusted source. Also, these examples will not run correctly on a standard JVM.
Listing One illustrates the setup and use of an asynchronous event handler -- in this case, an event tied to a hardware interrupt. The handler can be conceptually viewed as a thread that waits on a notification of the occurrence of the hardware event.
Listing Two demonstrates the use of ImmortalMemory as an alternative to standard garbage-collected heap allocation of objects. Even though garbage collection is a preemptible operation on JVMs that support the RTSJ, this preemption time may be too long for many applications. Scoped and Immortal memory areas do not require garbage collection, and thus can be freely accessed in the context of a NoHeapRealtimeThread that runs at higher eligibility than the collector. Listing Two also illustrates the use of scheduling parameters to achieve periodic scheduling of real-time threads.
Listing Three shows the use of asynchronous transfer of control from an operation that can be timed out. The use of an AsynchronouslyInterruptedException allows cleanup to occur quite naturally from the programmer's perspective and is much safer than, say, setjmp()/longjmp().
Listing Four gives an example of the use of RawMemoryAccess to write device-level code in Java -- in this case, an interface to the Intel 8253 Programmable Interval Timer/Counter chip.
By the time you read this article, public review of the RTSJ should be concluding. The Reference Implementation will then follow, as well as a conformance test suite, as specified by the Java Community Process. Within a year, implementations of the RTSJ will no doubt be available from a number of vendors. Most implementations of the RTSJ will be hosted on traditional Real-Time Operating Systems (RTOS) and many will focus on embedded device targets. However, enterprise-level implementations, as well as implementations on platforms such as Real-Time Linux, are also likely. Finally, direct support for the RTSJ in silicon will be forthcoming from my company, aJile Systems, based on the JEM designs developed by the aJile team while at Rockwell Collins.
Given the network-oriented nature of much current Java development, a significant future specification effort lies ahead in the area of Distributed Real-Time. Expect to see an expert group to convene in this area soon.
A Java environment augmented with real-time capabilities provides an attractive object-oriented language environment for real-time developers, and a predictable, responsive platform for Java developers. The RTSJ documents a limited set of modifications to the Java Language Specification and JVM Specification, as well as a set of APIs, to provide a predictable platform for the execution of Java code. The development of the RTSJ also demonstrates that Sun Java licensees and nonlicensees can cooperate on an equal footing under the Java Community Process to develop a technically difficult specification on an aggressive schedule.
DDJ
import javax.realtime.*; /** Example of using Asynchronous Event/Event Handling facility to provide an interface to hardware events, i.e. interrupts. A hardware interrupt conceptually fires an AsyncEvent, which causes the associated handler to run. */ public class HardwareEventExample extends AsyncEvent { private int interruptNum; /** Construct a new Hardware Event for a given interrupt. * @param num Interrupt number */ public HardwareEventExample(int num) { interruptNum = num; } /** Bind a handler to the interrupt. * @param h Handler for the interrupt */ public void setHandler(AsyncEventHandler h) { super.setHandler(h); Hardware.bind(interruptNum, h); } } class HardwareEventHandler extends AsyncEventHandler { private int interruptCount = 0; /** Interrupt handler method. */ public void handleAsyncEvent() { interruptCount++; // Driver code follows } }
import javax.realtime.*; /** Example of the use of "Immortal" memory in a periodic processing context. This example eschews heap allocation, thus avoiding garbage collection overhead. */ public class ImmortalMemoryExample { public static void main(String[] Args) { NoHeapRealtimeThread t = null; // Set up periodic processing of 1 msec each 10 msec PeriodicParameters timeParams = new PeriodicParameters(); timeParams.cost = new RelativeTime(1, 0); // 1 msec computation timeParams.period = new RelativeTime(10, 0); // 10 msec period // Set up immortal memory; size is given in RealtimeSystem. MemoryParameters memParams = new MemoryParameters(ImmortalMemory.instance()); // Processing is encapsulated in a Runnable Runner r = new Runner(); // Create a NoHeapRealtimeThread with Periodic scheduling parameters // and ImmortalMemory memory parameters. try { t = new NoHeapRealtimeThread(timeParams, memParams, r); } catch (AdmissionControlException e) {} // Start processing t.start(); } } /** Perform periodic processing in Immortal memory */ class Runner implements Runnable { public void run() { // Processing code here } }
import javax.realtime.*; /** Example of the use of an AsynchronouslyInterruptedException (actually, the * Timed subclass of AIE) to timeout a long-running computation, and return * a "rough" answer instead. Use of AIE avoids overhead of a polling approach. */ public class AIEExample { /** Timeout class */ private class MyTimed extends Timed { public MyTimed(HiResTime timeout) { super(timeout); } } /** Long-running computation that may be timed out. * @param T Timeout */ int computeRefinedAnswer(MyTimed T) throws MyTimed { int refinedAnswer = 0; T.enable(); // hairy computation goes here T.disable(); return refinedAnswer; } /** Public interface to the potentially timed-out computation. If a * timeout occurs while computing the "refined" answer, a "rough" * answer is returned instead. */ public int computeAnswer() { int roughAnswer = 3; // Set up 100 usec timeout MyTimed T = new MyTimed((new RelativeTime(0, 100000))); try { return computeRefinedAnswer(T); } catch (MyTimed t) { // Computation timed out return roughAnswer; } } }
import javax.realtime.*; /** Example use of RawMemoryAccess (actually, a subclass of RawMemoryAccess * for accessing the Intel x86 I/O space) to directly address memory. This * (elided) example provides an interface to the Intel 8253 Programmable * Interval Timer, based on code originally developed by Gerald H. Hilderink. */ public class IOAccess extends RawMemoryAccess { /* ... */ } public class I8253Example { /* ... */ private long counter0Offset = 0; private long counter1Offset = 1; private long counter2Offset = 2; private long controlWordOffset = 3; private byte controlWord0 = 0x00; private byte controlWord1 = 0x00; private byte controlWord2 = 0x00; /** Create instance of the I8253 class. * @param baseAddr base address */ IOAccess iox; public I8253Example(long baseAddr) { iox = IOAccess.create(baseAddr, (long)8); } /* ... */ /** Write a 16-bit value to counter 2. * @param value value for counter 2 */ public void setCounter2(short value) { setControlWord(controlWord2); iox.setByte(counter2Offset, (byte)(value & 0xFF)); iox.setByte(counter2Offset, (byte)(value >> 8)); } /** Write a byte value to the control register. * @param value value for control register */ public void setControlWord(byte value) { iox.setByte(controlWordOffset, value); } /* ... */ /** Read a 16-bit value from counter 2. * @return value of counter 2 */ public short getCounter2() { short value; setControlWord(COUNTER2); value = (short)iox.getByte(counter2Offset); value |= ((short)iox.getByte(counter2Offset) << 8); return value; } }
(a) java.lang.Object javax.realtime.AsyncEvent javax.realtime.Timer javax.realtime.OneShotTimer javax.realtime.PeriodicTimer javax.realtime.AsyncEventHandler javax.realtime.BoundAsyncEventHandler javax.realtime.Clock javax.realtime.GarbageCollector javax.realtime.HiResTime javax.realtime.AbsoluteTime javax.realtime.RelativeTime javax.realtime.MemoryArea javax.realtime.ImmortalMemory javax.realtime.ImmortalPhysicalMemory javax.realtime.ScopedMemory javax.realtime.CTMemory javax.realtime.ScopedPhysicalMemory javax.realtime.VTMemory javax.realtime.MemoryParameters javax.realtime.MonitorControl javax.realtime.PriorityCeilingEmulation javax.realtime.PriorityInheritance javax.realtime.PhysicalMemoryFactory javax.realtime.PosixSignalHandler javax.realtime.RawMemoryAccess javax.realtime.RealtimeSystem javax.realtime.Scheduler javax.realtime.SchedulingParameters javax.realtime.DDMParameters javax.realtime.DDMSubtaskParameters javax.realtime.PeriodicParameters javax.realtime.PriorityParameters java.lang.Thread javax.realtime.RealtimeThread javax.realtime.NoHeapRealtimeThread java.lang.Throwable java.lang.Error javax.realtime.MemoryAccessError javax.realtime.ThrowBoundaryError java.lang.Exception java.lang.InterruptedException javax.realtime.AsynchronouslyInterruptedException javax.realtime.Timed javax.realtime.MemoryScopeException javax.realtime.OffsetOutOfBoundsException javax.realtime.ResourceLimitException javax.realtime.AdmissionControlException java.lang.RuntimeException javax.realtime.ThrowBoundaryException javax.realtime.SizeOutOfBoundsException javax.realtime.WaitFreeDequeue javax.realtime.WaitFreeReadQueue javax.realtime.WaitFreeWriteQueue (b) javax.realtime.Interruptible javax.realtime.Schedulable
Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.