[Compuware Corporation] [Compuware NuMega home page] [NuMega Lab] [teal] [DriverStudio] [Image][Image] · Home [Driver Products] Driver Technical Tips · DriverStudio Synchronizing Multiple Interrupts · DriverBundle · Previews The Windows NT kernel provides a mechanism to protect data that is shared · Compatibility between an interrupt service routine (ISR) and code running at a lower [Downloads] · priority level. If this mechanism were not available, then the ISR could execute while the lower priority code was in the process of modifying the Wizards shared data, potentially resulting in a catastrophic failure. · Utilities · NT source The mechanism that the system provides is the service KeSynchronizeExecution: examples · VxD source BOOLEAN KeSynchronizeExecution( examples IN PKINTERRUPT Interrupt, · WDM source IN PKSYNCHRONIZEROUTINE SynchronizeRoutine, examples IN PVOID SynchronizeContext [Resources] · ); Technical papers · Useful links A driver calls KeSynchronizeExecution when it needs to access data shared · Technical tips with the ISR. The parameter SynchronizeRoutine is the address of a function [Support] · that actually accesses the shared data. The service calls the supplied function at raised IRQL, while holding the spin lock associated with the Support interrupt. If an interrupt occurs while SynchronizeRoutine is running, the · Knowledge base execution of the ISR is deferred until SynchronizeRoutine returns. · Problem submission Now suppose the driver is managing not one, but possibly several interrupts. · Product Each interrupt has its own priority level (IRQL). If the driver writer does registration not take precautions, then one ISR could interrupt the execution of a second · Release notes ISR, raising the possibility of data corruption. [Shop NuMega] · Buy it! One way to avoid the problem is to first determine which interrupt has the · Price list highest IRQL, and use KeSynchronizeExecution from inside the ISRs of · How to buy interrupts that have lower IRQLs. The ISR for the lower priority interrupt · Sales offices passes in a pointer to the interrupt object having the highest IRQL. The system takes the spin lock associated with the higher level interrupt, thereby ensuring atomic access to the critical data. This is just a [Y2K Compliance] generalization of the usage of KeSynchronizeExecution as described for sharing data between ISRs and non-interrupt code. [More information] Because it could be expensive to make extra calls and to change IRQLs while in an ISR, NT enables the driver writer to assign a common synchronization level for a set of interrupts. For a set of interrupts that have a common IRQL, the associated ISRs cannot interrupt one another, so they don't have to call KeSynchronizeExecution to ensure atomic access to data. The key to setting a common synchronization level for a set of interrupts is found in the service IoConnectInterrupt: NTSTATUS IoConnectInterrupt( OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave ); The parameter in question is SynchronizeIrql. To determine this value, the driver first collects the IRQLs for all of its interrupts (using HalGetInterruptVector), and selects the greatest. The driver must also initialize storage for a spin lock, and pass its address in parameter SpinLock. The spin lock must remain in existence while the interrupts are hooked. Once the driver has determined the greatest IRQL for all its interrupts, and has intialized a spin lock, it calls IoConnectInterrupt for each interrupt, using the same values for SynchronizeIrql and SpinLock for each call. A driver that uses this technique causes all of its ISRs to run at the same IRQL, which greatly simplifies the task of serializing access to critical data. If you develop NT or WDM drivers with DriverWorks, it is very easy to use this method. The class that handles interrupts is called KInterrupt. There are two forms of KInterrupt::Connect. The first form is the simple form, used when a driver has only one interrupt, or when multiple interrupts do not require synchronization: NTSTATUS KInterrupt::Connect(PKSERVICE_ROUTINE Isr, PVOID Context); The second form is for the case when there are multiple interrupts requiring synchronization: NTSTATUS KInterrupt::Connect( PKSERVICE_ROUTINE Isr, PVOID Context, PKSPIN_LOCK pSpin, KIRQL SynchIrql ); Back to technical tip start page. DriverCentral · DriverStudio · Free downloads · Resources · Support and Services · Shop NuMega Compuware NuMega · Tel: +1 603 578-8400 · Updated: 9 August 1999 · Problems? Contact our webmaster.