Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Minimalizace doby, po kterou ovladač drží zámek otáčení, může výrazně zlepšit výkon ovladače i celého systému. Představte si například následující obrázek, který ukazuje, jak zámek pro přerušení chrání data specifická pro zařízení, která musí být sdílena mezi isR a rutinami StartIo a DpcForIsr v počítači SMP.
Zatímco ISR ovladače běží na úrovni DIRQL na jednom procesoru, jeho rutina StartIo běží na úrovni DISPATCH_LEVEL na druhém procesoru. Obslužná rutina přerušení jádra obsahuje InterruptSpinLock pro ISR ovladače, který přistupuje k chráněným datům specifických pro zařízení, jako je stav nebo ukazatele na registrace zařízení (SynchronizeContext), v rozšíření zařízení ovladače. Rutina StartIo, která je připravena pro přístup k SyncContext, volá KeSynchronizeExecution, předává ukazatel na přidružené objekty přerušení, shared SyncContext a rutinu SynchCritSection ovladače (AccessDevice na předchozím obrázku).
Dokud se ISR nevrátí, čímž uvolní InterruptSpinLock ovladače, KeSynchronizeExecutiončeká na druhém procesoru, což brání AccessDevice v přístupu k SynchronizeContext. KeSynchronizeExecution však také zvýší IRQL na druhém procesoru na hodnotu SynchronizeIrql objektů přerušení, čímž zabrání dalšímu přerušení zařízení na tomto procesoru, aby bylo možné AccessDevice spustit na úrovni DIRQL ihned po návratu ISR. Vyšší přerušení DIRQL pro jiná zařízení, přerušení hodin a přerušení napájení mohou na obou procesorech stále nastat.
Když ISR zařadí DpcForIsr ovladače do fronty a se vrátí, AccessDevice běží na druhém procesoru na úrovni SynchronizeIrql u přidružených objektů přerušení a přistupuje k SynchronizeContext. Mezitím se DpcForIsr spouští na jiném procesoru v DISPATCH_LEVEL IRQL. DpcForIsr je také připraven pro přístup k SyncContext, takže volá KeSynchronizeExecution pomocí stejných parametrů, jaké rutina StartIo udělala v kroku 1.
Když KeSynchronizeExecution získá zámek spinu a spustí AccessDevice jménem rutiny StartIo, má ovladačem dodaná synchronizační rutina AccessDevice výhradní přístup k SynchronizeContext. Vzhledem k tomu, že AccessDevice běží na úrovni SynchronizeIrql, obslužná rutina přerušení (ISR) ovladače nemůže získat otočný zámek a přistupovat ke stejné oblasti, dokud se otočný zámek neuvolní, i když zařízení přeruší na jiném procesoru během provádění AccessDevice.
AccessDevice se vrátí a uvolní spinlock. Rutina StartIo pokračuje v běhu na úrovni DISPATCH_LEVEL na druhém procesoru. KeSynchronizeExecution teď spouští AccessDevice na třetím procesoru, aby mohl jménem DpcForIsr přistupovat k SynchronizeContext. Pokud však došlo k přerušení zařízení předtím, než DpcForIsr zavolal KeSynchronizeExecution v kroku 2, ISR může být spuštěn na jiném procesoru dříve, než KeSynchronizeExecution získá spinlock a spustí AccessDevice na třetím procesoru.
Jak ukazuje předchozí obrázek, zatímco rutina spuštěná na jednom procesoru drží spinlock, žádná jiná rutina, která se jej snaží získat, neprovede žádnou práci. Každá rutina, která se snaží získat zámek typu spin lock, který je již držen, běží na svém aktuálním procesoru, dokud držitel neuvolní zámek typu spin lock. Když se uvolní otáčkový zámek, může ho získat právě jedna rutina; každá další rutina, která se v současné době pokouší získat ten samý otáčkový zámek, bude se dál točit.
Držitel jakéhokoli spinového zámku běží na vyvýšeném irQL: buď v DISPATCH_LEVEL pro výkonný spinový zámek, nebo v DIRQL pro přerušení zamčení. Volající KeAcquireSpinLock a KeAcquireInStackQueuedSpinLock běží na DISPATCH_LEVEL, dokud nezavolají KeReleaseSpinLock nebo KeReleaseInStackQueuedSpinLock k uvolnění zámku. Volající KeSynchronizeExecution automaticky zvyšují IRQL na aktuálním procesoru na SynchronizeIrql objektů přerušení, dokud volajícím dodaná rutina SynchCritSection nedokončí a KeSynchronizeExecution nevrátí řízení. Pro další informace se podívejte na téma Volání podpůrných rutin používajících spinové zámky.
Mějte na paměti následující skutečnost o používání spin locků:
Veškerý kód, který běží na nižší úrovni IRQL, nemůže vykonat žádnou práci na sadě procesorů obsazených držitelem spin-locku a jinými rutinami, které se snaží získat stejný spin-lock.
V důsledku toho minimalizace doby, kdy ovladač uchovává zámky otáčení, vede k výrazně lepšímu výkonu ovladačů a výrazně přispívá k lepšímu celkovému výkonu systému.
Jak ukazuje předchozí obrázek, obslužná rutina přerušení jádra spouští rutiny běžící na stejné úrovni IRQL v multiprocesorovém počítači podle pořadí, v jakém přicházejí. Jádro také dělá toto:
Když rutina ovladače volá KeSynchronizeExecution, jádro způsobí, že se rutina SynchCritSection ovladače spustí na stejném procesoru, ze kterého došlo k volání KeSynchronizeExecution (viz kroky 1 a 3).
Když ISR (přerušení služby) ovladače zařadí do fronty DpcForIsr, jádro způsobí spuštění DPC na prvním dostupném procesoru, na kterém úroveň priorita přerušení (IRQL) klesne pod DISPATCH_LEVEL. Nemusí se jednat o stejný procesor, ze kterého došlo k volání IoRequestDpc (viz krok 2).
Vstupně-výstupní operace řízené přerušením ovladače můžou být serializovány v jednoprocesorovém počítači, ale stejné operace mohou být skutečně asynchronní v počítači SMP. Jak ukazuje předchozí obrázek, ISR ovladače může běžet na CPU4 v SMP stroji dříve, než jeho DpcForIsr začne zpracovávat IRP, pro který ISR již zpracoval přerušení zařízení na CPU1.
Jinými slovy, neměli byste předpokládat, že zámek spinu pro přerušení může chránit data specifická pro operace, která ISR ukládá, když běží na jednom procesoru, před přepsáním ISR při přerušení zařízení na jiném procesoru, pokud se rutiny DpcForIsr nebo CustomDpc ještě nespustily.
Přestože by se ovladač mohl pokusit serializovat všechny vstupně-výstupní operace řízené přerušením, aby zachoval data shromážděná isR, tento ovladač by v počítači SMP neběžel mnohem rychleji než v jednoprocesorovém počítači. Pokud chcete dosáhnout nejlepšího možného výkonu ovladače při zachování přenositelného mezi jednoprocesorovými a multiprocesorovými platformami, ovladače by měly použít jinou techniku k uložení dat specifických pro operace získané isR pro následné zpracování nástrojem DpcForIsr.
Například ISR může uložit data specifická pro operace v IRP, která předá DpcForIsr. Vylepšením této techniky je implementace DpcForIsr, který se poradí s počtem rozšířeným o ISR, zpracuje tento počet IRP pomocí dat dodaných ISR a před vrácením resetuje počet na nulu. Samozřejmě, počet musí být chráněn zamykacím zámkem přerušení řidiče, protože jeho ISR a SynchCritSection by zachovaly jeho hodnotu dynamicky.