为什么在XV6调度器中禁用中断?

问题描述 投票:0回答:1

对于XV6中的sched()函数(proc.c),为什么要禁用中断?

  1. 为什么在做上下文切换时一定要禁用中断?是不是因为如果启用了中断,就可以反复调用sched函数?
  2. 为什么ncli(pushcli嵌套的深度)必须等于1?
   sched(void) {
      int intena;

      if(readeflags()&FL_IF)
        panic("sched interruptible");
      if(cp->state == RUNNING)
        panic("sched running");
      if(!holding(&ptable.lock))
        panic("sched ptable.lock");
      if(c->ncli != 1)
        panic("sched locks");

      intena = c->intena;
      swtch(&cp->context, &c->context);
      c->intena = intena;
    }
operating-system xv6
1个回答
3
投票
  1. 为什么在进行上下文切换时必须禁用中断?是不是因为如果启用了中断,就可以反复调用sched函数?

每个任务都有状态,其中包括CPU的状态和操作系统用来跟踪事物的各种变量的状态(比如当前哪个任务正在运行)。在 switch() 函数从一个任务的状态切换到另一个任务的状态;但它并不是以原子方式进行的。如果一个IRQ发生在 switch() 在从一个任务切换到另一个任务的过程中,IRQ处理程序会看到不一致的状态(例如 "当前正在运行的任务 "变量与当前的虚拟地址空间不匹配),这将导致微妙的bug,这些bug极难重现(因为你必须准确地掌握问题发生的时机),而且极难发现和修复。

请注意,支持多个CPU的操作系统不能依靠 "禁用IRQs "来防止重入问题(例如,在一个CPU上禁用IRQs不会阻止另一个CPU调用 sched() 而它已经在运行)。) 为此,XV6(它确实支持多个CPU)使用了一个锁(即 "锁")。ptable.lock).

  1. 为什么ncli(pushcli嵌套的深度)一定要等于1呢?

从CPU的角度来看。

  • 一个任务会导致 ncli 设为1
  • 换班
  • 导致 ncli 递减为零

从任务的角度看。

  • 任务的原因 ncli 设为1
  • 发生许多任务切换(当其他任务获得CPU时间时),直到任务再次获得CPU时间。
  • 任务导致 ncli 递减为零

这两种观点需要兼容。例如,如果一项任务导致 ncli 设置为2,那么(任务切换后)就会减少 ncli 两次;那么 "从该任务的角度 "来看,它是好的,但 "从CPU的角度 "来看,它就会崩溃(不同的任务只会减少 ncli 一旦导致IRQ在不该被禁用时被禁用)。)

换言之。ncli 必须始终是同一个值。之所以选择1,可能是因为它对大多数调用者来说已经 "足够好 "了,使用更高的值会增加不必要的开销。

© www.soinside.com 2019 - 2024. All rights reserved.