This discussion is archived
2 Replies Latest reply: Mar 7, 2011 12:19 PM by 841270 RSS

NoHeapRealTimeFibonacciLoops

841270 Newbie
Currently Being Moderated
Just as an exercise, I would like to modify the Deterministic scenario in the Getting Started guide to make the bench thread run in a NoHeapRealtimeThread instead of a standard RealtimeThread.
http://download.oracle.com/javase/realtime/doc_2.2/release/JavaRTSGettingStarted.html

I realize this is a silly exercise, as memory is never consumed in this program and therefore there is no Garbage Collection. Overall I want to do the same for the GCDeterministic scenarios and compare performance, system overhead, resource usage, etc. between a RTT and a NHRTT.

The simplest approach would seem to be create a new NoHeapRealTimeFibonacciLoops by modifying RealTimeFibonacciLoops to extend NoHeapRealtimeThread and use ImmortalMemory.Instance() as the MemoryArea parameter. This predictably gives an "Exception in thread "main" java.lang.IllegalArgumentException: Illegal Memory Area Passed or argument allocated in heap" error.

Unfortunately after several attempts (including a few different approaches), I have not been able to make the Deterministic scenario use a NoHeapRealtimeThread for the bench thread. Any suggestions or examples would be greatly appreciated.
  • 1. Re: NoHeapRealTimeFibonacciLoops
    841270 Newbie
    Currently Being Moderated
    I've also tried calling the NHRT from within a regular RTT. With the following class, I get a java.lang.StackOverflowError at ImmortalMemory.Instance().enter(this). Any clues as to what I'm doing wrong would be greatly appreciated.

    ------

    class NoHeapRealTimeFibonacciLoops extends RealtimeThread {

    boolean records_time_measures = false;
    int nb_outer_iterations = 0;
    int nb_inner_iterations = 0;
    int nb_stress_class_iterations = 0;
    int pause_time = 0;

    NoHeapRealTimeFibonacciLoops(boolean is_bench_thread,
    int time_to_pause,
    int outer_iterations,
    int inner_iterations,
    int stress_class_iterations,
    SchedulingParameters schedulingParams,
    ReleaseParameters releaseParams) {
    super(schedulingParams, releaseParams);
    records_time_measures = is_bench_thread;
    nb_outer_iterations = outer_iterations;
    nb_inner_iterations = inner_iterations;
    nb_stress_class_iterations = stress_class_iterations;
    pause_time = time_to_pause;
    }

    public void run() {

    // Set immortal memory as allocation context
    ImmortalMemory.instance().enter(this);
    System.out.println("In IM context");

    // Create NHRT (within immortal memory)
    NoHeapRealtimeThread nhrt =
    new NoHeapRealtimeThread(
    this.getSchedulingParameters(), this.getReleaseParameters(), ImmortalMemory.Instance()) {

    public void run() {
    // Execute NHRT code here...
    final Clock rtClock = Clock.getRealtimeClock();
    final RelativeTime time_to_sleep = new RelativeTime(pause_time, 0);

    // the AbsoluteTime from which to measure
    AbsoluteTime rtWallClockTimeBefore = rtClock.getTime();
    AbsoluteTime rtWallClockTimeAfter = rtClock.getTime();

    int no_loop = 0;
    try {
    while (no_loop < nb_outer_iterations) {
    if (records_time_measures) {
    // bench thread -> recording time before computation and allocation
    rtClock.getTime(rtWallClockTimeBefore);
    wallclock_times_begin_loops[no_loop] =
    (rtWallClockTimeBefore.getMilliseconds() * 1000000L)
    + rtWallClockTimeBefore.getNanoseconds();
    }

    // Fibonacci computation sample
    NHRTDeterministic.this.computeFibs(nb_inner_iterations, nb_stress_class_iterations);

    if (records_time_measures) {
    // this should be bench thread -> recording time after computation and allocation
    rtClock.getTime(rtWallClockTimeAfter);
    wallclock_times_end_loops[no_loop] =
    (rtWallClockTimeAfter.getMilliseconds() * 1000000L)
    + rtWallClockTimeAfter.getNanoseconds();

    while (RealtimeThread.currentRealtimeThread().waitForNextPeriod() == false) {
    missed_deadlines[no_loop]++;
    }
    } else {
    // stress thread -> parameterized pause if asked for
    if (pause_time != 0) {
    sleep(time_to_sleep);
    }
    }

    no_loop++;
    }
    } catch (InterruptedException ie) {
    System.out.println("javax.RealtimeThread interrupted");
    }
    }
    };
    nhrt.start();
    }
    }
  • 2. Re: NoHeapRealTimeFibonacciLoops
    841270 Newbie
    Currently Being Moderated
    Here is one successful approach I've taken. As with all No-Heap Realtime Threads, the challenge was in making sure the NHRT did not access any object in the heap and that it itself was not allocated in the heap. With the following setup, the bench thread runs in a NHRT while the stress threads continue to run either in a regular =java.lang.Thread= or =javax.realtime.RealtimeThread=. Of course, any insight into more enlightened ways of approaching this would be greatly appreciated.

    In essence, I create a regular FibonacciLoops class that just implements Runnable:
    ------
    class FibonacciLoops implements Runnable {

    boolean records_time_measures = false;
    int nb_outer_iterations = 0;
    int nb_inner_iterations = 0;
    int nb_stress_class_iterations = 0;
    int pause_time = 0;

    FibonacciLoops(boolean is_bench_thread,
    int time_to_pause,
    int outer_iterations,
    int inner_iterations,
    int stress_class_iterations) {
    records_time_measures = is_bench_thread;
    nb_outer_iterations = outer_iterations;
    nb_inner_iterations = inner_iterations;
    nb_stress_class_iterations = stress_class_iterations;
    pause_time = time_to_pause;
    }

    // Fibonacci computation stress method
    // computes 2 fibonacci sequences "nb_inner_iterations" times
    // - nb_stress_class_iterations : quantity of fib numbers to compute
    // Either computeFibs here, or make outer NHRTDeterministic.computeFibs static
    void computeFibs(int nb_inner_iterations, int nb_stress_class_iterations) {
    Fibonacci1 f1 = new Fibonacci1(nb_stress_class_iterations);
    Fibonacci2 f2 = new Fibonacci2(nb_stress_class_iterations);

    for (int i = 1; i <= nb_inner_iterations; i++) {
    f1.computeFib();
    f2.computeFib();
    }
    }

    public void run() {

    final Clock rtClock = Clock.getRealtimeClock();
    final RelativeTime time_to_sleep = new RelativeTime(pause_time, 0);

    // the AbsoluteTime from which to measure
    AbsoluteTime rtWallClockTimeBefore = rtClock.getTime();
    AbsoluteTime rtWallClockTimeAfter = rtClock.getTime();

    int no_loop = 0;

    try {
    while (no_loop < nb_outer_iterations) {
    if (records_time_measures) {
    // bench thread -> recording time before computation and allocation
    rtClock.getTime(rtWallClockTimeBefore);
    wallclock_times_begin_loops[no_loop] =
    (rtWallClockTimeBefore.getMilliseconds() * 1000000L) +
    rtWallClockTimeBefore.getNanoseconds();
    }

    // Fibonacci computation sample
    computeFibs(nb_inner_iterations, nb_stress_class_iterations);

    if (records_time_measures) {
    // this should be bench thread -> recording time after computation and allocation
    rtClock.getTime(rtWallClockTimeAfter);
    wallclock_times_end_loops[no_loop] =
    (rtWallClockTimeAfter.getMilliseconds() * 1000000L) +
    rtWallClockTimeAfter.getNanoseconds();

    while(RealtimeThread.currentRealtimeThread().waitForNextPeriod() == false ) {
    missed_deadlines[no_loop]++;
    }
    }
    else {
    // stress thread -> parameterized pause if asked for
    if (pause_time != 0) RealtimeThread.currentRealtimeThread().sleep(time_to_sleep);
    }

    no_loop++;
    }
    }
    catch (InterruptedException ie) {
    System.out.println("FibonacciLoops interrupted");
    }
    }
    }
    ------

    I then use a RealtimeThread (allocated in ImmortalMemory) in main() to run FibonacciLoops as follows:
    ------
    rt_bench_thread = new RealtimeThread() {
    public void run() {
    ImmortalMemory.instance().enter(
    new Runnable() {
    public void run() {
    FibonacciLoops fib_loops = d.new FibonacciLoops(true,
    bench_pause_time,
    bench_nb_outer_iterations,
    bench_nb_inner_iterations,
    bench_nb_stress_class_iterations);
    NoHeapRealtimeThread nhrt = new NoHeapRealtimeThread(
    new PriorityParameters(rt_bench_thread_priority),
    new PeriodicParameters(null,
    benchPeriod, null, null,
    null, null), null, ImmortalMemory.instance(), null, fib_loops);
    nhrt.start();
    }
    });
    }
    };

    ------

    For this to work, a few class variables need to be made static and some of the local variables in main() need to be made final. For example, wallclock_times_begin_loops needs to be static and defined in the constructor as:
    wallclock_times_begin_loops = (long[]) ImmortalMemory.instance().newArray(long.class, nb_loops)

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points