Einführung in SynchCritSection-Routinen
Kritische Abschnitte sind Codeabschnitte, die exklusiven Zugriff auf Hardwareressourcen oder Treiberdaten erfordern. Das heißt, der Code darf nicht durch anderen Code unterbrochen werden, der auf dieselben Ressourcen oder Daten verweisen kann, und auf die Ressourcen oder Daten darf nicht mehr als ein Prozessor gleichzeitig verweisen.
Kritische Abschnitte sollten auf ISRs und SynchCritSection-Routinen beschränkt sein. Das System ruft diese Routinen nur auf, nachdem der IRQL des aktuellen Prozessors auf den DIRQL-Wert des Geräts erhöht und eine Drehsperre erhalten hat. Nachdem eine SynchCritSection-Routine zurückgegeben wurde, gibt das System die Spinsperre auf und senkt die IRQL des Prozessors.
Das Erhöhen des IRQL des Prozessors auf den DIRQL-Wert des Geräts verhindert, dass der aktuelle Prozessor unterbrochen wird, mit Ausnahme eines Geräts mit höherer Priorität. Das Abrufen einer Spinsperre verhindert, dass andere Prozessoren kritischen Abschnittscode ausführen, der dieser Spinsperre zugeordnet ist. (Diese Spinsperre wird manchmal als Interrupt-Spinsperre bezeichnet.)
Die StartIo- und DpcForIsr- oder CustomDpc-Routinen eines Gerätetreibers müssen häufig auf dieselben Hardwareressourcen (z. B. Geräteregister oder einen anderen busrelativen Arbeitsspeicher) oder treiberseitig verwaltete Daten als ISR des Treibers zugreifen. Je nach Gerät oder Design des Treibers, dessen Dispatch, AdapterControl, ControllerControl oder Timerroutinen können auch auf Hardwareressourcen oder vom Treiber verwaltete Daten zugegriffen werden.
Um einen nicht ISR-kritischen Abschnitt aufzurufen, muss ein Treiber die KeSynchronizeExecution-Routine verwenden. Diese Routine akzeptiert die Adresse einer SynchCritSection-Routine als Eingabe, zusammen mit vom Treiber definierten Kontextinformationen und einem Interruptobjektzeiger. Das System verwendet den Interruptobjektzeiger, um die DIRQL- und Spin-Sperre für die Verwendung mit der SynchCritSection-Routine zu bestimmen. (Der Treiber hat diese Werte zuvor mithilfe der SpinLock- und SynchronizeIrql-Parameter der IoConnectInterrupt-Funktion angegeben.)