Warteschlangen- und Dequeuing-IRPs
Da der E/A-Manager asynchrone E/A-Vorgänge innerhalb eines Multitasking- und Multithreadsystems unterstützt, können E/A-Anforderungen an ein Gerät schneller eingehen, als der Treiber sie zum Abschluss verarbeiten kann, insbesondere auf Multiprozessorcomputern. Folglich müssen IRPs, die an ein bestimmtes Gerät gebunden sind, im Treiber in die Warteschlange gestellt werden, wenn das Gerät bereits mit der Verarbeitung eines anderen IRP beschäftigt ist.
Daher erfordert ein Treiber der niedrigsten Ebene eine der folgenden:
Eine StartIo-Routine , die der E/A-Manager aufruft, um E/A-Vorgänge für IRPs zu starten, die der Treiber in eine vom System bereitgestellte IRP-Warteschlange eingereiht hat (siehe IoStartPacket).
Ein interner IRP-Warteschlangen- und Dequeuierungsmechanismus, den der Treiber verwendet, um IRPs zu verwalten, die schneller eintreffen, als er sie erfüllen kann. Treiber können Gerätewarteschlangen, ineinander verriegelte Warteschlangen oder abbruchsichere Warteschlangen verwenden. Weitere Informationen finden Sie unter Vom Treiber verwaltete IRP-Warteschlangen.
Nur ein Gerätetreiber der niedrigsten Ebene, der alle möglichen IRP in seinen Dispatchroutinen erfüllen und abschließen kann, benötigt keine StartIo-Routine und keine vom Treiber verwalteten Warteschlangen für IRPs.
Übergeordnete Treiber verfügen fast nie über StartIo-Routinen . Die meisten Zwischentreiber verfügen weder über StartIo-Routinen noch über interne Warteschlangen. Ein zwischengeschalteter Treiber kann normalerweise IRPs mit gültigen Parametern aus seinen Dispatchroutinen übergeben und die Nachverarbeitung ausführen, die für jeden IRP in seiner IoCompletion-Routine erforderlich ist.
Im Folgenden werden im Allgemeinen einige Entwurfsüberlegungen beschrieben, um zu bestimmen, ob eine StartIo-Routine mit oder ohne interne, vom Treiber verwaltete Warteschlangen für IRPs implementiert werden soll.
StartIo-Routinen in Treibern
Für Computerperipheriegeräte, die jeweils nur einen Geräte-E/A-Vorgang verarbeiten können, können Gerätetreiber StartIo-Routinen implementieren. Für diese Treiber stellt der E/A-Manager IoStartPacket - und IoStartNextPacket-Routinen bereit, um IRPs in eine Warteschlange zu stellen und aus einer vom System bereitgestellten IRP-Warteschlange zu dequeden.
Weitere Informationen zu StartIo-Routinen finden Sie unter Schreiben einer StartIo-Routine.
Interne Warteschlangen für IRPs in Treibern
Wenn ein Gerät mehr als einen gleichzeitigen E/A-Vorgang unterstützen kann, muss der Gerätetreiber der niedrigsten Ebene interne Anforderungswarteschlangen einrichten und seine eigenen Warteschlangen für IRPs verwalten. Beispielsweise verwaltet der serielle Systemtreiber separate Warteschlangen für Lese-, Schreib-, Lösch- und Wartevorgänge auf seinen Geräten, da er serielle Vollduplexgeräte unterstützt.
Ein Höherstufiger Treiber, der Anforderungen an eine bestimmte Anzahl zugrunde liegender Gerätetreiber sendet, kann auch interne Warteschlangen von IRPs verwalten. Beispielsweise verfügen Dateisystemtreiber fast immer über interne Warteschlangen für IRPs.
Weitere Informationen finden Sie unter Vom Treiber verwaltete IRP-Warteschlangen.
Interne Warteschlangensynchronisierung
Treiber mit gerätededizierten Threads und Treiber der höchsten Ebene, die Ausführende Workerthreads (einschließlich der meisten Dateisystemtreiber) verwenden, richten in der Regel eine eigene Warteschlange für IRPs ein. Die Warteschlange wird vom Treiberthread oder vom Treiber bereitgestellten Workerthread-Rückruf und von anderen Treiberroutinen verwendet, die IRPs verarbeiten.
Ein Treiber, der eine eigene Warteschlangenstruktur implementiert, muss sicherstellen, dass der Zugriff auf die Warteschlange synchronisiert wird und dass abgebrochene IRPs aus der Warteschlange entfernt werden. Um diese Aufgabe für Treiberautoren zu vereinfachen, stellen abbruchsichere IRP-Warteschlangen ein Standardframework bereit, das Sie beim Implementieren einer IRP-Warteschlange verwenden können. Weitere Informationen finden Sie unter Cancel-Safe IRP-Warteschlangen . Dies ist die bevorzugte Methode zum Implementieren einer IRP-Warteschlange.
Treiber können auch die gesamte IRP-Warteschlangensynchronisierung implementieren und logik explizit abbrechen. Ein Treiber könnte beispielsweise eine ineinander verriegelte Warteschlange verwenden. Die Dispatchroutinen des Treibers fügen IRPs in die verriegelte Warteschlange ein, und ein vom Treiber erstellter Thread oder der Workerthreadrückruf des Treibers entfernt sie durch Aufrufen der ExInterlockedXxx List-Unterstützungsroutinen.
Der System-Diskettencontrollertreiber verwendet beispielsweise eine ineinander verriegelte Warteschlange. Der gerätededizierte Thread verarbeitet die gleiche Verarbeitung von IRPs, die von den StartIo-Routinen anderer Gerätetreiber und teilweise von der gleichen Verarbeitung von IRPs ausgeführt wird, die von den DpcForIsr-Routinen anderer Gerätetreiber ausgeführt wird.
Interne Warteschlangen mit StartIo-Routinen in Treibern
Ein Treiber, der seine eigenen internen Warteschlangen verwaltet, kann auch über eine StartIo-Routine verfügen, muss aber nicht. Die meisten Gerätetreiber der niedrigsten Ebene verfügen entweder über eine StartIo-Routine oder verwalten ihre eigenen Warteschlangen von IRPs, aber nicht beides.
Eine Ausnahme ist der SCSI-Porttreiber, der über eine StartIo-Routine verfügt und interne Warteschlangen von IRPs verwaltet. Der E/A-Manager stellt IRPs an die StartIo-Routine des Porttreibers in der Gerätewarteschlange bereit, die dem vom Treiber erstellten Geräteobjekt zugeordnet ist, das einen SCSI-HBA darstellt. Der SCSI-Porttreiber richtet außerdem Gerätewarteschlangen für IRPs für jedes Zielgerät (entsprechend einer logischen SCSI-Einheit) auf jedem HBA-gesteuerten SCSI-Bus auf dem Computer ein und verwaltet diese.
Der SCSI-Porttreiber verwendet seine zusätzlichen Gerätewarteschlangen, um IRPs aufzunehmen, die von den SCSI-Klassentreibern in LU-spezifischen Warteschlangen gesendet werden, wenn ein Gerät auf einem SCSI-Bus besonders ausgelastet ist. Die zusätzlichen LU-spezifischen Gerätewarteschlangen dieses Treibers ermöglichen es dem SCSI-Porttreiber, Vorgänge für heterogene SCSI-Geräte über einen HBA zu serialisieren, während jedes Gerät in den SCSI-Bussen dieses HBA so ausgelastet wie möglich bleibt.