标签:调度 count global struct 设置 抢占式 cal 标识 用户
两种情况:
时钟中断处理函数会调用 scheduler_tick()查看是否是需要抢占的时间点
void scheduler_tick(void) { int cpu = smp_processor_id(); struct rq *rq = cpu_rq(cpu); struct task_struct *curr = rq->curr; ...... curr->sched_class->task_tick(rq, curr, 0); cpu_load_update_active(rq); calc_global_load_tick(rq); ...... }
标识当前运行中的进程应该被抢占了,但是真正的抢占动作并没有发生
进程调用 `__schedule`,:分为用户态和内核态
用户态进程
时机-1: 从系统调用中返回, 返回过程中会调用 exit_to_usermode_loop, 检查 `_TIF_NEED_RESCHED`, 若打了标记, 则调用 schedule(),调用的过程和上一节解析的一样,会选择一个进程让出 CPU,做上下文切换。
时机-2: 从中断中返回, 中断返回分为返回用户态和内核态(汇编代码: arch/x86/entry/entry_64.S), 返回用户态过程中会调用 exit_to_usermode_loop()->shcedule()
内核态进程
时机-1: 发生在 preempt_enable() 中, 内核态进程有的操作不能被中断, 会调用 preempt_disable(), 在开启时(调用 preempt_enable) 时是一个抢占时机, 会调用 preempt_count_dec_and_test(), 检测 preempt_count 和标记, 若可抢占则最终调用 `__schedule`
时机-2: 发生在中断返回, 也会调用 `__schedule`
参考:《趣谈Linux操作系统》调度(中)
标签:调度 count global struct 设置 抢占式 cal 标识 用户
原文地址:https://www.cnblogs.com/mysky007/p/12342505.html