内核定延迟执行-sleep-dealy
创始人
2025-05-30 01:05:58
0
  • mdelay
    mdelay采用的忙等待的方法一直占用cpu资源,延时准确,直到时间到达,长延时不建议采用该方法。可以用于进程上下文和中断上下文。
/** Using udelay() for intervals greater than a few milliseconds can* risk overflow for high loops_per_jiffy (high bogomips) machines. The* mdelay() provides a wrapper to prevent this.  For delays greater* than MAX_UDELAY_MS milliseconds, the wrapper is used.  Architecture* specific values can be defined in asm-???/delay.h as an override.* The 2nd mdelay() definition ensures GCC will optimize away the * while loop for the common cases where n <= MAX_UDELAY_MS  --  Paul G.*/#ifndef MAX_UDELAY_MS
#define MAX_UDELAY_MS	5
#endif#ifndef mdelay
#define mdelay(n) (\(__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \({unsigned long __ms=(n); while (__ms--) udelay(1000);}))
#endif#ifndef ndelay
static inline void ndelay(unsigned long x)
{udelay(DIV_ROUND_UP(x, 1000));
}
#define ndelay(x) ndelay(x)
#endif
  • msleep
    msleep只能用于进程上下文,延时不准确,延时期间不占用cpu资源,从内核实现来看其实就是调用了一个内核标准定时器。
/*** msleep - sleep safely even with waitqueue interruptions* @msecs: Time in milliseconds to sleep for*/
void msleep(unsigned int msecs)
{unsigned long timeout = msecs_to_jiffies(msecs) + 1;while (timeout)timeout = schedule_timeout_uninterruptible(timeout);
}EXPORT_SYMBOL(msleep);signed long __sched schedule_timeout_uninterruptible(signed long timeout)
{__set_current_state(TASK_UNINTERRUPTIBLE);return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_uninterruptible);// 定时时间到达之后调用的回调函数,其实就是将睡眠进程唤醒
static void process_timeout(struct timer_list *t)
{struct process_timer *timeout = from_timer(timeout, t, timer);wake_up_process(timeout->task);
}/*** schedule_timeout - sleep until timeout* @timeout: timeout value in jiffies** Make the current task sleep until @timeout jiffies have* elapsed. The routine will return immediately unless* the current task state has been set (see set_current_state()).** You can set the task state as follows -** %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to* pass before the routine returns unless the current task is explicitly* woken up, (e.g. by wake_up_process())".** %TASK_INTERRUPTIBLE - the routine may return early if a signal is* delivered to the current task or the current task is explicitly woken* up.** The current task state is guaranteed to be TASK_RUNNING when this* routine returns.** Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule* the CPU away without a bound on the timeout. In this case the return* value will be %MAX_SCHEDULE_TIMEOUT.** Returns 0 when the timer has expired otherwise the remaining time in* jiffies will be returned.  In all cases the return value is guaranteed* to be non-negative.*/
signed long __sched schedule_timeout(signed long timeout)
{struct process_timer timer;unsigned long expire;switch (timeout){case MAX_SCHEDULE_TIMEOUT:/** These two special cases are useful to be comfortable* in the caller. Nothing more. We could take* MAX_SCHEDULE_TIMEOUT from one of the negative value* but I' d like to return a valid offset (>=0) to allow* the caller to do everything it want with the retval.*/schedule();goto out;default:/** Another bit of PARANOID. Note that the retval will be* 0 since no piece of kernel is supposed to do a check* for a negative retval of schedule_timeout() (since it* should never happens anyway). You just have the printk()* that will tell you if something is gone wrong and where.*/if (timeout < 0) {printk(KERN_ERR "schedule_timeout: wrong timeout ""value %lx\n", timeout);dump_stack();current->state = TASK_RUNNING;goto out;}}expire = timeout + jiffies;timer.task = current;timer_setup_on_stack(&timer.timer, process_timeout, 0);__mod_timer(&timer.timer, expire, 0);schedule();del_singleshot_timer_sync(&timer.timer);/* Remove the timer from the object tracker */destroy_timer_on_stack(&timer.timer);timeout = expire - jiffies;out:return timeout < 0 ? 0 : timeout;
}
EXPORT_SYMBOL(schedule_timeout);
  • schedule_timeout
/** We can use __set_current_state() here because schedule_timeout() calls* schedule() unconditionally.*/
signed long __sched schedule_timeout_interruptible(signed long timeout)
{__set_current_state(TASK_INTERRUPTIBLE);return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_interruptible);signed long __sched schedule_timeout_killable(signed long timeout)
{__set_current_state(TASK_KILLABLE);return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_killable);signed long __sched schedule_timeout_uninterruptible(signed long timeout)
{__set_current_state(TASK_UNINTERRUPTIBLE);return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_uninterruptible);/*1. Like schedule_timeout_uninterruptible(), except this task will not contribute2. to load average.*/
signed long __sched schedule_timeout_idle(signed long timeout)
{__set_current_state(TASK_IDLE);return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_idle);
  1. schedule_timeout_interruptible
    将进程状态设置为可中断状态后睡眠,定时器时间到达后进程被唤醒。
  2. schedule_timeout_uninterruptible
    将进程状态设置为不可中断状态后睡眠,定时器时间到达后进程被唤醒。
  3. schedule_timeout_killable
    将进程状态设置为killable后睡眠,定时器时间到达后进程被唤醒。
  4. schedule_timeout_idle
    将进程状态设置为idle后睡眠,定时器时间到达后进程被唤醒。
  • msecs_to_jiffies
/*** msecs_to_jiffies: - convert milliseconds to jiffies* @m:	time in milliseconds** conversion is done as follows:** - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)** - 'too large' values [that would result in larger than*   MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.** - all other values are converted to jiffies by either multiplying*   the input value by a factor or dividing it with a factor and*   handling any 32-bit overflows.*   for the details see __msecs_to_jiffies()** msecs_to_jiffies() checks for the passed in value being a constant* via __builtin_constant_p() allowing gcc to eliminate most of the* code, __msecs_to_jiffies() is called if the value passed does not* allow constant folding and the actual conversion must be done at* runtime.* the HZ range specific helpers _msecs_to_jiffies() are called both* directly here and from __msecs_to_jiffies() in the case where* constant folding is not possible.*/
static __always_inline unsigned long msecs_to_jiffies(const unsigned int m)
{if (__builtin_constant_p(m)) {if ((int)m < 0)return MAX_JIFFY_OFFSET;return _msecs_to_jiffies(m);} else {return __msecs_to_jiffies(m);}
}/*1. Convert jiffies to milliseconds and back.2.  3. Avoid unnecessary multiplications/divisions in the4. two most common HZ cases:*/
unsigned int jiffies_to_msecs(const unsigned long j)
{
#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)return (MSEC_PER_SEC / HZ) * j;
#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
#else
# if BITS_PER_LONG == 32return (HZ_TO_MSEC_MUL32 * j + (1ULL << HZ_TO_MSEC_SHR32) - 1) >>HZ_TO_MSEC_SHR32;
# elsereturn DIV_ROUND_UP(j * HZ_TO_MSEC_NUM, HZ_TO_MSEC_DEN);
# endif
#endif
}
EXPORT_SYMBOL(jiffies_to_msecs);
  1. msecs_to_jiffies
    ms转换成jiffies
  2. jiffies_to_msecs
    jiffies转换成ms

相关内容

热门资讯

springboot简介和项目... Java知识点总结:想看的可以从这里进入 目录SpringBoot1、简介和原理1....
最新或2023(历届)嘉祥教育... 信息时报讯 面临中考,初三学生陈黎的父母十分发愁。一是孩子成绩并不拔尖,另外,父母虽然有心让儿子出...
“牛孩儿”“每天一题”助你提升... “小升初”的战鼓越擂越响,你准备好了吗?不要着急,自4月29日起,中原网教育频道官方微信“中原教育”...
这是一封发给西安小升初家长的邀... 秦学·伊顿交大校区4月9日晚上举办的小升初讲座圆满结束了,回顾讲座现场的瞬间,小编有一些小小的感动。...
四大法宝护航“528冲刺班”巨... 又是一个四月,春风扑面,鲜花盛开。又是一届小考,竞争激烈,埋头伏案。又是一轮冲刺,全力以赴,舍我其谁...
小升初数学面谈题型归纳 小升初... 数学在小升初择校中的重要性可以说是毋庸置疑的。很多一线名校例如二中应元、六中珠江、广大附等都对数学情...
vue2+3 pinia v... 1. 为什么要学习vue1.官网https://v3.cn.vuejs.org/guide/migr...
防雷设计、防雷检测为什么选同为... 随着现代科技的不断发展,电子设备得到广泛应用,而雷电等自然灾害也越来越频...
最新或2023(历届)快乐的下...  今天下午,我去了隋唐遗址。那里好美丽;有小河;有草地,小河里有鱼,有虾。  我先说河,有的河水清澈...
最新或2023(历届)6年级数...  篇一  今天,妈妈给我出了一道题,题目是这样的:“一头牛可换6头猪,2头猪可换10只羊,三只羊可换...
本次小升初直升考试试卷分析这就... 还记得前几天预告的小升初直升考试吗?这次的考试对于小学六年级的孩子们来说,是非常重要的。家长朋友们也...
西安小升初528预录来了! 西... 相信大家这几天除了被各种各样的学校参观弄得有点晕,到底这参观是几个意思呢!是有暗示还是没暗示,其实这...
最新或2023(历届)认真积极...   今天妈妈带我去学英语,上课我认真听盘,积极的举手回答问题,下课后妈妈表扬了我,我很高兴。回到家我...
【js】多分支语句练习(2) 个人名片: 😊作者简介:一名大一在校生,w...
Git 的 Cherry-Pi... 1、什么是 Cherry-Pickcherry-pick 是 Git 版本控制工具中的一个命令&#x...
最新或2023(历届)观察日记...  1.  7月23日星期一  今天我从东北回来了,我迫不急待的去看我出发前种下的含羞草种子,都十天了...
多线程进阶学习01------... 开篇:为什么学习多线程 实事求是地讲,对于绝大多数研发人员,...
最新或2023(历届)观察日记...  1.  有一天,我和好朋友们到小河边捉鱼摸虾。忽然发现,阴天的时候小鱼都跳到半空中。这是为什么呢?...
最新或2023(历届)小学数学...   1.  果园里的苹果树是梨树的3倍,老王师傅每天给50棵苹果树20棵梨树施肥,几天后,梨树全部施...
最新或2023(历届)4年级数...  1.  今天上午,我按照爸爸让我写的“假期计划”,开始了复习数学、练习数学、加强数学的“启动仪式”...