Freigeben über


Multiprocessor-Safe

Das Microsoft Windows NT-basierte Betriebssystem ist für die gleichmäßige Ausführung auf Uniprozessor- und SMP-Plattformen (Symmetric Multiprocessor) konzipiert, und Kernelmodustreiber sollten für die gleiche Ausführung konzipiert sein.

Auf jeder Windows-Multiprozessorplattform gelten die folgenden Bedingungen:

  • Alle CPUs sind identisch, und entweder alle oder keiner der Prozessoren muss über identische Coprozessoren verfügen.

  • Alle CPUs nutzen Arbeitsspeicher und haben einen einheitlichen Zugriff auf Den Arbeitsspeicher.

  • Auf einer symmetrischen Plattform kann jede CPU auf Arbeitsspeicher zugreifen, einen Interrupt ausführen und auf E/A-Steuerungsregister zugreifen. (Bei einem asymmetrischen Multiprozessorcomputer nimmt dagegen eine CPU alle Interrupts für eine Reihe untergeordneter CPUs an.)

Für die sichere Ausführung auf einer SMP-Plattform muss ein Betriebssystem sicherstellen, dass Code, der auf einem Prozessor ausgeführt wird, nicht gleichzeitig auf Daten zugreift und diese ändert, auf die ein anderer Prozessor zugreift und diese ändert. Wenn beispielsweise der ISR eines Treibers der niedrigsten Ebene einen Geräteunterbrechung auf einem Prozessor verarbeitet, muss er exklusiven Zugriff auf Geräteregister oder kritische, vom Treiber definierte Daten haben, falls das Gerät gleichzeitig auf einem anderen Prozessor unterbricht.

Darüber hinaus können die E/A-Vorgänge von Treibern, die auf einem Uniprozessorcomputer serialisiert werden, in einem SMP-Computer überlappen. Das heißt, die Routine eines Treibers, die eingehende E/A-Anforderungen verarbeitet, kann auf einem Prozessor ausgeführt werden, während eine andere Routine, die mit dem Gerät kommuniziert, gleichzeitig auf einem anderen Prozessor ausgeführt wird. Unabhängig davon, ob Kernelmodustreiber auf einem Uniprozessor oder einem symmetrischen Multiprozessorcomputer ausgeführt werden, müssen sie den Zugriff auf alle vom Treiber definierten Daten oder vom System bereitgestellten Ressourcen synchronisieren, die von Treiberroutinen gemeinsam genutzt werden, und den Zugriff auf das physische Gerät synchronisieren, falls vorhanden.

Die Windows NT-Kernelkomponente exportiert einen Synchronisierungsmechanismus, der als Spinsperre bezeichnet wird und den Treiber verwenden können, um freigegebene Daten (oder Geräteregister) vor dem gleichzeitigen Zugriff durch eine oder mehrere Routinen zu schützen, die gleichzeitig auf einer symmetrischen Multiprozessorplattform ausgeführt werden. Der Kernel erzwingt zwei Richtlinien für die Verwendung von Spinsperren:

  • Nur eine Routine kann zu einem bestimmten Zeitpunkt eine bestimmte Drehsperre halten. Vor dem Zugriff auf freigegebene Daten muss jede Routine, die auf die Daten verweisen muss, zuerst versuchen, die Spinsperre der Daten abzurufen. Um auf dieselben Daten zuzugreifen, muss eine andere Routine die Spinsperre abrufen, aber die Spinsperre kann erst abgerufen werden, wenn sie vom aktuellen Halter freigegeben wird.

  • Der Kernel weist jeder Spinsperre im System einen IRQL-Wert zu. Eine Kernelmodusroutine kann eine bestimmte Spinsperre nur abrufen, wenn die Routine an der von der Spinsperre zugewiesenen IRQL ausgeführt wird.

Diese Richtlinien verhindern, dass eine Treiberroutine, die normalerweise mit einem niedrigeren IRQL ausgeführt wird, derzeit aber eine Drehsperre enthält, von einer Treiberroutine mit höherer Priorität, die versucht, dieselbe Drehsperre zu erhalten, aufgehoben wird. So wird ein Deadlock vermieden.

Die IRQL, die einer Drehsperre zugewiesen ist, ist im Allgemeinen die der höchsten IRQL-Routine, die die Spinsperre abrufen kann.

Beispielsweise teilt die ISR eines Treibers der niedrigsten Ebene häufig einen Zustandsbereich mit der DPC-Routine des Fahrers. Die DPC-Routine ruft eine vom Treiber bereitgestellte kritische Abschnittsroutine auf, um auf den freigegebenen Bereich zuzugreifen. Die Drehsperre, die den freigegebenen Bereich schützt, weist eine IRQL auf, die dem DIRQL entspricht, bei dem das Gerät unterbricht. Solange die Routine für kritische Abschnitte die Drehsperre enthält und auf den freigegebenen Bereich bei DIRQL zugreift, kann der ISR weder auf einem Uniprozessor noch auf einem SMP-Computer ausgeführt werden.

  • Der ISR kann nicht auf einem Uniprozessorcomputer ausgeführt werden, da der Geräteunterbrechung maskiert ist, wie unter Always Preemptible und Always Interruptible beschrieben.

  • Auf einem SMP-Computer kann der ISR nicht die Spinsperre abrufen, die die freigegebenen Daten schützt, während die Routine für kritische Abschnitte die Spinsperre enthält und auf die freigegebenen Daten bei DIRQL zugreift.

Eine Reihe von Kernelmodusthreads kann den Zugriff auf freigegebene Daten oder Ressourcen synchronisieren, indem auf eines der Dispatcherobjekte des Kernels gewartet wird: ein Ereignis, mutex, Semaphor, Timer oder ein anderer Thread. Die meisten Treiber richten jedoch keine eigenen Threads ein, da sie eine bessere Leistung erzielen, wenn sie Threadkontextwechsel vermeiden. Wenn zeitkritische Kernelmodusunterstützungsroutinen und Treiber bei IRQL = DISPATCH_LEVEL oder dirql ausgeführt werden, müssen sie die Spinsperren des Kernels verwenden, um den Zugriff auf freigegebene Daten oder Ressourcen zu synchronisieren.

Weitere Informationen finden Sie unter Spin Locks, Verwalten von Hardwareprioritäten und Kernel Dispatcher-Objekten.