This is actualy very interesting. Riped the parts from periodic.c 
to play a with the code to see how it reacts to some changes.

The code below reproduces the problem:

sleep()+0x7 /sys/src/libc/9syscall/sleep.s:5
periodicThread(msec=0x3e8)+0xb2 /tmp/a.c:21
        ct=0x47a68e5b
        t=0x47e50e4d
        ts=0x0
main()+0x10 /tmp/a.c:32
_main+0x31 /sys/src/libc/386/main9.s:16


The zerosleeps go away if one uncomments the foo print. It also
goes away if one makes the sleep one milli second longer by
changing ts to ts+1.

I would love if anybody gives a good explaination of this bug
and how to fix it :-)

#include <u.h>
#include <libc.h>

static void
periodicThread(int msec)
{
        double t, ct, ts;

        ct = nsec()*1e-6;
        t = ct + msec;

        for(;;){
                /* skip missed */
                while(t <= ct)
                        t += msec;

                ts = t - ct;
                if(ts > 1000)
                        ts = 1000;
                sleep(ts);
                ct = nsec()*1e-6;
                if(t <= ct){
//                      print("foo!\n");
                        t += msec;
                }
        }
}

void
main(int argc, char *argv[])
{
        periodicThread(1000);
}
--- Begin Message ---
> Can anybody explain this fossil behaviour from the periodic code?

what if 0 < t - ct < 1?

wouldn't it be a good idea to replace the doubles with vlongs?
and replace *1e-6 with /1000000?  that would make 0 < t - ct < 1
impossible.

- erik

--- End Message ---

Reply via email to