Kernel-Mode Driver Architecture: Windows DDK
总是可优先和总是可中断
操作系统优先权级别和可中断的设计目标为了最大化系统的性能。任何都可以被其他优先级高的线程超过,同样任何驱动的中断服务例程(interrupt service routine[ISR])都可被其他拥有更高中断请求级别(interrupt request level[IRQL])的例程所中断。
内核组件(Kernel)根括代码的优先级情况,来决定一段代码序列何时执行:
内核为线程定义的实时优先规则。
每一个系统中的线程都有一个相应的优先级属性。一般情况下,大部分线程拥有一个可变的优先级属性:她们总是可以被优先或者根据圆棒算法调度其与等同优先级线程的运行。有一部分线程拥有实时(real-time)优先级:这些对时间要求特别高的线程将会运行到结束除非她们被另一个拥有更高优先级的实时线程所超越。Windows构架从本质上来讲就从来不是一个实时(real-time)系统 。
无论线程的优先级,当硬件中断或者特定种类的软件中断发生时,系统中的任何线程都可被超越。
由内核(Kernel)定义的中断请求级别(IRQL)与特定的中断向量(interrupt vector)相绑定。
内核优先执行硬件中断和软断,因此一些内核模式的代码,包括大部分的驱动运行于高IRQLs,来确保其具有比系统当中其他线程更高的优先级。由底层设备的硬件优先级来确实相同级别IRQL时运行何段内核模式驱动的代码。
内核模式代码永远都可以被中断:一个拥有更高级别IRQL值的中断可以在任何时候产生,从而这一拥有更高的IRQL的代码能够立即在处理器上得到执行。然而,当一段代码运行机制于一个给定IRQL上,内核将屏bi所有IRQL小于或者等于该IRQL的中断向量号(interrupt vectors)。
最低的IRQL级别被称为PASSIVE_LEVEL。在这个级别上,没有屏蔽任何中断微量.
一般情况下,线程都运行于IRQL=PASSIVE_LEVEL。下一个更高阶的IRQL级别是软中断。这些级别包括APC_LEVEL,DISPATCH_LEVEL,或者为了内核调试,WAKE_LEVEL。设备中断拥有更高阶的IRQL值。内核为系统严重中断(如系统时钟和总线错误)保留了最高级别的IRQL。
一些系统支持例程只能运行于IRQL=PASSIVE_LEVEL的环境下,这可能是因为她们被设计成为可分页代码或者她们会访问可分页数据,当然也可能因为一些内核组件创建属于她们自己的线程。
同样地,一些标准驱动例程(standard driver routines)常运行于IRQL=PASSIVE_LEVEL。然而,一些标准驱动例程运行于IRQL=DISPATCH_LVEL或者对于最底层驱动来看,运行于设备IRQL级别(device IRQL,亦被称为DIRQL)。更多关于IRQLs的信息,请见
管理硬件优先级。
驱动当中任何例程都是可以被中断的。这包括那些运行于高于PASSIVE_LEVEL的IRQL级别的例程。任何运行于特定IRQL级别的例程只有在没有更高级别IRQL发生时才可以得到CPU的控制权。
与一些较古老的计算机操作系统不同,一个Microsoft Windows驱动的ISR从来都不是一个完成大部分I/O处理的由大而复杂的例程 。这是因为所有驱动的中断服务例程(interrupt service routine[ISR])都能够被其他任何更高级IRQL上他例程所中断(例如,被其他驱动的ISR)。因此,一个驱动的ISR不一定能够从一而终不间断的得到CPU的控制权,
在Windows的驱动中,一个ISR一般都保存了硬件状态信息,排队了一个延时过程调用(deferred procedure call[DPC]), 然后快速退出。过后,系统从队列中取得该驱动的DPC,这样驱动就能够在低IRQL(DISPATCH_LEVEL)完成I/O操作了。为一个优秀的全局效率,所有运行于高IRQLs必须主动快速放弃其对CPU的控制权。
在Windows当中,所有的线程都有一个线程上下文环境。这个上下文包括了标志拥有该线程的进程,还有一些线程访问权限的属性。
一般说来,只有最高级别的驱动运行于请求驱动I/O操作的线程当中。中间层驱动或者最底层驱动永远都不应该假定自己执行于请求当前I/O操作的线程环境当中。
结果是,驱动的例程常常执行于一个异线程环境(aribitrary thread context)- 标准驱动例程被调用时正在运行的任意线程。考虑到性能的问题(为了避免上下文交换),只有很少的驱动创建其自身的线程。
Microsoft Corporation
Send feedback on this topic
Built on Friday, February 18, 2005