When a device driver needs to deal with latencies in its hardware, the
delays involved are usually a few dozen microseconds at most. In this
case, relying on the clock tick is definitely not the way to go.
The kernel functions ndelay, udelay, and mdelay serve well for
short delays, delaying execution for the specified number of
nanoseconds, microseconds, or milliseconds respectively. Their
prototypes are: The u in udelay represents the Greek letter mu and
stands for micro.
#include
void ndelay(unsigned long nsecs);
void udelay(unsigned long usecs);
void mdelay(unsigned long msecs);
The actual implementations of the functions are in
, being architecture-specific, and sometimes build
on an external function. Every architecture implements udelay, but the
other functions may or may not be defined; if they are not,
offers a default version based on udelay. In all cases, the delay achieved is at least the requested value but could be more;
actually, no platform currently achieves nanosecond precision, although
several ones offer submicrosecond precision. Delaying more than the
requested value is usually not a problem, as short delays in a driver
are usually needed to wait for the hardware, and the requirements are
to wait for at least a given time lapse.
The implementation of udelay (and possibly ndelay too) uses a
software loop based on the processor speed calculated at boot time,
using the integer variable loops_per_jiffy.
If you want to look at the actual code, however, be aware that the x86
implementation is quite a complex one because of the different timing
sources it uses, based on what CPU type is running the code.
To avoid integer overflows in loop calculations, udelay and ndelay
impose an upper bound in the value passed to them. If your module fails
to load and displays an unresolved symbol, __bad_udelay,
it means you called udelay with too large an argument. Note, however,
that the compile-time check can be performed only on constant values
and that not all platforms implement it. As a general rule, if you are
trying to delay for thousands of nanoseconds, you should be using
udelay rather than ndelay; similarly, millisecond-scale delays should
be done with mdelay and not one of the finer-grained functions.
It's important to remember that the three delay functions are busy-waiting; other tasks can't be run during the time lapse.
Thus, they replicate, though on a different scale, the behavior of
jitbusy. Thus, these functions should only be used when there is no
practical alternative.
There is another way of achieving millisecond (and longer) delays
that does not involve busy waiting. The file
declares these functions:
void msleep(unsigned int millisecs);
unsigned long msleep_interruptible(unsigned int millisecs);
void ssleep(unsigned int seconds)
The first two functions puts the calling process to sleep for the
given number of millisecs. A call to msleep is uninterruptible; you can
be sure that the process sleeps for at least the given number of
milliseconds. If your driver is sitting on a wait queue and you want a
wakeup to break the sleep, use msleep_interruptible. The return value
from msleep_interruptible is normally 0; if, however, the process is
awakened early, the return value is the number of milliseconds
remaining in the originally requested sleep period. A call to ssleep
puts the process into an uninterruptible sleep for the given number of
seconds.
In general, if you can tolerate longer delays than requested, you should use schedule_timeout, msleep, or ssleep.