Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
来源:互联网 发布:linux赋予用户root权限 编辑:程序博客网 时间:2024/05/22 15:49
Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
目录(?)[+]
我们已经在前面几章介绍了低分辨率定时器和高精度定时器的实现原理,内核为了方便其它子系统,在时间子系统中提供了一些用于延时或调度的API,例如msleep,hrtimer_nanosleep等等,这些API基于低分辨率定时器或高精度定时器来实现,本章的内容就是讨论这些方便、好用的API是如何利用定时器系统来完成所需的功能的。
/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/droidphone原创,转载请注明出处,谢谢!
/*****************************************************************************************************/
1. msleep
msleep相信大家都用过,它可能是内核用使用最广泛的延时函数之一,它会使当前进程被调度并让出cpu一段时间,因为这一特性,它不能用于中断上下文,只能用于进程上下文中。要想在中断上下文中使用延时函数,请使用会阻塞cpu的无调度版本mdelay。msleep的函数原型如下:
- void msleep(unsigned int msecs)
- unsigned long msleep_interruptible(unsigned int msecs)
图1.1 两个延时函数的调用序列
下面我们看看schedule_timeout函数的实现,函数首先处理两种特殊情况,一种是传入的延时jiffies数是个负数,则打印一句警告信息,然后马上返回,另一种是延时jiffies数是MAX_SCHEDULE_TIMEOUT,表明需要一直延时,直接执行调度即可:
- signed long __sched schedule_timeout(signed long timeout)
- {
- struct timer_list timer;
- unsigned long expire;
- switch (timeout)
- {
- case MAX_SCHEDULE_TIMEOUT:
- schedule();
- goto out;
- default:
- 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;
- setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);
- __mod_timer(&timer, expire, false, TIMER_NOT_PINNED);
- schedule();
- static void process_timeout(unsigned long __data)
- {
- wake_up_process((struct task_struct *)__data);
- }
- del_singleshot_timer_sync(&timer);
- /* Remove the timer from the object tracker */
- destroy_timer_on_stack(&timer);
- timeout = expire - jiffies;
- out:
- return timeout < 0 ? 0 : timeout;
- }
说完了关键的schedule_timeout函数,我们看看msleep如何实现:
- signed long __sched schedule_timeout_uninterruptible(signed long timeout)
- {
- __set_current_state(TASK_UNINTERRUPTIBLE);
- return schedule_timeout(timeout);
- }
- void msleep(unsigned int msecs)
- {
- unsigned long timeout = msecs_to_jiffies(msecs) + 1;
- while (timeout)
- timeout = schedule_timeout_uninterruptible(timeout);
- }
看看msleep_interruptible的实现:
- signed long __sched schedule_timeout_interruptible(signed long timeout)
- {
- __set_current_state(TASK_INTERRUPTIBLE);
- return schedule_timeout(timeout);
- }
- 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);
- }
- signed long __sched schedule_timeout_killable(signed long timeout)
- {
- __set_current_state(TASK_KILLABLE);
- return schedule_timeout(timeout);
- }
2. hrtimer_nanosleep
- long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
- const enum hrtimer_mode mode, const clockid_t clockid)
- {
- struct restart_block *restart;
- struct hrtimer_sleeper t;
- int ret = 0;
- unsigned long slack;
- slack = current->timer_slack_ns;
- if (rt_task(current))
- slack = 0;
- hrtimer_init_on_stack(&t.timer, clockid, mode);
- hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack);
- if (do_nanosleep(&t, mode))
- goto out;
- /* Absolute timers do not update the rmtp value and restart: */
- if (mode == HRTIMER_MODE_ABS) {
- ret = -ERESTARTNOHAND;
- goto out;
- }
- if (rmtp) {
- ret = update_rmtp(&t.timer, rmtp);
- if (ret <= 0)
- goto out;
- }
- restart = ¤t_thread_info()->restart_block;
- restart->fn = hrtimer_nanosleep_restart;
- restart->nanosleep.clockid = t.timer.base->clockid;
- restart->nanosleep.rmtp = rmtp;
- restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);
- ret = -ERESTART_RESTARTBLOCK;
- out:
- destroy_hrtimer_on_stack(&t.timer);
- return ret;
- }
- void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task)
- {
- sl->timer.function = hrtimer_wakeup;
- sl->task = task;
- }
- EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
- static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
- {
- hrtimer_init_sleeper(t, current);
- do {
- set_current_state(TASK_INTERRUPTIBLE);
- hrtimer_start_expires(&t->timer, mode);
- if (!hrtimer_active(&t->timer))
- t->task = NULL;
- if (likely(t->task))
- schedule();
- hrtimer_cancel(&t->timer);
- mode = HRTIMER_MODE_ABS;
- } while (t->task && !signal_pending(current));
- __set_current_state(TASK_RUNNING);
- return t->task == NULL;
- }
- schedule_hrtimeout 使得当前进程休眠指定的时间,使用CLOCK_MONOTONIC计时系统;
- schedule_hrtimeout_range 使得当前进程休眠指定的时间范围,使用CLOCK_MONOTONIC计时系统;
- schedule_hrtimeout_range_clock 使得当前进程休眠指定的时间范围,可以自行指定计时系统;
- usleep_range 使得当前进程休眠指定的微妙数,使用CLOCK_MONOTONIC计时系统;
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep() .
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device .
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- C/C++编译过程理解
- android superuser.apk管理root权限原理分析
- Eddy's digital Roots(hdu1163二分取模)
- Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现
- http://www.datakong.cn/
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
- Ubuntu 12.04安装GCC-3.4.6
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)
- SQL2008无法连接到.\SQLEXPRESS,用户'sa'登录失败(错误18456)图文解决方法
- 看大神文章小结——微软等面试 31,32,33,34
- Bloom Filter(布隆过滤器)用于 检查一个元素是否在集合中
- jQuery表单校验jquery.validate.js的使用
- const volatile int i = 10
- vs2010 调试未能将脚本调试器附加到xx解决方案