5.3: Concurrency in drivers
在 consoleread 和 consoleintr 函数中,你可能注意到了对 acquire 的调用。这些调用获取了一个锁,用于保护控制台驱动程序的数据结构,防止其被并发访问。这里存在三种主要的并发风险:
不同 CPU 上的两个进程可能同时调用 consoleread。
当某个 CPU 正在执行 consoleread 时,硬件可能请求该 CPU 处理控制台(实际是 UART)的中断。
当一个 CPU 正在执行 consoleread 时,中断可能在另一个 CPU 上被交付并处理。
第 6 章解释了如何使用锁来确保这些风险不会导致错误的结果。
另一种需要在驱动程序中关注并发的情况是,一个进程可能正在等待设备的输入,但表示输入已到达的中断可能会在另一个进程(或根本没有进程运行)时到达。因此,中断处理程序不能假设它所中断的进程或代码的状态。例如,中断处理程序不能安全地使用当前进程的页表调用 copyout。
通常,中断处理程序只会执行相对较少的工作(例如,将输入数据复制到缓冲区),然后唤醒上半部代码来完成其余的任务。