我花了很多时间在代码级别弄清楚函数,现在我真的很困惑。
首先在core.c中,功能__schedule()
或schedule()
似乎是最有前途的。通常在__schedule()
,我发现代码hrtick_clear(rq)
似乎是一个计时器。然后同样在__schedule()
中,将调用函数next = pick_next_task(rq)
,它将尝试找到下一个要调度的任务。对于正常任务,使用 CFS 算法。因此,我进入fair.c文件检查pick_next_task_fair函数。通过跟踪该函数,我看到hrtick_start(rq, delta)
已被调用。
所以很明显,似乎有一个基于 hrtick 的计时器用于定期激活调度算法。但奇怪的是,在core.c文件中,我真的找不到计时器是如何配置为定期调用__schedule()
或schedule()
的。我没有看到计时器配置为调用此函数。
是否使用了其他功能? linux任务调度专家可以给我一个提示吗:>
不需要任何特别的东西。计时器只是触发一个中断,中断逻辑已经必须处理确定从中断返回时要运行哪个任务。例如,请参阅来自 entry_32.S 的这段代码,它处理从中断返回的语句:
358 ENTRY(resume_userspace)
359 LOCKDEP_SYS_EXIT
360 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
361 # setting need_resched or sigpending
362 # between sampling and the iret
363 TRACE_IRQS_OFF
364 movl TI_flags(%ebp), %ecx
365 andl $_TIF_WORK_MASK, %ecx # is there any work to be done on
366 # int/exception return?
367 jne work_pending
368 jmp restore_all
369 END(ret_from_exception)
...
615 work_pending:
616 testb $_TIF_NEED_RESCHED, %cl
617 jz work_notifysig
618 work_resched:
619 call schedule
实际上有两个调度程序,或者更确切地说是 Linux 内核中的两个调度代码。有一个核心调度程序,你自己提到过称为 schedule(),它调用 __schedule()。schedule() 是从内核中的许多点调用的,例如在系统调用等之后。
还有另一个调度器代码,名称为 scheduler_tick()[这也驻留在 core.c] 中],它是一个周期性调度器,由定时器代码(timer.c)通过频率为 HZ 的中断调用,即 scheduler_tick() 在一秒内称为 HZ 时间。HZ 取决于硬件,其值在 100-1024 之间变化。scheduler_tick() 调用处理器上当前任务所属的调度类的 task_tick()。