内核延迟执行-sleep-dealy
创始人
2025-05-30 04:35:05
  • 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

相关内容

热门资讯

Python基础(十七):装饰... 闭包闭包(英语:Closure),又称词法闭...
计算机科学导论笔记(十四) 目录 十六、安全 16.1 引言 16.1.1 安全目标 16.1.2 攻击 16.1.2.1 威...
@Transactional导... 首先我有一个Class A和Class B,A和B存在循环依赖。 @Servi...
HTML5-表单 HTML5-表单 一、Form 1.action 属性 action 属性用于指定表单...
【小猫爪】AUTOSAR学习笔... 【小猫爪】AUTOSAR学习笔记05-Communication Stack之CanSM模块前言1 ...
c# 使用AutoResetE...         做项目时有一个需求。用一个线程去执行耗时操作。另一个线程需要使用第一个线程的操作结果...
在pycharm中使用chat... 目录 前言 一、插件安装 二、使用步骤 总结 前言 ChatGPT是目前最强大的AI,...
Codeforces Roun... G. Subsequence Addition 标签 规律、数学 链接 传送门、 结论 当前前缀和小...
算法leetcode|42. ... 文章目录42. 接雨水:样例 1:样例 2:提示ÿ...
【项目设计】负载均衡在线OJ 🎇Linux: 博客主页:一起去看日落吗分享博主的在L...
Java开发 | 重写 | 多... 前言 大家好,我是程序猿爱打拳,今天给大家带来的是面向对象之封装继承多...
【Unity】NavMesh ... 在Unity中,可以使用自带导航系统(Navigation System...
由文心一言发布会引发的思考,聊... 文章目录前言一. 文心一言的试用1.1 文心一言发布会1.2 文心一言图片生成功能试用1.3 文心一...
java线程之Thread类的... Thread类的基本用法1. Thread类的构造方法2. Thread的几个常见属性常见属性线程中...
css实现3D弹性按钮以及bo... box-shadow 在实现案例之前先了解css的阴影属性box-shadow,该属性...
【Linux】基础命令大全、实... 个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主&#...
R语言基础教程4:列表和数据框 文章目录列表数据帧表头 R语言系列:1 编程基础💎2 循环语句...
Git基础知识 Git基础知识前言一、Git基本概念1、分布式版本控制系统--Git2、Git配置命令3、Git原理...
【JavaWeb】MySQL 一、数据库的相关概念 1.数据库(DB) ==存储和管...
CPU 是如何执行程序的 代码写了那么多,你知道 a = 1 + 2 这条代码是怎么被 CPU ...
从产品的角度看缓存 文章目录 1. What——什么是缓存?2. Why——为什么需要使用缓存?2.1 什么是用户体验2...
vivado 开发过程中所遇错...  [Synth 8-4556] 开辟的数组内存空间大小问题 [Synth 8-4556] size...
1.4 K8S入门之POD和网... POD 分类 自主式POD控制器管理的POD 容器 每个容器独立存在,有自己的IP地址...
【二】一起算法---队列:ST... 纸上得来终觉浅,绝知此事要躬行。大家好!我是霜淮子,欢迎订...
在使用fastjson中遇到的... 一、在使用fastjson中遇到的问题 导论:最近在写一个JavaFx项目的时候使用...
HJ31 单词倒排 描述 对字符串中的所有单词进行倒排。 说明: 1、构成单词的字符只有26个大写或小写英...
普通插槽、具名插槽、作用域插槽 插槽 插槽就是子组件提供给父组件的占位符,用slot来表示,父组件可以在...
Go语言必知必会100问题-0... 减少代码的嵌套层数 软件开发中的“心智模型”用于描述开发人员在编码时心理活动,每段代码...
CSRF漏洞的概念、利用方式、... CSRF漏洞1.CSRF的概念1.1 什么是CSRF?1.2 基本攻击流程2.CSRF...
基于springboot开发的... 基于springboot开发的学生考勤管理系统 如需更多资料请前往文章底部获取联系方式 系统设计主要...