kernel的版本是 3.19.2
今天有空了解了下调度算法,cfs, rt等。由调度算法想到driver中经常会有些延迟的操作,比如想给设备一些准备的时间,或是等待信号状态稳定等。
这个延迟的函数可以用msleep(timeout),当然可以看出它是放弃了cpu,等到一定时间后再由系统重新调度来运行它。
所以来看下msleep()的具体实现. 它是用了个timer来处理当时间到了就wake up该进程。
1.原型在 kernel/time/timer.c
void msleep(unsigned int msecs)
void msleep(unsigned int msecs)
1691 {
1692 unsigned long timeout = msecs_to_jiffies(msecs) + 1; // in jiffies, when timer irq happens, jiffies will increase by 1
1693
1694 while (timeout) //if it is waken up by signal before timeout, it still will sleep ,until timeout equals 0
1695 timeout = schedule_timeout_uninterruptible(timeout); //
1696 }
----->
1528 signed long __sched schedule_timeout_uninterruptible(signed long timeout)
1529 {
1530 __set_current_state(TASK_UNINTERRUPTIBLE); //can't be waken up by signal?
1531 return schedule_timeout(timeout);
1532 }
---> schedule_timeout()
1459 signed long __sched schedule_timeout(signed long timeout)
1460 {
1461 struct timer_list timer; //!!!!!!!!!!!!!timer irq will call it?
1462 unsigned long expire;
1463
492
1493 expire = timeout + jiffies;
1494
1495 setup_timer_on_stack(&timer, process_timeout/*timer handler*/, (unsigned long)current/*this process pointer*/);//!!!!!!!!!!!!!
1496 __mod_timer(&timer, expire, false, TIMER_NOT_PINNED);
1497 schedule(); //call schedule system to pick up another process to run!!!!!!!!!!!!!!!!!! this process will sleep here!!!!!!!!!
1498 del_singleshot_timer_sync(&timer);
1499
1500 /* Remove the timer from the object tracker */
1501 destroy_timer_on_stack(&timer);
1502
1503 timeout = expire - jiffies;
1504
1505 out:
1506 return timeout < 0 ? 0 : timeout;
1507 }
----->process_timeout()
1428 static void process_timeout(unsigned long __data)
1429 {
1430 wake_up_process((struct task_struct *)__data); //!!!!!!!here will make the sleep process to return to run queue!!!!!!!!!!!
1431 }