Delen via


Synchronisatievoorbeelden

In de volgende voorbeelden ziet u wat een minidriver moet doen met betrekking tot synchronisatie en voorbeelden van wanneer synchronisatie niet mag worden gebruikt:

  • Voorbeeld: Minidriver met een werkende ISR

    Als streamklassesynchronisatie is ingeschakeld, worden alle minidriverinvoerpunten aangeroepen bij verhoogde IRQL, met behulp van KeSynchronizeExecution, wat betekent dat het IRQ-niveau van de adapter en alle lagere IRQ-niveaus worden gemaskeerd wanneer de minidriver de code uitvoert. Daarom is het noodzakelijk dat de minidriver slechts een kleine hoeveelheid werk in deze modus uitvoert.

    De minidriver mag geen code uitvoeren die doorgaans meer dan 10 tot 20 microseconden kost bij verhoogde IRQL. Als u de foutopsporingsbuild van stream.sysgebruikt, registreert de streamklasse de hoeveelheid tijd die is besteed aan verhoogde IRQL en bevestigt dat het stuurprogramma daar te veel tijd besteedt. Als de minidriver gewoon hardware DMA-registers voor een aanvraag moet programmeren of alleen poorten in de ISR moet lezen, is het meestal acceptabel om alle verwerkingen uit te voeren bij verhoogde IRQL.

    Als de minidriver verwerking moet uitvoeren die meer dan een paar microseconden in beslag neemt, zoals een minidriver die gegevens overdraagt via PIO, moet de minidriver StreamClassCallAtNewPriority gebruiken om een DISPATCH_LEVEL-callback te plannen. In de callback kan de minidriver ongeveer een halve tot een hele milliseconde nemen om de verwerking uit te voeren. Een ding om te onthouden wanneer in deze modus is dat de DISPATCH_LEVEL callback niet wordt gesynchroniseerd met de ISR.

    Dit gebrek aan synchronisatie is geen probleem als de hardware stabiel blijft wanneer de minidriver toegang heeft tot resources (bijvoorbeeld poorten of een wachtrij) tijdens de callback en in de ISR. Maar als instabiliteit een probleem kan zijn, moet de minidriver StreamClassCallAtNewPriority gebruiken om een callback met hoge prioriteit te plannen waarbij de DISPATCH_LEVEL callback resources raakt die worden gedeeld met de resources die door de ISR worden gebruikt.

    Houd er rekening mee dat een callback met hoge prioriteit gelijk is aan het aanroepen van KeSynchronizeExecution. KeSynchronizeExecution vereist dat de minidriver verwijst naar verschillende parameters die StreamClassCallAtNewPriority niet doet, maar in het algemeen resulteert de twee in hetzelfde gedrag.

    Als de minidriver slechts af en toe code moet uitvoeren die langer dan 1/2 tot 1 milliseconden duurt, of af en toe services moet aanroepen op PASSIVE_LEVEL (zoals tijdens de initialisatie), kan het instellen van StreamClassCallAtNewPriority op LAGE prioriteit worden gebruikt om een PASSIVE_LEVEL werkrolthread te verkrijgen. Houd er rekening mee dat een callback met lage prioriteit niet wordt gesynchroniseerd met iets en dat de minidriver nieuwe aanvragen kan ontvangen (ervan uitgaande dat de parameter ReadyForNextRequest NotificationType in behandeling is) of een ISR-aanroep bij het uitvoeren van een callback met lage prioriteit.

  • Voorbeeld twee: Minidriver zonder ISR

    Als synchronisatie van streamklasse is ingeschakeld, worden de toegangspunten van de minidriver allemaal aangeroepen op DISPATCH_LEVEL. De minidriver kan verwerking van ongeveer een halve tot één milliseconde doen zonder de prioriteit aan te passen. Als de minidriver slechts af en toe code moet uitvoeren die langer dan 1/2 milliseconden duurt, of af en toe services moet aanroepen op PASSIVE_LEVEL (zoals tijdens de initialisatie), kan StreamClassCallAtNewPriority met LAGE prioriteit worden gebruikt om een PASSIVE_LEVEL werkrolthread te verkrijgen. Houd er rekening mee dat een callback met lage prioriteit niet wordt gesynchroniseerd met iets en dat de minidriver nieuwe aanvragen kan ontvangen (ervan uitgaande dat de parameter ReadyForNextRequest NotificationType in behandeling is) bij het uitvoeren van een callback met lage prioriteit.

  • Wanneer synchronisatie van streamklassennietmoet worden gebruikt

    Hier volgen enkele voorbeelden van situaties waarin streamklassesynchronisatie niet mag worden gebruikt. Deze omvatten:

    • Wanneer stuurprogramma's vaak (meer dan ongeveer 20 procent van de aanvragen die de minidriver ontvangt) verwerking moeten uitvoeren die langer dan 1 milliseconde duurt, of vaak PASSIVE_LEVEL-services moeten aanroepen, zoals Microsoft DirectDraw-services. Wanneer u de foutopsporingsversie van stream.sys gebruikt, zal de streamklasse beide gevallen controleren en stoppen als synchronisatie ingeschakeld is en ze worden gedetecteerd.

    • Wanneer de minidriver een filter is zonder gekoppelde hardware. Een dergelijke minidriver moet worden uitgevoerd op PASSIVE_LEVEL omdat er geen onderliggende hardware is om mee te synchroniseren en de minidriver meestal veel verwerking uitvoert. In dit geval is het eenvoudiger om uw eigen synchronisatie uit te voeren dan onnodige overhead te veroorzaken door het gebruik van synchronisatie van stroomklassen. Gebruik indien nodig mutexes om uw wachtrijen te beveiligen.

      Fouten in synchronisatiecode kunnen vaak moeilijk te vinden zijn en in bepaalde omgevingen (zoals op NT gebaseerde besturingssystemen die worden uitgevoerd op multiprocessorsystemen) kunnen bugs pas na vele uren stress worden weergegeven. Op basis van ervaring met leveranciers, hebben de meeste leveranciers niet de mogelijkheid of de wens om te debuggen. Alleen stuurprogrammaschrijvers die bekend zijn met het schrijven van volledig asynchrone WDM-apparaatstuurprogramma's, moeten proberen hun eigen synchronisatie uit te voeren.

    • Wanneer de minidriver een bus-on-bus-type stuurprogramma is (bijvoorbeeld een USB- of 1394-randapparaatstuurprogramma) dat zich geen zorgen maakt over de synchronisatie van de feitelijke hardware, maar simpelweg verzoeken doorgeeft naar de volgende laag op PASSIVE_LEVEL en meestal callbacks ontvangt op DISPATCH_LEVEL.