Udostępnij przez


Wprowadzenie do spinlocków

Blokady spinlock są definiowanymi przez jądro, tylko do trybu jądra mechanizmami synchronizacji, eksportowane jako nieprzezroczysty typ: KSPIN_LOCK. Spinlock może służyć do ochrony udostępnionych danych lub zasobów przed równoczesnym dostępem. Podczas działania na poziomie IRQL <= DISPATCH_LEVEL sterownik może użyć KeAcquireInStackQueuedSpinLock i KeReleaseInStackQueuedSpinLock, aby uzyskać i zwolnić blokadę spin jako blokadę kolejki.

Alternatywnie osoby wywołujące działające na poziomie IRQL >= DISPATCH_LEVEL mogą wywoływać KeAcquireSpinLockAtDpcLevel i KeReleaseSpinLockFromDpcLevel, aby uzyskać lepszą wydajność sterownika.

Wiele składników, w tym sterowniki, używa spin-locków. Każdy rodzaj kierowcy może używać jednej lub więcej systemowych spin locków. Na przykład większość systemów plików używa kolejki pracy z synchronizacją w rozszerzeniu urządzenia sterownika systemu plików (FSD) do przechowywania IRP, które są przetwarzane zarówno przez procedury wywołania zwrotnego wątku roboczego systemu plików, jak i przez FSD. Zablokowana kolejka pracy jest chroniona przez blokadę wykonawczą typu spin lock, która rozwiązuje rywalizację pomiędzy FSD próbującymi wstawić IRP do kolejki a wszystkimi wątkami jednocześnie próbującymi usunąć IRP. W innym przykładzie sterownik kontrolera dyskietki systemowej używa dwóch blokad spin executive. Jedna blokada spin executive chroni zablokowaną kolejkę pracy udostępnioną z dedykowanym wątkiem tego sterownika; druga chroni obiekt czasomierza współużytkowany przez trzy procedury sterowników.

Blokady spin w kolejce zapewniają lepszą wydajność niż zwykłe blokady spin dla wysokich blokad rywalizacji na maszynach wieloprocesorowych. Aby uzyskać więcej informacji, zobacz Kolejkowane blokady wirujące. Sterowniki mogą również używać KeAcquireSpinLock i KeReleaseSpinLock do uzyskiwania i zwalniania blokady spin w sposób typowy dla zwykłej blokady spin.

Aby zsynchronizować dostęp do prostych struktur danych, sterowniki mogą używać dowolnej procedury ExInterlockedXxx w celu zapewnienia niepodzielnego dostępu do struktury danych. Sterowniki korzystające z tych procedur nie muszą wprost uzyskiwać ani zwalniać blokady spin.

Każdy sterownik, który ma ISR, używa przerwania blokady spin, aby chronić dowolne dane lub sprzęt współużytkowany między ISR a procedurami SynchCritSection, które są wywoływane z procedur StartIo i DpcForIsr. Blokada obrotowa przerwania jest skojarzona z zestawem obiektów przerwania stworzonych podczas wywoływania IoConnectInterrupt, zgodnie z opisem w sekcji Rejestrowanie ISR.

Postępuj zgodnie z następującymi wytycznymi dotyczącymi używania spinlocków w sterownikach:

  • Zabezpiecz miejsce w pamięci systemowej dla wszelkich danych lub zasobów chronionych za pomocą blokady obrotowej oraz dla odpowiedniej blokady obrotowej w pamięci rezydentnej systemu (pula niestronicowana, jak pokazano na rysunku Miejsca pamięci wirtualnej i pamięć fizyczna). Kierowca musi zapewnić przestrzeń dla wszelkich blokad spin, z których korzysta. Jednak sterownik urządzenia nie musi zapewniać pamięci dla blokady spinowej przerwania, chyba że ma wielowektorowy ISR lub ma więcej niż jeden ISR, zgodnie z opisem w rejestrowaniu ISR.

  • Wywołaj KeInitializeSpinLock, aby zainicjować każdą blokadę spinu, dla której sterownik rezerwuje miejsce przed użyciem go w celu zsynchronizowania dostępu do udostępnionych danych lub zasobów, które chronią.

  • Wywołaj każdą procedurę wsparcia, która używa blokady spinlock na odpowiednim poziomie IRQL, na ogół na <= DISPATCH_LEVEL dla blokad spinlock warstwy zarządzania lub na <= DIRQL dla blokady spinlock przerwania skojarzonej z obiektami przerwań sterownika.

  • Zaimplementuj procedury, aby wykonać tak szybko, jak to możliwe, podczas gdy posiadają blokadę spin. Żadna rutyna nie powinna trzymać blokady spin na dłużej niż 25 mikrosekund.

  • Nigdy nie implementuj procedur, które wykonują dowolną z następujących czynności przy zachowaniu blokady spin:

    • Powodować wyjątki sprzętowe lub zgłaszać wyjątki oprogramowania.

    • Spróbuj uzyskać dostęp do pamięci stronicowalnej.

    • Wykonaj rekursywne wywołanie, które spowodowałoby zakleszczenie lub mogłoby spowodować zatrzymanie blokady spinu przez dłużej niż 25 mikrosekund.

    • Próba uzyskania innej blokady spin, jeśli tak może spowodować zakleszczenie.

    • Wywołaj zewnętrzną procedurę, która narusza dowolną z powyższych reguł.