Writing reentrant code that executes at multiple IRQL levels requires attention to proper synchronization. This section examines the issues that arise in this kind of environment. The ProblemIf code executing at two different IRQLs attempts to access the same data structure simultaneously, the structure can become corrupted. Figure 5.1 illustrates the details of this synchronization problem. Figure 5.1. Synchronization problem with interrupting code.To understand the exact problem, consider this sequence of events.
Of course, similar results occur even when only a single shared value is used with different code threads. When one code path attempts to increment the variable, there may be a brief moment in time when the modified value is held in a CPU register. If this thread is interrupted prior to storing the register back into the variable, the same contention problem arises. In the following sections, techniques that a driver can use to synchronize the work of multiple code paths is described. Interrupt BlockingIn the previous example, the lower-IRQL routine could have avoided synchronization problems by preventing itself from being interrupted. To do this, it can temporarily raise the IRQL of the CPU and then lower it back to its original level after completing the modification. This technique is called interrupt blocking. Table 5.4 lists the kernel functions that a driver can use to manipulate the IRQL value. Rules for Blocking InterruptsWhen using interrupt blocking, there are certain rules that must be followed.
Synchronization Using Deferred Procedure CallsDPCs provide another way to avoid data structure collisions. If all the kernel-mode components using a particular data structure access it only from within a DPC routine, there will be no corruption since DPC routines are always executed serially. The main advantage of using DPCs for synchronization is that they run at a relatively low IRQL. Another key advantage of DPC routines is that the kernel's DPC Dispatcher automatically handles synchronization in a multi processor (MP) environment. The next section describes what is required to perform manual synchronization among multiple processors.
|