Sdílet prostřednictvím


Přístup ke sdíleným informacím o stavu

Pokyny pro navrhování a psaní rutin SynchCritSection, které udržují stav, zahrnují následující obecné zásady:

  • Pro přístup k datům, ke kterým přistupuje ISR, musí rutina ovladače volat SynchCritSection. Kód oddílu, který není kritický, může být přerušen. Mějte na paměti, že nestačí jednoduše získat spinlock pro ochranu dat, ke kterým mají přístup také ISRy, protože ISRy se spouští na úrovni DIRQL a získání spinlocku (KeAcquireSpinLock) pouze zvýší IRQL na úroveň DISPATCH_LEVEL, což umožňuje přerušení spustit ISR na aktuálním procesoru.

  • Dejte každé rutině SynchCritSection, která udržuje informace o stavu, odpovědnost za samostatnou sadu proměnných stavu. To znamená, že se vyhněte psaní SynchCritSection rutin, které udržují překrývající se informace o stavu.

    To brání kolizím a pravděpodobně i podmínkám časování mezi rutinami SynchCritSection (a ISR) při souběžném přístupu ke stejnému stavu.

    Tím také zajistíte, že každá rutina SynchCritSection vrátí kontrolu co nejrychleji, protože jedna rutina SynchCritSection nikdy nebude muset čekat na jinou, která aktualizuje některé ze stejných informací o stavu, aby vrátily řízení.

  • Vyhněte se psaní jedné velké, obecné rutiny SynchCritSection, která více testuje podmínky k určení toho, co má dělat, místo aby skutečně dělala užitečnou práci. Na druhou stranu, vyhněte se použití mnoha SynchCritSection rutin, které nikdy nespustí podmíněný příkaz, protože každá z nich aktualizuje jen jeden bajt informací o stavu.

  • Každá rutina SynchCritSection musí co nejrychleji vrátit kontrolu, protože spuštění jakékoli rutiny SynchCritSection brání spuštění isR ovladače.

Následuje technika pro udržování čítače časovače v rámci rozšíření zařízení. Předpokládejme, že ovladač používá čítač k určení, zda vypršel časový limit vstupně-výstupní operace. Také předpokládejme, že ovladač neprovádí souběžně vstupně-výstupní operace.

  • Rutina StartIo ovladače inicializuje čítač časovače na počáteční hodnotu pro každou I/O operaci. Ovladač pak přidá sekundu k hodnotě časového limitu zařízení v případě, že jeho IoTimer rutina právě vrátila řízení.

  • ISR řidiče musí nastavit čítač časovače na hodnotu mínus jedna.

  • Rutina IoTimer ovladače se volá jednou za sekundu, aby načetla časový čítač a určila, jestli už je ISR nastavená na hodnotu -1. Pokud ne, rutina IoTimer snižuje čítač pomocí KeSynchronizeExecution k vyvolání rutiny SynchCritSection_1.

    Pokud čítač přejde na nulu, což znamená, že vypršel časový limit požadavku, SynchCritSection_1 rutina volá SynchCritSection_2 rutinu pro programování operace resetování zařízení. Pokud je hodnota čítače −1, rutina IoTimer se jednoduše vrátí.

  • Pokud DpcForIsr rutina ovladače musí přeprogramovat zařízení, aby zahájilo částečný přenos, musí znovu inicializovat čítač časovače, protože to dělala rutina StartIo.

    Rutina DpcForIsr musí také použít KeSynchronizeExecution k volání rutiny SynchCritSection_2 nebo případně rutiny SynchCritSection_3 k naprogramování zařízení pro jinou operaci přenosu.

V tomto scénáři má ovladač více než jednu SynchCritSection rutinu, z nichž každá má diskrétní a specifické odpovědnosti: jedna pro udržování čítače časovače a jedna nebo více dalších pro naprogramování zařízení. Každá rutina SynchCritSection může rychle vrátit řízení, protože provádí jednu diskrétní úlohu.

Všimněte si, že ovladač má jednu rutinu SynchCritSection_1, která spolu s ISR ovladače udržuje stav čítače časovače. Neexistuje tedy žádný konflikt pro přístup k čítači časovače mezi několika rutinami SynchCritSection a ISR.