Freigeben über


Immer vorbelastbar und immer unterbrechbar

Das Ziel des vorzeitigen, unterbrechbaren Designs des Betriebssystems besteht darin, die Systemleistung zu maximieren. Jeder Thread kann von einem Thread mit einer höheren Priorität entfernt werden, und die Interrupt-Dienstroutine (ISR) eines Treibers kann durch eine Routine unterbrochen werden, die mit einer höheren Interruptanforderungsebene (IRQL) ausgeführt wird.

Die Kernelkomponente bestimmt, wann eine Codesequenz gemäß einem der folgenden Priorisierungskriterien ausgeführt wird:

  • Das vom Kernel definierte Laufzeitprioritätsschema für Threads.

    Jeder Thread im System verfügt über ein zugeordnetes Prioritätsattribut. Im Allgemeinen verfügen die meisten Threads über Attribute mit variabler Priorität: Sie sind immer vorzeitig und werden für die Ausführung eines Roundrobins mit allen anderen Threads geplant, die derzeit die gleiche Priorität haben. Einige Threads verfügen über Echtzeitprioritätsattribute: Diese zeitkritischen Threads werden bis zum Abschluss ausgeführt, es sei denn, sie werden von einem Thread mit einem höheren Echtzeitprioritätsattribut entfernt. Die Microsoft Windows-Architektur bietet kein systeminternes Echtzeitsystem.

    Unabhängig vom Prioritätsattribut kann jeder Thread im System vorzeitig entfernt werden, wenn Hardwareunterbrechungen und bestimmte Arten von Softwareunterbrechungen auftreten.

  • Die vom Kernel definierte Interruptanforderungsebene (IRQL), der ein bestimmter Interruptvektor auf einer bestimmten Plattform zugewiesen ist.

    Der Kernel priorisiert Hardware- und Softwareunterbrechungen, sodass einige Kernelmoduscode, einschließlich der meisten Treiber, mit höheren IRQLs ausgeführt wird, sodass er eine höhere Planungspriorität als andere Threads im System hat. Die bestimmte IRQL, bei der ein Teil des Kernelmodustreibercode ausgeführt wird, wird durch die Hardwarepriorität des zugrunde liegenden Geräts bestimmt.

    Kernelmoduscode ist immer unterbrechbar: Ein Interrupt mit einem höheren IRQL-Wert kann jederzeit auftreten, wodurch ein anderer Teil des Kernelmoduscodes, der über einen höheren systemseitig zugewiesenen IRQL verfügt, sofort auf diesem Prozessor ausgeführt wird. Wenn jedoch ein Codeteil an einem bestimmten IRQL ausgeführt wird, maskiert der Kernel alle Interruptvektoren mit einem geringeren oder gleichen IRQL-Wert auf dem Prozessor.

Die niedrigste IRQL-Ebene wird PASSIVE_LEVEL genannt. Auf dieser Ebene werden keine Interruptvektoren maskiert. Threads werden in der Regel mit IRQL=PASSIVE_LEVEL ausgeführt. Die nächst höheren IRQL-Ebenen gelten für Softwareunterbrechungen. Diese Ebenen umfassen APC_LEVEL, DISPATCH_LEVEL oder WAKE_LEVEL zum Kerneldebuggen. Geräteunterbrechungen weisen noch höhere IRQL-Werte auf. Der Kernel reserviert die höchsten IRQL-Werte für systemkritische Interrupts, z. B. für Systemuhr- oder Busfehler.

Einige Systemunterstützungsroutinen werden unter IRQL=PASSIVE_LEVEL ausgeführt, entweder weil sie als auslagerungsfähiger Code implementiert sind oder auf ausserstellbare Daten zugreifen oder weil einige Kernelmoduskomponenten eigene Threads einrichten.

In ähnlicher Weise werden einige Standardtreiberroutinen normalerweise mit IRQL=PASSIVE_LEVEL ausgeführt. Mehrere Standardtreiberroutinen werden jedoch entweder mit IRQL=DISPATCH_LEVEL oder bei einem Treiber auf niedrigster Ebene auf dem GERÄT IRQL (auch ALS DIRQL bezeichnet) ausgeführt. Weitere Informationen zu IRQLs finden Sie unter Verwalten von Hardwareprioritäten.

Jede Routine in einem Treiber ist unterbrechbar. Dies schließt alle Routinen ein, die mit einem höheren IRQL als PASSIVE_LEVEL ausgeführt werden. Jede Routine, die auf einem bestimmten IRQL ausgeführt wird, behält nur dann die Kontrolle über den Prozessor, wenn während der Ausführung dieser Routine kein Interrupt für einen höheren IRQL auftritt.

Im Gegensatz zu den Treibern in einigen älteren Pc-Betriebssystemen ist die ISR eines Microsoft Windows-Treibers nie eine große, komplexe Routine, die den Großteil der E/A-Verarbeitung des Treibers übernimmt. Dies liegt daran, dass die Interruptdienstroutine (ISR ) eines Treibers durch eine andere Routine (z. B. durch die ISR eines anderen Treibers) unterbrochen werden kann, die mit einem höheren IRQL ausgeführt wird. Daher behält der ISR des Treibers nicht unbedingt die Kontrolle über eine CPU, die vom Anfang des Ausführungspfads bis zum Ende unterbrechungsfrei ist.

In Windows-Treibern speichert ein ISR in der Regel Hardwarestatusinformationen, stellt einen DPC (DeFerred Procedure Call ) in die Warteschlange und wird dann schnell beendet. Später dequeniert das System den DPC des Treibers, sodass der Treiber E/A-Vorgänge mit einer niedrigeren IRQL (DISPATCH_LEVEL) abschließen kann. Für eine gute Gesamtsystemleistung müssen alle Routinen, die mit hohen IRQLs ausgeführt werden, die Kontrolle über die CPU schnell aufgeben.

In Windows verfügen alle Threads über einen Threadkontext. Dieser Kontext besteht aus Informationen, die den Prozess identifizieren, der den Thread besitzt, sowie anderen Merkmalen wie den Zugriffsrechten des Threads.

Im Allgemeinen wird nur ein Treiber der höchsten Ebene im Kontext des Threads aufgerufen, der den aktuellen E/A-Vorgang des Treibers anfordert. Ein Treiber auf mittlerer oder niedrigster Ebene kann niemals davon ausgehen, dass er im Kontext des Threads ausgeführt wird, der den aktuellen E/A-Vorgang angefordert hat.

Daher werden Treiberroutinen normalerweise in einem beliebigen Threadkontext ausgeführt – dem Kontext des Threads, der aktuell ist, wenn eine Standardtreiberroutine aufgerufen wird. Aus Leistungsgründen (um Kontextwechsel zu vermeiden) richten nur sehr wenige Treiber eigene Threads ein.