内核延时函数【转】

转自:http://www.mamicode.com/info-detail-514261.html

1) msleep:实现毫秒级的延时,该延时保证至少延时所设置的延时时间,不会提前超时返回,会让出CPU

void msleep(unsigned int msecs)
{
	unsigned long timeout = msecs_to_jiffies(msecs) + 1;

	while (timeout)
		timeout = schedule_timeout_uninterruptible(timeout);
}

为什么在转换成jiffies时要+1呢?前边我们讲到,该延时要至少保证延时转换的jiffies时间,一个jiffies为10毫秒,比如我们可以查10个数表示一个jiffies,在数到5时调用了msleep,那么显然我们不能在此jiffies到时时返回,违反了至少延时设置的jiffies的原则,因此转换成jiffies+1是比较合适的,内核中也特意做了解释。

unsigned long msecs_to_jiffies(const unsigned int m)
{
	/*
	 * Negative value, means infinite timeout:
	 */
	if ((int)m < 0)
		return MAX_JIFFY_OFFSET;
。
。
。
}
/*
 * Change timeval to jiffies, trying to avoid the
 * most obvious overflows..
 *
 * And some not so obvious.
 *
 * Note that we don't want to return LONG_MAX, because
 * for various timeout reasons we often end up having
 * to wait "jiffies+1" in order to guarantee that we wait
 * at _least_ "jiffies" - so "jiffies+1" had better still
 * be positive.
 */
#define MAX_JIFFY_OFFSET ((LONG_MAX >> 1)-1)

2)msleep_interruptible:毫秒级延时,该延时函数有可能被信号打断提前超时,返回剩余的时间,会让出CPU

unsigned long msleep_interruptible(unsigned int msecs)
{
	unsigned long timeout = msecs_to_jiffies(msecs) + 1;

	while (timeout && !signal_pending(current))
		timeout = schedule_timeout_interruptible(timeout);
	return jiffies_to_msecs(timeout);
}

3)ssleep:秒级延时,通过调用msleep实现,会让出CPU

static inline void ssleep(unsigned int seconds)
{
	msleep(seconds * 1000);
}

4)usleep_range:该延时函数实现微秒级延时,特别之处在于其可以设定一个超时范围,通过看源代码可以发现此函数设置任务状态为ASK_UNINTERRUPTIBLE,即该延时至少可以保证延时min微秒而不被打断。会让出CPU

/**
 * usleep_range - Drop in replacement for udelay where wakeup is flexible
 * @min: Minimum time in usecs to sleep
 * @max: Maximum time in usecs to sleep
 */
void usleep_range(unsigned long min, unsigned long max)
{
	__set_current_state(TASK_UNINTERRUPTIBLE);
	do_usleep_range(min, max);
}

5)ndelay:纳秒级延时,不会让出CPU

static inline void ndelay(unsigned long x)
{
	udelay(DIV_ROUND_UP(x, 1000));
}

6)udelay:微秒延时,不会让出CPU

7)mdelay:毫秒级延时,不会让出CPU

关于延时函数会不会让出CPU,使用时需要注意,一般对延时要求特别精确,使用不让出CPU的延时函数;对延时要求不是特别精确的,可以使用让出CPU的延时函数,为了保证延时时系统不会进入睡眠,通常延时前要加上wakelock锁来组织睡眠。

时间: 2025-01-27 23:44:12

内核延时函数【转】的相关文章

5-3 Linux内核计时、延时函数与内核定时器【转】

转自:http://www.xuebuyuan.com/510594.html 5-3 Linux内核计时.延时函数与内核定时器  计时 1. 内核时钟 1.1   内核通过定时器(timer)中断来跟踪时间流 1.2   硬件定时器以周期性的间隔产生时间中断,这个间隔(即频率)由内核根据HZ来确定,HZ是一个与体系结构无关的常数. 1.3   这个时间间隔通常取1ms到10ms. 2. jiffies计算器 2.1每次当定时器中断发生时,内核内部通过一个64位的变量jiffies_64做加一计

asp脚本延时函数代码

asp脚本延时函数代码,该函数不断计算当前时间和预设时间的差值,当超过预设时候后跳出循环,占用资源可能比较大. 以下是函数代码:<%  Function Delay(s)  Dim t = Now()  While DateDiff("s", t, Now) < s  Wend  End Function  %>

C语言生成随机数的函数、延时函数

下面C语言代码使用了生成随机数的函数.延时函数.请大家仔细观察其显示效果. 从以下代码,我们可以得出一个重要的结论:当上述两类函数被放入循环时,应作出一定修改.同时还应关注其参数的定义位置(子函数外?子函数内?全局变量?局部变量?). 另外大家要注意:scanf在输入double型时,应该使用%lf,而在printf时却只需使用%f. #include<stdio.h> #include<time.h> #include<stdlib.h> double t_delay

delay-ubantu系统下,需要毫秒级的延时函数。

问题描述 ubantu系统下,需要毫秒级的延时函数. 毫秒级的延时函数,赐教赐教!包括头文件什么的.我找了Sleep,delay,可是头文件不存在.不会了-- 解决方案 头文件不存在是什么意思?如果是Ubuntu的man手册找不到头文件,可能是手册的问题.你可以用usleep函数,微秒级的 解决方案二: 死循环用rdtsc测量时间,精度在纳秒级http://blog.csdn.net/tbwood/article/details/5536597 解决方案三: sleep n 毫秒 #includ

单片机 延时函数-延时函数时间计算问题

问题描述 延时函数时间计算问题 void delay_n_ms(uchar num) { uchar time; while(num) { time = 250; // fosc = 11.0592MHz CLK_DIV = 0; while(time) time --; num --; } } 这个函数的周期是1ms吗?为什么?求大神详解! 解决方案 你用这种循环是得不到精确的延时时间的,要想得到精确的1ms还的配置定时器来定时. 另外,你的这个函数周期是不是1ms我没有算,但是这是和你单片机

嵌入式 arm-如何编写延时函数,求指点迷津

问题描述 如何编写延时函数,求指点迷津 cpu频率为400MHz,如何编写延时为1us的延时函数?请大哥门指点下.cpu为armv7架构的s5pv210处理器 解决方案 振荡频率为16MHZ,则Tcy=0.0625us. 编写us级延时函数如下: void Delay_us(unsigned char nCount) { while(--nCount); } 函数反汇编后如下: push a OFST: set 0 L13: dec(OFST+1,SP) jrne L13 pop a ret 主

指针-ucos中当调用延时函数时会释放cpu使用权,当延时时间到了以后又会夺取cpu使用权吗

问题描述 ucos中当调用延时函数时会释放cpu使用权,当延时时间到了以后又会夺取cpu使用权吗 当延时时间到了以后,这个延时的函数的优先级一定是最高的吗,这个是怎么保证的, ucos中好多次参数都是指针,或者指针的指针,变量或函数的数据类型也是很XX(不知道怎么形容,感觉不那么显眼一下子就能看懂,而是要一层一层的跟踪进去),

C++中的延时函数

1.推荐用Sleep(): MS VC++可以用MFC的Sleep函数,参数是毫秒. 包含在头文件<windows.h>里 /*#include<iostream> #include<windows.h> using namespace std; void main() { Sleep(1000); //延时1秒 cout<<"adsd"<<endl; Sleep(10000); // 注意S大写 cout<<&q

内核程序跳转内核空间的某个函数或者跳转用户空间某个函数的过程

问题描述 内核程序跳转内核空间的某个函数或者跳转用户空间某个函数的过程 运行在内核的程序,如果想调用其他内核程序,是否可以直接跳转到这个程序函数函数所在的地址(假设已经知道了目标函数的地址)? 内核程序访问用户地址空间的程序,能否直接跳转,有什么保护或者检查机制吗? 解决方案 linux用户空间和内核空间延时函数linux用户空间和内核空间延时函数linux 用户空间 和 内核空间 延时函数 解决方案二: 当然不能,这涉及到页表切换,堆栈切换,权限检查等一系列细节的东西