High Precision Sleep

Recently, for my research, I needed to make a network traffic generator which could ouput CBR traffic at a given rate with exponentially distributed on off times. Its actually pretty strange I didn’t find anything as simple as that on the internet in the first place. (So if any of you guys need it mail me.)

The problem I ran in building it had to do with high presicion sleeping with an accuracy in microseconds. Now, we do have nanosleep and usleep (which calls nanosleep()). However, they are no where as accurate as microseconds. Most OS kernels keep their internal timer resolution to 10ms to avoid a lot of timing overhead. I recompiled my linux kernel to improve the kernel timer resolution to 1ms. Even after that I saw that usleep actually had an error of around 2000us!

However, it seems that the gettimeofday() is pretty accurate as it uses the kernel timer along with help from hardware level clocks to get an accurate estimate of the time. The accuracy of gettimeofday is supposed to be as good as microseconds. However, I saw that the overhead of a gettimeofday() (its a system call) call itself was about 5us. That was good enough for me so I built a high precision sleep using usleep and gettimeofday. Basically, I divide the time required to sleep into parts for which I usleep on and busywait over gettimeofday() respectively. The code is given below.

#include<unistd.h>
#include<sys/time.h>

#define BUSY_WAIT       3000            //in microseconds

unsigned long long int get_clock()
{
        struct timeval tv;
        gettimeofday(&tv, NULL);
        return (unsigned long long int)tv.tv_usec + 1000000*tv.tv_sec;
}

int high_pres_usleep_untill(unsigned long long int end)
{
        //The basic idea is to divide the delay into sleep and busy wait parts.
        unsigned long long int busywait, start;
        int sleep, delay;

start = get_clock();
        delay = end - start;

sleep = (delay / BUSY_WAIT) - 1;
        if(sleep > 0)
                if(usleep(sleep*BUSY_WAIT))
                        return -1;

//Now busy wait such that from start till the end is the exact delay.
        while(get_clock() < end)
                ;

return 0;
}

If you require even greater sleep accuracy do take a look at the TSC register way of getting the current time. Its available on higher pentiums and it is a register which increments at the rate of the CPU clock. As CPU clocks are well over a GigaHertz you get nanosecond accuracy using that. The only hurdle that comes with it is calibrating it against a reference clock before you start doing anything with it (and some multiprocessor issues).

Advertisements
This entry was posted in Computing. Bookmark the permalink.

3 Responses to High Precision Sleep

  1. That is pretty awesome man… the blog, the work. It is nice to be able to take pride on the achievements of your friends 🙂

    Do mention Ragesh Jaiswal’s new paper on your blog ( FOCS 06 )

  2. Dave File says:

    I’ll be using your approach along with some VME based DAQ componets to do some photo mulitplier and scaler cals.
    Thanks

  3. To me it is necessary to find

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s