目录

  • 1. schedule_timeout
    • 1.1 函数功能
    • 1.2 参数
    • 1.3 代码
    • 1.4 流程图
    • schedule_timeout衍生接口
  • 更新

Kernel Version : 5.16.0-rc1

1. schedule_timeout

1.1 函数功能

将当前task调度出cpu,并根据传入的timeout决定何时重新调度。

1.2 参数

参数分为以下几种类型:

参数值含义
MAX_SCHEDULE_TIMEOUTtask睡眠后不主动唤醒
0 < timeout < MAX_SCHEDULE_TIMEOUT在timeout个jiffies后重新调度task
timeout < 0无效值,报错返回

1.3 代码

代码路径

  • kernel/time/timer.c

详细代码分析,请见注释

signed long __sched schedule_timeout(signed long timeout)
{
        struct process_timer timer;
        unsigned long expire;

        switch (timeout)
        {
        case MAX_SCHEDULE_TIMEOUT: //task睡眠后,不唤醒
                /*
                 * 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; //待task再次唤醒后,退出本函数
        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) { //若传入的timeout不正确,报错打印后,设置task为running状态,退出函数
                        printk(KERN_ERR "schedule_timeout: wrong timeout "
                                "value %lx\n", timeout);
                        dump_stack();
                        __set_current_state(TASK_RUNNING);
                        goto out; //此时返回0
                }
        }

        expire = timeout + jiffies; //根据传入的参数,计算出到期时间点

        timer.task = current; //设置timer
        timer_setup_on_stack(&timer.timer, process_timeout, 0); //timer初始化
        __mod_timer(&timer.timer, expire, MOD_TIMER_NOTPENDING); //将timer配置到kernel中,低精度timer
        schedule(); //调度点
        del_singleshot_timer_sync(&timer.timer); //等待timer handler运行完成后,删除该timer

        /* Remove the timer from the object tracker */
        destroy_timer_on_stack(&timer.timer); //从debug object中删除该timer

        timeout = expire - jiffies; //期望唤醒的时间点 减去 当前的时间点, 赋值给timeout
        							//(当timer未到期就被唤醒时 expire > jiffies, timeout为负数)
        							//(当timer到期后唤醒时 expire <= jiffies, timeout为正数)

 out:
        return timeout < 0 ? 0 : timeout;
}
EXPORT_SYMBOL(schedule_timeout);

1.4 流程图

schedule_timeout衍生接口

函数名功能
schedule_timeout_interruptible在执行前将当前task的状态设置为TASK_INTERRUPTIBLE,可被信号唤醒
schedule_timeout_killable在执行前将当前task的状态设置为TASK_KILLABLE,无法被常规信号唤醒,可以被致命信号唤醒
schedule_timeout_uninterruptible在执行前将当前task的状态设置为TASK_UNINTERRUPTIBLE,无法被信号唤醒,只能wake_up
schedule_timeout_idle在执行前将当前task的状态设置为TASK_IDLE

更新

2021年11月16日
初稿
2021年11月18日
添加章节:schedule_timeout衍生接口

更多推荐

schedule_timeout 函数分析