On 2003/10/31 00:34, Shaul Karl wrote:
On Thu, Oct 30, 2003 at 10:49:38PM +0200, Ami Chayun wrote:

I have a question regarding short sleeps (under 10 millisec).
I require to implement sleep with about 1-10 microsec accuracy (that's no problem), but I require to sleep for times ranging between 1 microsec to 1 millisec.

usleep?

Its manpage states: This function is obsolete. Use nanosleep(2) or setitimer(2) instead.

But nanosleep(2) won't do the trick. If the machine is idle, nanosleep(2) will cause the kernel to issue a HLT instruction from which will wake up only upon the next interrupt; the only interrupt that's guaranteed to occur is the timer interrupt, up to 1/HZ = 10 millisec (in kernel 2.4) later -- much worse than the desired accuracy of 1-10. Similarly, if some other task takes over the CPU then it might be preempted only at the next timer interrupt.

nanosleep(2) *can* perform accurate busy-wait delays, but will do so only for for pauses up to 2ms and "if the process is scheduled under a real-time policy like SCHED_FIFO or SCHED_RR". I happened to look this up in the 2.4 kernel source and yup, that's exactly what it does.

So the solution is to do a busy-wait loop by yourself, in userspace. Modern x86 CPUs have an RDTSC instruction which reads a CPU cycle count -- this is the best way to make time measurements in the relevant scale. The code should look something like this (courtesy of the kernel source):

#define rdtscl(low) asm volatile("rdtsc" : "=a" (low) : : "edx")
#define rep_nop asm volatile("rep;nop")
static void rdtsc_delay(unsigned long loops)
{
        unsigned long bclock, now;
        rdtscl(bclock);
        do
        {
                rep_nop(); // reduce CPU power consumption
                rdtscl(now);
        } while ((now-bclock) < loops);
}

If you need loops>2^32, either wrap it by an outer loop or replace all longs by long longs and replace rdtscl by
#define rdtscll(val) asm volatile("rdtsc" : "=A" (val))


You can find the number of loops per second by doing some calibration at program startup (be careful if it's a laptop with variable CPU speed).

Eran


================================================================= To unsubscribe, send mail to [EMAIL PROTECTED] with the word "unsubscribe" in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]



Reply via email to