The enormous success of Java technology is due to the relative ease ofwriting correct programs in Java as compared to other commonprogramming languages. A well defined syntax and semantics is asignificant factor in the development of automatic analysis tools.Garbage collection and strong typing vastly improve program safety.
The large standard class library also contributes to higherproductivity and safety. These are benefits that save both time andmoney during project development, testing, and maintenance. Evencritical applications could profit from these advantages.
The use of Java technology is becoming more and more popular even inareas well beyond the original scope of this programming language.Especially in critical applications in domains -as diverse asautomotive, anionic, industrial automation, telecommunication, andmedical, the advantages of Java are attractive. The enormous cost of afailure for such systems and the improvement in Java performance ismaking the performance advantages of C and C++ ever more irrelevant.
As embedded and safety critical systems become more complex, theadvantages of higher productivity in the development process comparedto traditional languages such as C and C-I-+ increase Java'sattractiveness. Platform independence and the increased flexibility ofJava through mechanisms such as dynamic class loading, also weighstrongly in Java's favor.
Combined with good object oriented design, the use of Java caneliminate the need for reimplementing the same functionality more thanonce. With Java Technology, the choice of machine architecture andoperating system can be decoupled from program code.
Nevertheless, there are a number of drawbacks that prevent the useof standard Java implementations in embedded, realtime, and safetycritical systems. High memory demand, poor runtime performance, andlack of realtime performance guarantees can nullify the advantages ofJava for these systems. To address these challenges, both realtimespecific Java standards and implementations are now available.
In particular, the Real-Time Specification for Java (RTSJ) ensuresthat a variety of implementations will continue to be available forprogramming embedded and realtime systems.
Inadequacies of Java for RealtimeProgramming
There are two main kinds of barriers to using Java for realtime andembedded programming: lack of determinism and limited access to theunderlying hardware. Both these issue arise in part from the goal ofensuring platform independence.
It was easier to provide platform independence by providing minimalrequirements for thread and priority behavior and to restrict access tothe hardware to ease the job of implementation than to devise arigorous definition that could be implemented on a broad range ofprocessors and operating systems. The use of garbage collection forensuring memory integrity tended to support the minimalist approach,since realtime garbage collection technology had not been availableuntil relatively recently.
Garbage Collection. One ofthe biggest advantages of Java technology, the safe memory managementthrough automatic garbage collection, has also been the biggest problemfor the use in realtime systems. The garbage collector is a basicsafety mechanism in Java and has consequently been considered to becompulsory.
Unfortunately, traditional garbage collection techniques requirenon-deterministic preemption of the processor to accomplish its task.Though there are now realtime garbage collection techniques, solvingthis problem was a major goal of the RTSJ.
The garbage collector (GC) is responsible for ensuring that allmemory that is no longer in use is returned to the free memory list. Inaddition, GC must ensure that the memory does not become fragmented. Ina classic Java system, the GC can stop all application threads at anunpredictable time and for an unpredictable duration to fill allocationrequests or to move objects to reduce memory fragmentation. This leadsto pauses as illustrated in Figure 1,below.
|Figure1: Pauses Due to Garbage Collection|
These pauses make the prediction of timing behavior of theapplication impossible. To permit realtime programming, one thereforeneeds a means of exempting realtime tasks from these pauses. Theobvious solution is to break up GC activity into short intervals thatmay be safely interrupted. This proves to be quite tricky in practicedue to the fine grain interdependency of object allocation and accessin application threads and the GC process. Any realtime specificationmust address this issue.
Threads, Priorities, andSynchronization. Threads need to not only interact with the GCprocess, but also with other application threads. Ensuring realtimebehavior requires a well defined thread, priority, and synchronizationmodel.
Standard Java defines only minimal requirements for threadinteraction. How priorities effect thread execution is ill defined.Preemption is not required. No mechanism for priority inversionavoidance is specified. In short, there are not guarantees aboutexecution order in standard Java. Again, any realtime system requiressuch guarantees.
Device Access. Finally, hardrealtime application are hard realtime because they interact with theirenvironment in some way. Certainly, device support can be providedthrough JNI, but this reduces portability and opens vulnerabilities inthe type system. A realtime systems specification needs support heretoo.
The Real-Time Specification for Java
The aim of the Realtime Specification for Java (RTSJ) is to extend theJava language definition and the Java standard libraries to supportrealtime programming.
Central to this task is the provision of threads whose execution isdeterministic, while preserving compatibility with other Javaenvironments and upward compatibility for existing, non realtime Javaapplications. The most important contributions of the RTSJ todeterministic execution are in the following seven areas:
• thread scheduling,
• memory management,
• asynchronous events,
• asynchronous flow of control,
• thread termination, and
• physical memory access.
In addition, the RTSJ also addresses areas that are not directlyrelated to realtime behavior, but are of great importance to manyembedded realtime applications. In particular, direct access tophysical memory and asynchronous mechanisms are included for supportingdevice access. In short, the RTSJ addresses all the issues mentionedabove which prevent the use of standard Java for realtime programming.
Memory Areas. The mostobvious barrier to realtime programming is the garbage collector.Pauses due to garbage collection are avoided by using the alternatefacilities for managing memory provided by the RTSJ, thus avoidinggarbage collection without allowing reference integrity to be violated.Threads that need to respond deterministically are only allowed toaccess memory not subject to garbage collection.
New memory classes, ImmortalMemory and ScopedMemory ,provide these memory areas. Objects in ImmortalMemory may only be allocated, but not freed. Objects in ScopedMemory areonly freed when the last thread exits the area. Since ScopedMemory areas may be nested, deallocation always occurs in reverse order ofentry.
Thus, both of these memory areas guarantee that dangling and falsereferences can not be created. The first by never deallocating objectsand the second by allowing objects in a given ScopedMemory area to be referenced only by objects in the same and more deeplynested areas.
One important consequence of the use of special memory areas is, ofcourse, that the advantages of dynamic memory management is not fullyavailable to realtime threads. Though reference integrity ismaintained, memory leaks are possible. In addition, the user must takemore direct control of deallocation.
|Figure2: ScopedMemory Example|
Threads and Scheduling. Though using the alternate memory areas is necessary for ensuringrealtime performance in an environment where the GC stops the executionof application threads unpredictably, their use is not sufficient toguarantee realtime behavior. The system must ensure both that criticaltasks can preempt the GC and other less critical threads. As mentionedabove, the priority of standard threads are not well defined.
|Figure3: Thread Interaction in RTSJ with a Standard Garbage Collector|
The RTSJ defines two new thread classes, RealtimeThread and NoHeapRealtimeThread to ensure proper preemption between both threads and threads withrespect to the GC. These thread types are unaffected or at least lessheavily affected by GC activity. Also, at least 28 new priority levels,logically higher than the priority of the garbage collector, areavailable for these threads. Figure3, above illustrates how the new realtime thread classes caninterrupt garbage collector activity.
Figure 4, below , shows anexample of how the realtime threads can be used in practice. In thisexample, a periodic thread is created which becomes active every 200msand writes a short message to the standard output stream. A realtimeThread implements this task. The priority and the length of the period of thisperiodic thread need to be provided. A call to waitForNextPeriod() causes the thread to wait after the completion of each activation forthe start of the next period.
In addition to periodic release parameters, the RTSJ also supportsaperiodic release parameters for managing intermittent tasks.
|Figure4: Periodic Thread|
Synchronization . In realtimesystems with threads of different priority levels, priority inversionmust be avoided. Priority inversion occurs when a thread of higherpriority is blocked waiting for a monitor that is owned by a thread oflower priority.
The RTSJ provides two alternative protocols to avoid priorityinversion: priority inheritance and priority ceiling emulation. Theformer is better for systems multi-threading performance and forsystems which start thread dynamically where as the second is usefulfor systems with a fixed number of threads, where the priorities can becalculated in advance.
Asynchronous Transfer of Control
Sometimes it is necessary to end a task before it is completed. TheRTSJ provides an asynchronous transfer of control API for this purpose.Any method that includes AsynchronouslyInterruptedException in itsthrow clause can be ended by calling interrupt () onthe corresponding thread object. Furthermore, any code defined in therun method of an Interruptibleobject and started via the doInterruptible of an AsynchronouslyInterruptedException object can be ended by calling the fire() methodof the exception object.
|Figure5: Interruptible Task|
Figure 5, above , gives anexample using the Timed subclass of AsynchronouslyInterruptedException .Here, some approximation method is run for a fixed time frame.
To read Part 2 in this seriesgo to “Events,Devices and Safety Crtical Java” where the authors identify thedrawbacks of conventional Java in real timesystems related to events and devices, deal with real time garbagecollection, and examine the safety critical portions of RTSJ and thetools for correctness verification .
Dr. James J. Hunt, is CEO, and Dr. Fridtjof B. Siebert is CTO atreal time Java developer avaicas GmbH in Karlsruhe, Germany.
This article is excerpted from a paper of the same name presentedat the Embedded Systems Conference Silicon Valley 2006. Used withpermission of the Embedded Systems Conference. For more information,please visit www.embedded.com/esc/sv .