So far, you have just modified an application; now it is time to write some code. You can write applications that use real-time threads to take advantage of the real-time priority levels and memory areas.
This sample shows you how to use immortal memory with the same sample that is described in Modifying Java applications.
In Table 1, the priorities are assigned on the basis that the SimulationThread has the highest priority because it represents external events and must not be allowed to be preempted by anything in the program. The RadarThread needs to respond quickly to the pings from the controller. The quicker the response, the more accurate the measurement of the height of the lunar lander. The ListenThread also has to respond quickly to commands from the controller but takes second place to the RadarThread.
These three threads are in scoped memory because the simulation runs as a server. After it has run a simulation, it can exit the scoped memory area and then reenter it to wait for another run of the simulation. It is using scoped memory so that it can reset itself.
RTJavaRadarthread has the highest priority of the controller threads because it is more sensitive to timing because it is using this time to derive the height. It is immortal because it is running as a NHRT and the controller is run only once and the memory is released when the JVM exits.
For RTJavaControlThread and RTJavaEventThread, the time constraints are not as critical and therefore using heap memory is acceptable.
Finally, RTLoadThread performs no useful function for the lunar lander. However, it demonstrates that significant memory allocation and deallocation can be performed at a lower priority than other threads and not affect the performance of the higher priority threads of the lunar lander.
Memory | Thread | Priority |
---|---|---|
Scoped | demo.sim.SimulationThread | 38 |
demo.sim.RadarThread | 37 | |
demo.sim.SimulationThread.ListenThread | 36 | |
Immortal | demo.controller.RTJavaRadarThread | 15 |
Heap | demo.controller.RTJavaControlThread | 14 |
demo.controller.RTJavaEventThread | 13 | |
Scoped and Heap | demo.controller.RTLoadThread | 12 |
super(null, area);
// Set priority separately, as we are using "this".
// Note that PriorityScheduler.MAX_PRIORITY has been deprecated.
this.setSchedulingParameters(new PriorityParameters(PriorityScheduler
.getMaxPriority(this))); 1
This code from demo.sim.SimLauncher shows where scoped memory has been defined. 2 shows the allocation of LTMemory, which is a scoped memory area that allocates memory in linear time.
final IndirectRef<MemoryArea> myMemRef = new IndirectRef<MemoryArea>();
/*
* The LTMemory object has to be created in a memory area that the
* NHRTs can access.
*/
ImmortalMemory.instance().enter(new Runnable() {
public void run() {
myMemRef.ref = new LTMemory(10000000); 2
}
});
final MemoryArea simMemArea = myMemRef.ref;
The ScopedMemoryArea object referenced by simMemArea is being allocated in immortal memory, because the NHRT must be able to reference the object that represents the ScopedMemoryArea. Allocating it on the heap results in the NHRT constructor throwing an IllegalArgumentException, because its memory area argument was on the heap.
simMemArea.enter(new Runnable() { public void run() { try { CommsControl commsControl = new CommsControl();
final RadarPort radarPort = commsControl.getRadarPort(); EventPort eventPort = commsControl.getEventPort(); final IndirectRef<RTJavaRadar> radarRef = new IndirectRef<RTJavaRadar>(); // Create RTJavaRadar in Immortal, it is an NHRT. // If it was in scoped, it's interaction with the other threads would // be more complex. ImmortalMemory.instance().enter(new Runnable() { public void run() { // Realtime version of Radar. radarRef.ref = new RTJavaRadar(radarPort, ImmortalMemory .instance()); } }); RTJavaRadar radarJava = radarRef.ref;