[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.
