- Linux timekeeping:
HZ
, jiffies
- sometimes we need to delay execution, for example
- short: device initialization, timeouts, ...
- longer: need to do something at certain time
bad: burning CPU cycles (don't use)
#define DELAY_MS 100
unsigned long j = jiffies + DELAY_MS * HZ / 1000;
while (time_before(jiffies, j1))
cpu_relax();
-
cpu_relax
means not doing much. Calls architecture dependent
code, actually only a memory barrier on powerpc.
slightly better but still wasteful:
while (time_before(jiffies, j1))
schedule();
- others can run, but system stays loaded (we stay in run queue of
the scheduler)
recommended for small (busy waiting) delays
void ndelay(unsigned long nsecs);
void udelay(unsigned long usecs);
void mdelay(unsigned long msecs);
better: sleep instead of busy waiting if possible:
void msleep(unsigned int ms);
/*
* interruptible version (for waitqueues)
* return 0 or if interrupted remaining time
*/
unsigned long msleep_interruptible(unsigned int ms);
void ssleep(unsigned int sec);
- Interesting:
msleep(1)
can sleep for up to 20ms
lkml thread.
Proposed solution: implement msleep with hrtimers.
longer delays: use waitqueues!:
wait_queue_head_t wait;
init_waitqueue_head(&wait);
/* condition is always false=0, delay in jiffies */
wait_event_interruptible_timeout(wait, 0, delay);