delay/sleep mechanisms in  Linux kernel 

delay/sleep mechanism in  Linux kernel 

一、How to insert delays in kernel 

在编写device driver时,经常需要加一段延时以等待hardware操作完成,在linux kernel中有udelay,也有sleep, 对不同时长的延时,该怎么选择呢?选择合适的延时函数,能够较好地平衡scheduler和power management的需求。

首先也是最重要的,明确当前是不是在atomic context中,我们知道,在atomic context下,是不允许休眠的。接下来,我们就分别从atomic和un-atomic context来介绍适用的延时函数。

1.1 atomic context

         在atomic context下,不能休眠,只能使用busy wait的*delay函数来实现一段延时操作。这些*delay函数包括:

         ndelay(unsigned long nsecs);

         udelay(unsigned long usecs);

         mdelay(unsigned long msecs);

这里面最推荐使用udelay,在一些non-PC platforms中,可能不支持ndelay;mdelay是基于udelay来实现的,通常需要重新调整code,来使用msleep来完成较长的延时。

这主要是考虑到power需求,毕竟ms级的busy-wait延时,对省电不是很友好。

1.2 un-atomic context

        在un-atomic context中,没有休眠的限制,可以使用*sleep[_range]系列的函数,通常是使用定时器设置一个定时时间,之后就可以让出CPU去处理其他任务,定时到期之后,会唤醒该task继续执行。

       *sleep[_range]函数按照所使用的定时器的不同,可以分成以下两类:

      1)基于hrtimer的延时

usleep_range (unsigned long min, unsigned long max)

设置hrtimer最早在min时刻,最晚在max时刻叫醒任务。

      2)基于jiffies/legacy_timer的延时函数

msleep (unsigned long msecs)

msleep_interruptible(unsigned long msecs)

这两者的区别是,msleep在做schedule之前,会设置task为TASK_UNINTERRUPTIBLE,不允许被其他signal打断;

而msleep_interruptible设置task为TASK_INTERRUPTIBLE,允许被其他signal打断,这就有可能在timeout之前唤醒。

注意到,这里的msleep有可能因为线程调度,延迟更长的时间。

这三类函数的适用场景

延时场景

函数

<10us

udelay

10us~20ms

usleep_range()

>10ms

msleep()

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值