timer - 为什么linux内核中的udelay和ndelay不准确?

标签 timer linux-kernel linux-device-driver delay

我做了一个这样的函数

trace_printk("111111");
udelay(4000);
trace_printk("222222");

日志显示它是 4.01 毫秒,没问题

但是当我这样打电话时

trace_printk("111111");
ndelay(10000);
ndelay(10000);
ndelay(10000);
ndelay(10000);
....
....//totally 400 ndelay calls
trace_printk("222222");

日志将显示 4.7 毫秒。这是 Not Acceptable 。 为什么ndelay的误差这么大?

深入内核代码我发现了这两个函数的实现

void __udelay(unsigned long usecs)
{
    __const_udelay(usecs * 0x10C7UL); /* 2**32 / 1000000 (rounded up) */
}

void __ndelay(unsigned long nsecs)
{
    __const_udelay(nsecs * 0x5UL); /* 2**32 / 1000000000 (rounded up) */
}

我以为udelay会是ndelay的1000倍,但事实并非如此,为什么?

最佳答案

正如您已经注意到的,纳秒延迟实现与毫秒延迟相比是相当粗略的近似,因为使用了 0x5 常数因子。 0x10c7/0x5 大约为 859。使用 0x4 将更接近 1000(大约 1073)。

但是,使用 0x4 会导致ndelay小于请求的纳秒数。一般来说,延迟函数的目标是提供至少只要用户请求的延迟(参见此处:http://practicepeople.blogspot.jp/2013/08/kernel-programming-busy-waiting-delay.html)。

关于timer - 为什么linux内核中的udelay和ndelay不准确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30396869/

相关文章:

android - Android API 15 及更高版本上的准确计时器

python - Python定时器可以通过检查它是否存在来取消吗?

javascript - angularjs计算开始时间和当前时间的时间差

javascript - Rails 4 - 计时器 (jQuery.Countdown)

linux-kernel - 同步访问 net_device 结构的最佳原因是什么?

linux - 为什么我收到 "killall -q -USR1 udhcpd"错误消息?

linux - Linux内核中的sscanf函数是否容易受到缓冲区溢出攻击?

c - Linux内核中的链表卡住机器

linux - 在汇编程序中从/dev/input/event* 读取键盘事件

linux - linux内核模块生成的核心文件