我是靠谱客的博主 风趣小馒头,最近开发中收集的这篇文章主要介绍linux arm 进程调度时机,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

基于 3.10.90 内核代码
在 kernelschedcore.c 里, 对于 __schedule 有如下注释:
/*
 * __schedule() is the main scheduler function.
 *
 * The main means of driving the scheduler and thus entering this function are:
 *
 *   1. Explicit blocking: mutex, semaphore, waitqueue, etc.
 *   (1) mutext:
 *    mutex_lock --> might_sleep --> might_resched --> 定义了 CONFIG_PREEMPT_VOLUNTARY ,则 _cond_resched
 *          -->  if (should_resched()) __cond_resched() --> __schedule
 *   (2) semaphore:
 *          void down(struct semaphore *sem) --> __down --> __down_common --> schedule_timeout --> schedule
 *          void up(struct semaphore *sem) --> __up --> wake_up_process --> try_to_wake_up --> ttwu_queue
 *               --> ttwu_do_activate --> ttwu_do_wakeup --> check_preempt_curr
 *               --> resched_task(rq->curr);  --> set_tsk_need_resched 没有直接调用 schedule, 而是只设置 TIF_NEED_RESCHED 标志位。
 *   (3) waitqueue
 *     wake_up_interruptible --> __wake_up --> __wake_up_common --> default_wake_function --> try_to_wake_up
 *
 *   2. TIF_NEED_RESCHED flag is checked on interrupt and userspace return
 *      paths. For example, see arch/x86/entry_64.S.
 *
 *      To drive preemption between tasks, the scheduler sets the flag in timer
 *      interrupt handler scheduler_tick().
 *      scheduler_tick 设置 TIF_NEED_RESCHED 的流程如下:
 *      scheduler_tick --> curr->sched_class->task_tick --> task_tick_fair
 *          --> check_preempt_tick --> resched_task --> set_tsk_need_resched
 *          --> set_tsk_thread_flag(tsk,TIF_NEED_RESCHED);
 *
 *   3. Wakeups don't really cause entry into schedule(). They add a
 *      task to the run-queue and that's it.
 *   wakeups 设置 TIF_NEED_RESCHED 的过程为:
 *      wake_up_process --> try_to_wake_up --> ttwu_queue
 *       --> ttwu_do_activate --> ttwu_do_wakeup --> check_preempt_curr 
 *       --> resched_task(rq->curr);  --> set_tsk_need_resched
 *
 *      Now, if the new task added to the run-queue preempts the current
 *      task, then the wakeup sets TIF_NEED_RESCHED and schedule() gets
 *      called on the nearest possible occasion: *

 *
 *       - If the kernel is preemptible (CONFIG_PREEMPT=y):
 *
 *         - in syscall or exception context, at the next outmost
 *           preempt_enable(). (this might be as soon as the wake_up()'s
 *           spin_unlock()!)
 *              (1) syscall 流程: vector_swi --> ret_fast_syscall (disable_irq) -->
 *                     --> fast_work_pending --> work_pending --> do_work_pending -->
 *                         if (likely(thread_flags & _TIF_NEED_RESCHED)) {
 *                                  schedule();
 *             (2) exception 流程:
 *                    __dabt_usr --> ret_from_exception --> ret_to_user
 *                                  --> ret_slow_syscall(disable_irq) --> ret_to_user_from_irq --> work_pending
 *                                  后续流程与上面的 syscall 流程相同
 *                 __dabt_svc --> svc_exit -->  没有调用到 schedule
 *             (3) preempt_enable --> preempt_check_resched -->
 *                 当设置了 TIF_NEED_RESCHED 时,preempt_schedule --> 
 *                 当中断未禁止并且未被抢占,则进行抢占并 __schedule
 *
 *            (4) spin_unlock --> raw_spin_unlock --> _raw_spin_unlock --> __UNLOCK --> preempt_enable 与上面的流程相同
 *
 *         - in IRQ context, return from interrupt-handler to
 *           preemptible context
 *             (1) __irq_svc --> 当定义了 CONFIG_PREEMPT 时,如果当前未抢占,且 _TIF_NEED_RESCHED置位,则
 *                   调用 svc_preempt  --> preempt_schedule_irq  --> 先禁止抢占,然后使能中断后  __schedule 。
 *             (2) __irq_usr --> ret_to_user_from_irq --> work_pending 和上面的 syscall 流程相同
 *
 *       - If the kernel is not preemptible (CONFIG_PREEMPT is not set)
 *         then at the next:
 *
 *          - cond_resched() call
 *          - explicit schedule() call
 *          - return from syscall or exception to user-space --- 即上面的 syscall 流程 和 exception 流程 __dabt_usr
 *          - return from interrupt-handler to user-space --- 即上面的 __irq_usr 流程
 */

最后

以上就是风趣小馒头为你收集整理的linux arm 进程调度时机的全部内容,希望文章能够帮你解决linux arm 进程调度时机所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部