赞
踩
目录
内核中的睡眠、延时函数
使用delay系列函数
- ndelay(unsigned long nsecs)//首选使用
- udelay(unsigned long usecs)
- mdelay(unsigned long msecs)
这些函数使用对时钟速度的jiffie估计,并将忙于等待足够的循环周期以实现所需的延迟。
mdelay是udelay的宏包装器,以免udelay传递大参数时可能发生溢出.
使用sleep系列的函数
- usleep_range(umin,umax); //推荐使用
- msleep(ms);
- msleep_interruptible(ms);
- ssleep(s);
-- Backed by busy-wait loop:
udelay(unsigned long usecs)
-- Backed by hrtimers:
usleep_range(unsigned long min, unsigned long max)
-- Backed by jiffies / legacy_timers
msleep(unsigned long msecs)
msleep_interruptible(unsigned long msecs)
1)睡眠时间 ( < ~10us? ):
使用 udelay
为什么不使用 usleep?因为在较慢的系统上(如嵌入式)为usleep设置hrtimer的开销可能不值得。
2)睡眠时间 (10us - 20ms):
使用usleep_range
为什么不使用msleep 定时 (1ms - 20ms),
睡眠时间经常比设定的长 http://lkml.org/lkml/2007/8/3/250
为什么没有 "usleep",什么是好的范围?
usleep建立在hrtimers计时器之上,唤醒将非常精确。因此,一个简单的usleep函数可能会引入大量不需要的中断。 随着范围的引入,调度器可以自由地将您的唤醒与可能由于其他原因发生的任何其他唤醒合并,或者在最坏的情况下,为您的上限触发一个中断。
3)睡眠时间>10ms
使用 msleep or msleep_interruptible
msleep 设置当前的进程状态为TASK_UNINTERRUPTIBLE
msleep_interruptible 设置当前的进程状态为TASK_INTERRUPTIBLE
4)睡眠时间>1s
使用ssleep
u64 ktime_get_real_ns(void);
实例计算foo() bar()函数的延时
- #include <linux/ktime.h>
- t1 = ktime_get_real_ns();
- foo();
- bar();
- t2 = ktime_get_real_ns();
- time_taken_ns = (t2 -> t1);
计算时间的函数
- #define DILLY_DALLY(code_str, run_this) do { \
- u64 t1, t2; \
- t1 = ktime_get_real_ns(); \
- run_this; \
- t2 = ktime_get_real_ns(); \
- pr_info(code_str "-> actual: %11llu ns = %7llu us = %4llu ms\n", \
- (t2-t1), (t2-t1)/1000, (t2-t1)/1000000);\
- } while(0)
- static int __init delays_and_sleeps_init(void)
- {
-
- //delay
- DILLY_DALLY("ndelay() for 10 ns", ndelay(10));
- DILLY_DALLY("udelay() for 10,000 ns", udelay(10));
- DILLY_DALLY("mdelay() for 10,000,000 ns", mdelay(10));
-
-
- //sleep
- DILLY_DALLY("usleep_range(10,20) for 10,000 ns", usleep_range(10, 20));
- DILLY_DALLY("msleep(10) for 10,000,000 ns", msleep(10));
- DILLY_DALLY("msleep_interruptible(10) ", msleep_interruptible(10));
- DILLY_DALLY("ssleep(1) ", ssleep(1));
-
- }
- 1. *delay() functions (atomic, in a delay loop):
- [ 4176.946228] ndelay() for 10 ns-> actual: 219 ns = 0 us = 0 ms
- [ 4176.946239] udelay() for 10,000 ns-> actual: 9956 ns = 9 us = 0 ms
- [ 4176.956217] mdelay() for 10,000,000 ns-> actual: 9976582 ns = 9976 us = 9 ms
- [ 4176.956219]
- 2. *sleep() functions (process ctx, sleeps/schedule()'s out):
- [ 6372.868032] usleep_range(10,20) for 10,000 ns-> actual: 57183 ns = 57 us = 0 ms
- [ 6372.886923] msleep(10) for 10,000,000 ns-> actual: 18880096 ns = 18880 us = 18 ms
- [ 6372.906874] msleep_interruptible(10) -> actual: 19943338 ns = 19943 us = 19 ms
- [ 6373.915691] ssleep(1) -> actual: 1008605369 ns = 1008605 us = 1008 ms
1、udelay() 与mdelay() 函数实际用的时间比参数要少?这是为什么呢?
- * Please note that ndelay(), udelay() and mdelay() may return early for
- * several reasons:
- * 1. computed loops_per_jiffy too low (due to the time taken to
- * execute the timer interrupt.)
- * 2. cache behaviour affecting the time it takes to execute the
- * loop function.
- * 3. CPU clock rate changes.
- *
2、sleep()系列的函数用了更多的时间,在标准的linux上
原因有下
参考内核
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。