On Tue, 29 Sep 1998, Niels Hald Pedersen wrote:
>I would suspect usleep to encapsulate "the SIGALRM method of waiting"
>(set an alarm, sending process a signal after a given time, wait for the
>signal, handle it), at least it has a similar behaviour. I believe I've
usleep simply set the process timeout at the expected time in jiffies and
schedule(). It' s more simple and efficient (also in userspace ;-) than
set an alarm and then pause().
>It seems that any waiting time specified is rounded up to something
>being a multiple of 10 ms, and then a handling charge of further 10 ms
This is normal because the timeout set by the kernel before schedule(), is
set in jiffies and jiffies are increased evey 1/HZ sec, where HZ = 100 on
x86.
If you set the scheduler_policy real time (SCHED_FIFO or SCHED_RR) you' ll
be able to ask for delay < 1/HZ and the kernel will usleep() instead of
schedule(). This is not allowed to process with priority SCHED_OTHERS.
During usleep() the kernel will halt and only irq handlers will be allowed
to run (but don' t expect to see the mouse move because the irq will run
but X not ;-).
Here the interesting piece of code from the kernel tree:
asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
{
struct timespec t;
unsigned long expire;
if(copy_from_user(&t, rqtp, sizeof(struct timespec)))
return -EFAULT;
if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0)
return -EINVAL;
if (t.tv_sec == 0 && t.tv_nsec <= 2000000L &&
current->policy != SCHED_OTHER)
{
/*
* Short delay requests up to 2 ms will be handled with
* high precision by a busy wait for all real-time processes.
*
* Its important on SMP not to do this holding locks.
*/
udelay((t.tv_nsec + 999) / 1000);
return 0;
}
expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec) + jiffies;
current->timeout = expire;
current->state = TASK_INTERRUPTIBLE;
schedule();
if (expire > jiffies) {
if (rmtp) {
jiffies_to_timespec(expire - jiffies -
(expire > jiffies + 1), &t);
if (copy_to_user(rmtp, &t, sizeof(struct timespec)))
return -EFAULT;
}
return -EINTR;
}
return 0;
}
Andrea[s] Arcangeli