Previous Next

Always Preemptible and Always Interruptible

The Kernel component determines when a particular sequence of code is run according to one of the following prioritizing criteria:

In general, threads run at IRQL=PASSIVE_LEVEL no interrupt vectors are masked. Software interrupts are assigned relatively low IRQL values (APC_LEVEL, DISPATCH_LEVEL, or, for kernel debugging, WAKE_LEVEL). Device interrupts have higher IRQL values, and the Kernel reserves the highest IRQL values for system-critical interrupts such as the system clock or bus-error interrupts.

Some system support routines run at IRQL=PASSIVE_LEVEL both because some kernel-mode components set up their own threads and because some support routines are implemented as pageable code and/or access pageable data.

Similarly, certain standard driver routines usually run at IRQL = PASSIVE_LEVEL. However, several standard driver routines run either at IRQL=DISPATCH_LEVEL or, for a lowest-level driver, at device IRQL (also called DIRQL). See Managing Hardware Priorities for a detailed discussion of IRQLs.

In general, only a highest-level driver is called in the context of the thread that is requesting the driver's current I/O operation. An intermediate or lowest level driver can never assume that it is executing in the context of the thread that requested its current I/O operation.

For performance reasons (avoiding context switches), very few drivers set up their own threads. Consequently, driver routines usually execute in the context of whatever thread happens to be current when a standard driver routine is called to get some work done. That is, they execute in an arbitrary thread context.

While any kernel-mode routine that is run at higher than PASSIVE_LEVEL IRQL has a higher priority than all threads in the system, every routine in a driver is interruptible: any kernel-mode routine running at a particular IRQL retains control of the processor only if no interrupt with a higher Kernel-assigned IRQL occurs while that routine is running.

Even a lowest-level driver's interrupt service routine (ISR) can be interrupted by another routine (for example, by another driver's ISR) that runs at higher IRQL. Unlike the drivers in some older PC operating systems, a Windows driver's ISR is never the workhorse routine that does almost all of the driver's I/O processing because the driver's ISR does not necessarily retain control of the CPU it is currently running on until it returns.

Instead, a lowest-level driver must carry out most of its I/O operations at a lower IRQL than the DIRQL of its ISR. For good overall system performance, all kernel-mode routines that run at high IRQLs must relinquish control of the CPU quickly. Such routines do only what must be done at high IRQL and generally queue a deferred procedure call (DPC) to complete any operations that can be done at a lower IRQL (DISPATCH_LEVEL).

The goal of the interruptible, preemptible design of the operating system is to maximize average performance. Any driver's ISR can be interrupted in favor of a routine that runs at a higher IRQL, and any thread can be preempted by a thread with a higher priority. Although some threads have real-time priority attributes, even these threads can be preempted by a thread with a still-higher priority. Thus the Windows architecture does not provide an inherently real-time system.