【问题标题】:Interrupt masking: why?中断屏蔽:为什么?
【发布时间】:2011-06-22 11:29:13
【问题描述】:

我正在阅读中断。可以通过特殊的中断掩码暂停非关键中断。这称为中断屏蔽。我不知道什么时候/为什么你可能想要或需要暂时挂起中断?可能是信号量,还是在多处理器环境中编程?

【问题讨论】:

  • 我的有限理解是,您通常希望在驱动程序代码的关键部分执行此操作 - 以确保“原子”操作不会中断。
  • 是我的问题还是c++ 标签与问题不太相关?
  • @Cristian Ciupitu:同意。无论如何,它与操作系统更相关。重新标记。

标签: operating-system computer-architecture interrupt


【解决方案1】:

操作系统在准备运行自己的“让我们编排世界”代码时会这样做。

例如,在某些时候操作系统线程调度程序具有控制权。它在让线程运行之前准备处理器寄存器和需要完成的所有其他工作,以便为该进程和线程设置环境。然后,在让该线程运行之前,它会设置一个计时器中断,以便在它打算让该线程在 CPU 上拥有的时间过去后引发。

在该时间段(量子)过去之后,会引发中断,并且操作系统调度程序会再次获得控制权。它必须弄清楚接下来需要做什么。为此,它需要保存 CPU 寄存器的状态,以便知道如何撤消执行代码的副作用。如果在保存状态时出于任何原因(例如,某些异步 I/O 完成)引发另一个中断,这将使操作系统处于其世界处于有效状态(实际上,保存状态需要是原子操作)。

为了避免陷入这种情况,操作系统内核因此在执行任何需要原子的操作时禁用中断。在它完成任何需要做的事情并且系统再次处于已知状态后,它会重新启用中断。

【讨论】:

  • 大多数现代操作系统都使用重入中断处理程序,这些处理程序的设计目的是无论发生多少嵌套中断,它们都不会破坏现有状态——因此不处于有效状态的情况不会t 出现。正如@Tommy 回答的那样,优先级是使用屏蔽的主要原因。
  • 这个答案讨论了禁用中断(即全局屏蔽)。它没有解决关于“通过特殊中断掩码暂停 [ing] 非关键中断”的原始问题。
  • 维基百科说全局中断掩码有很多问题,包括在多处理器系统上停止世界和时钟漂移。全局中断掩码是否仍用于 Linux/Windows/BSD 等操作系统的单处理器和多处理器情况?
  • Keil RTX在整个内核运行范围内校准没有中断阻塞,不知道它是如何实现的
【解决方案2】:

我曾经在一个可能发生大约 10 个中断的 ARM 板上编程。我编写的每个特定程序对其中的四个都不感兴趣。例如,板上有 2 个计时器,但我的程序只使用了 1 个。我将屏蔽第二个计时器的中断。如果我没有屏蔽该计时器,它可能已启用并继续产生中断,这会减慢我的代码速度。

另一个例子是我会使用 UART 接收 REGISTER 完全中断,因此永远不需要发生 UART 接收 BUFFER 完全中断。

我希望这能让您了解为什么要禁用中断。

【讨论】:

  • 感谢分享真实世界的编程示例。
【解决方案3】:

除了已经给出的答案之外,还有一个优先事项。有些中断是您需要或希望能够尽快做出响应的,还有一些您想知道的,但只有在您不那么忙时才可以。最明显的例子可能是重新填充 DVD 刻录机上的写入缓冲区(如果您不及时这样做,某些硬件只会错误地写入 DVD)与处理来自网络的新数据包。您会在收到前者的中断后禁用后者的中断,并在填充缓冲区期间保持禁用。

实际上,很多 CPU 都直接在硬件中内置了中断优先级。发生中断时,为较小的中断设置禁用标志,并且通常,该中断与读取中断向量并跳转到相关地址同时发生。指示接收中断也隐含地屏蔽了该中断,直到中断处理程序结束为止,这具有放松对中断硬件的限制的良好副作用。例如。您可以简单地说,信号高电平触发中断,让外部硬件决定它想要保持线路高电平多长时间,而不必担心无意中触发多个中断。

在许多过时的系统(包括 z80 和 6502)中,往往只有两个级别的中断——可屏蔽和不可屏蔽,我认为这就是启用或禁用中断的语言的来源。但即使早在最初的 68000 中,您也有 8 个级别的中断和 CPU 中的当前优先级级别,该级别指示实际允许哪些级别的传入中断生效。

【讨论】:

  • +1 用于提及优先事项。我只是在写这个,想知道为什么还没有人提到它。
  • 如果一个中断被禁用,它只是被忽略和丢弃,还是以某种方式排队?
  • @CMCDragonkai 取决于架构和中断设备——一些中断信号会在特定时间段内自动解决 CPU 是否动作,可能大多数会继续断言直到 CPU 处理它们.这通常取决于他们试图沟通的内容。
【解决方案4】:

假设你的 CPU 现在在“int3”处理程序中,此时“int2”发生,新发生的“int2”与“int3”相比具有较低的优先级。这种情况我们该如何处理?

一种方法是在处理“int3”时,我们会屏蔽掉其他优先级较低的中断器。也就是说,我们看到“int2”正在向 CPU 发出信号,但 CPU 不会被它中断。在我们处理完“int3”之后,我们从“int3”返回并取消屏蔽较低优先级的中断器。

我们返回的地方可以是:

  1. 另一个进程(在抢占式系统中)
  2. 被“int3”中断的进程(在非抢占系统或抢占系统中)
  3. 一个被“int3”中断的int处理程序,比如int1的处理程序。

在情况 1 和 2 中,因为我们取消了低优先级中断器的屏蔽,并且“int2”仍在向 CPU 发出信号:“嗨,有事情需要您立即处理”,那么 CPU 将再次被中断,当它正在执行来自进程的指令,以处理“int2”

在情况3中,如果“int2”的优先级高于“int1”,那么CPU在执行“int1”的handler的指令时会再次中断,去处理“int2”。

否则,"int1" 的处理程序将在不中断的情况下执行(因为我们还屏蔽了优先级低于 "int1" 的中断器),CPU 将在处理完 "int1" 并取消屏蔽后返回进程。那时会处理“int2”。

【讨论】:

    猜你喜欢
    • 2016-01-19
    • 2012-06-04
    • 2011-04-06
    • 1970-01-01
    • 2020-02-28
    • 2016-12-29
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多