Native waitUntil method

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: 99jonathan, roger, imaqine

Native waitUntil method

Postby unroller » Sat Dec 24, 2011 3:59 pm

Hi!

I use task-based approach in my Segway like robot. Each task is activated periodically. I use following code to organize periodic activation of tasks:
Code: Select all
    public void run() {
        long end = System.currentTimeMillis();
        while (!stop) {
            taskAction.run();

            end += period;
            long delay = end - System.currentTimeMillis();
            //may be interrupted here!
            Delay.msDelay(delay);
        }
    }


The problem with this code is that the execution may be interrupted by another thread after the delay is calculated but not applied yet. Due to this the period is not stable.
I'd prefer to use a native waitUntil method like this:

Code: Select all
    public void run() {
        long end = System.currentTimeMillis();
        while (!stop) {
            taskAction.run();

            end += period;
            Delay.waitUntil(end);
        }
    }


Is it possible to add this native method into Lejos code? It seems that its implementation is trivial, because the firmware function sleep_thread uses sleepUntil variable to wait for the specified period of time.
Code: Select all
static inline void sleep_thread_until (const FOURBYTES end_time)
{
  #ifdef VERIFY
  assert (currentThread != JNULL, THREADS3);
  assert (currentThread->state != MON_WAITING, THREADS9);
  #endif

  currentThread->state = SLEEPING;
  currentThread->sleepUntil = end_time;
}
unroller
Novice
 
Posts: 41
Joined: Sat Sep 25, 2010 6:10 am

Re: Native waitUntil method

Postby gloomyandy » Sat Dec 24, 2011 10:44 pm

Unfortunately that won't work either. Consider what will happen if your thread is interrupted just after the call to waitUntil returns. If you want to make the timing more stable try adding a call to msDelay for 1ms just before you calculate the time to sleep. This will minimize the chance of your thread being interrupted by a thread of equal priority. You may also want to consider running your thread at a higher priority, the leJOS scheduler is purely priority based.
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4172
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Native waitUntil method

Postby unroller » Mon Dec 26, 2011 6:41 pm

I've implemented this native method and made a test to check delay stability. I found that this approach does not improve stability of the tasks with normal priority, but improves stability of high-priority tasks. In my test program I run 5 tasks with periods from 4 to 8 ms during 20 seconds. If the 4ms task runs with normal priority, it has about 1600 errors (when actual period is not equal to 4 ms) for both approaches (msDelay and waitUntil). But when I run this task with high priority, the period is more stable with waitUntil approach (~8 errors) than msDelay approach (~80 errors).
I used this approach in my SegWay-like robot I got following error rages: msDelay - 1.56 errors/sec, waitUntil - 0.86 errors/sec.

It seems this approach can improve stability of high-priority tasks, but this effect is not very big.
unroller
Novice
 
Posts: 41
Joined: Sat Sep 25, 2010 6:10 am

Re: Native waitUntil method

Postby gloomyandy » Mon Dec 26, 2011 11:09 pm

Did you try my suggestion above of adding the 1ms delay before the calculation? How did the results from that compare?

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4172
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Native waitUntil method

Postby skoehler » Tue Dec 27, 2011 12:45 am

gloomyandy wrote:Did you try my suggestion above of adding the 1ms delay before the calculation? How did the results from that compare?


Your suggestion was
Code: Select all
wait for 1 ms
x := delay until target time
wait for x ms

right?

The reasoning behing that is, that after the 1ms sleep (probably a Thread.yield() would do as well!), the thread has been assigned a new timeslice, which means that the last two steps of the code above run without any context switch.

I wonder, how the firmware implements Object.wait() or Threed.sleep(). Does it first compute the time, at which the thread is supposed to wake up? Or is some other mechanism being implemented? If the former is the case, then there already is a waitUntil() implementation hidden in the firmware. It would probably help, if we'd expose this functionality, and implement the other methods (which implement a relative wait) as a wrapper around that. The reason I'm kind of eager to have a waitUntil (not very much eager, but somewhat), is that I have to implement the periodic sampling of sensor (analog and I2C) and that I'd love to avoid the "2 context switch" workaround.
skoehler
leJOS Team Member
 
Posts: 1448
Joined: Thu Oct 30, 2008 4:54 pm

Re: Native waitUntil method

Postby unroller » Tue Dec 27, 2011 5:04 am

The approach with sleep(1) really improves stability of high priority tasks. My test program shows 6-20 errors in this case. Approach with using yield does not produce significant improvement (72-86 errors). For waitUntil approach the test program shows 6-8 errors.
But sleep(1) approach makes worse stability of normal priority tasks (~1800 errors vs ~1700 for msDelay and ~1600 for waitUntil)
unroller
Novice
 
Posts: 41
Joined: Sat Sep 25, 2010 6:10 am

Re: Native waitUntil method

Postby gloomyandy » Tue Dec 27, 2011 9:31 am

Hi,
Yes that is how the firmware implements the sleep etc. So we could switch the implementation. However this would make calls to sleep etc slightly slower as the computation would now be in Java...

However in this case the bigger problem is probably the short wait time and the definition of an error. 4ms is only two time slices. So if you have multiple threads running at the same priority there is a good chance you will not be the next thread to run even if the thread becomes runnable. So assuming that an error is counted if the overall loop time is not 4ms then with multiple threads an error is very likely. By raising the priority you are reducing the number of threads competing for the same time slice. The fact that the sleep 1 trick makes things better in one case and worse in the other is evidence for this.

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4172
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Native waitUntil method

Postby unroller » Tue Dec 27, 2011 10:02 am

skoehler wrote:I wonder, how the firmware implements Object.wait() or Threed.sleep(). Does it first compute the time, at which the thread is supposed to wake up?


Yes, the method Thread.sleep calls the function sleep_thread in the firmware that calculates wake up time and switches the thread into sleeping state:
Code: Select all
static inline void sleep_thread (const FOURBYTES time)
{
  #ifdef VERIFY
  assert (currentThread != JNULL, THREADS3);
  assert (currentThread->state != MON_WAITING, THREADS9);
  #endif

  currentThread->state = SLEEPING;
  currentThread->sleepUntil = get_sys_time() + time;    
}
unroller
Novice
 
Posts: 41
Joined: Sat Sep 25, 2010 6:10 am

Re: Native waitUntil method

Postby unroller » Tue Dec 27, 2011 3:15 pm

gloomyandy wrote:So we could switch the implementation. However this would make calls to sleep etc slightly slower as the computation would now be in Java...


Could you please clarify this? Do you mean another sleep implementation?

gloomyandy wrote:4ms is only two time slices.


Does leJOS use 1ms time slice or 2ms?
unroller
Novice
 
Posts: 41
Joined: Sat Sep 25, 2010 6:10 am

Re: Native waitUntil method

Postby gloomyandy » Tue Dec 27, 2011 3:42 pm

If as Sven suggested we switched the native call to be a waitUntil then part of the implementation of sleep would have to be in Java, this will be marginally slower as it would need to make calls to get the current time and perform the addition. This code is currently in C...

The thread scheduler code is called every 2ms, unless the current thread gives up the cpu by calling yield/sleep/wait etc.

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4172
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Native waitUntil method

Postby unroller » Tue Dec 27, 2011 4:15 pm

My first suggestion was to add waitUntil function, keeping existing Thread.sleep implementation. After tests I think that function may be helpful but is not necessary.
unroller
Novice
 
Posts: 41
Joined: Sat Sep 25, 2010 6:10 am


Return to NXJ Software

Who is online

Users browsing this forum: jusch and 3 guests

more stuff