网络代码处理输入分组用的是异步和中断驱动的方式。首先,一个设备中断引发接口层代码执行,然后它产生一个软中断
引发协议层代码执行。当内核完成这些级别的中断后,执行插口代码。当内核完成这些级别的中断后,执行插口代码。
在这里给每个硬件和软件中断分配一个优先级。如下图:
对于不同优先级,一个要关心的问题就是如何处理那些在不同级别的进程共享的数据结构。例如,当IP输入例程正在从它的
输入队列中取出一个接收的分组时,一个设备中断发生,抢占了协议层,并且那个设备驱动程序可能添加一个分组到IP输入
队列。这些共享的数据结构,如果不协调对他们的访问,可能会破坏数据的完整性。
Net/3代码经常调用函数splimp和splnet,这两个调用总是与splx成对出现,splx使处理器返回到原来的优先级。例如下面
这段代码,被协议层IP输入函数执行,去检查是否有其他分组在它的输入队列中等待处理。
struct mbuf *m; int s; s = splimp (); IF_DEQUEUE (&ipintrq, m); splx(s); if (m == 0) return;
调用splimp把CPU的优先级升高到网络设备驱动程序级,防止任何设备驱动程序中断发生,原来的优先级作为函数的返回值
存放在变量s中,然后执行宏IF_DEQUEUE把IP输入队列头部的第二个分组删去,并把指向此mbuf链表的指针放到变量m中。
最后,通过调用带有参数s的splx,CPU的优先级恢复到调用splimp前的级别。由于在调用splimp和splx之间所有的网络设备
驱动程序的中断被禁止,在这两个调用间的代码应尽可能的少。如果中断被禁用过长的时间,其他设备会被忽略,数据会被
丢失。
《TCP/IP详解卷2:实现》笔记--中断级别与并发,码迷,mamicode.com
时间: 2024-11-13 06:58:18