Udostępnij przez


Korzystanie z blokad frameworku

Czasami sterowniki muszą zapewnić specyficzną dla sterownika synchronizację funkcji wywołania zwrotnego związanych z żądaniami I/O, oprócz lub zamiast synchronizacji dostarczonej przez framework. Sterowniki mogą używać blokad synchronizacji wywołań zwrotnych, blokad spin, blokad oczekiwania i blokad przerwań w celu zsynchronizowania kodu sterownika.

Blokady synchronizacji dla wywołań zwrotnych

Jeśli skonfigurowałeś sterownik do korzystania z funkcji automatycznej synchronizacji platformy, platforma uzyskuje blokadę synchronizacji przed wywołaniem funkcji obsługi zdarzeń związanych z żądaniami we/wy sterownika.

Te blokady synchronizacji wywołania zwrotnego, które są związane z obiektami urządzeń ramowych i obiektami kolejek, mogą być także uzyskiwane przez sterowniki. Aby uzyskać blokadę synchronizacji, sterownik wywołuje element WdfObjectAcquireLock. Aby zwolnić blokadę, sterownik wywołuje funkcję WdfObjectReleaseLock.

Sterownik powinien użyć blokad synchronizacji wywołań zwrotnych, jeśli korzysta z synchronizacji na poziomie urządzenia lub poziomie kolejki funkcji wywołań zwrotnych związanych z żądaniami we/wy. W takich przypadkach, konieczne jest zsynchronizowanie kodu, który działa na poziomie IRQL = PASSIVE_LEVEL, z funkcjami wywołań zwrotnych, które działają na poziomie IRQL = DISPATCH_LEVEL. Dzieje się tak, ponieważ sterowniki mogą używać automatycznej synchronizacji tylko w przypadku funkcji wywołania zwrotnego, które są wykonywane w tym samym środowisku IRQL.

Na przykład sterownik może używać automatycznej synchronizacji dla obiektu elementu roboczego tylko wtedy, gdy poziom wykonywania obiektu nadrzędnego elementu roboczego wynosi WdfExecutionLevelPassive (ponieważ funkcja wywołania zwrotnego elementu roboczego zawsze wykonuje się na poziomie IRQL = PASSIVE_LEVEL). W związku z tym, jeśli sterownik określa WdfExecutionLevelDispatch w elemencie ExecutionLevel struktury WDF_OBJECT_ATTRIBUTES obiektu urządzenia, sterownik nie może ustawić członka AutomaticSerialization w strukturze konfiguracji obiektu podrzędnego elementu roboczego. Zamiast tego sterownik musi uzyskać blokadę synchronizacji wywołania zwrotnego w celu zsynchronizowania funkcji wywołania zwrotnego EvtWorkItem z funkcjami wywołania zwrotnego obiektu nadrzędnego urządzenia.

Blokady oczekiwania frameworku

Użyj blokad oczekiwania platformy, aby zsynchronizować dostęp do danych sterownika z kodu uruchamianego w środowisku IRQL = PASSIVE_LEVEL. Zanim sterownik może użyć blokady oczekiwania w ramach platformy, musi wywołać WdfWaitLockCreate, aby utworzyć obiekt blokady oczekiwania. Następnie sterownik może wywołać WdfWaitLockAcquire, aby uzyskać blokadę i WdfWaitLockRelease, aby ją zwolnić.

Blokady spin-locków infrastruktury

Użyj blokad spin platformy, aby zsynchronizować dostęp do danych sterownika z kodu, który działa w irQL <= DISPATCH_LEVEL. Gdy wątek sterownika uzyskuje blokadę spin, system ustawia irQL wątku na DISPATCH_LEVEL. Gdy wątek zwalnia blokadę, system przywraca IRQL wątku do poprzedniego poziomu.

Sterownik, który nie korzysta z automatycznej synchronizacji struktury, może używać blokady spinlock do synchronizowania dostępu do przestrzeni kontekstowej obiektu urządzenia, jeśli przestrzeń kontekstowa jest zapisywalna, a więcej niż jedna z funkcji wywołań zwrotnych zdarzeń sterownika uzyskuje dostęp do przestrzeni.

Aby sterownik mógł użyć spin-locka strukturalnego, musi wywołać WdfSpinLockCreate, aby utworzyć obiekt spin-lock. Sterownik może następnie wywołać WdfSpinLockAcquire w celu zdobycia blokady i WdfSpinLockRelease w celu jej zwolnienia.

Aby zapoznać się z przykładowym użyciem blokad spin, zobacz Synchronizowanie anulowania wysłanych żądań.

Blokady ramowe interrupcji

W przypadku obiektów przerwań wspierających obsługę przerwań DIRQL, blokady struktury przerwań są blokadami spin. Po uzyskaniu blokady spinlock przerwa, sterownik działa na poziomie DIRQL urządzenia, dopóki nie zwolni blokady. Aby uzyskać więcej informacji na temat używania blokad przerwań, zobacz Synchronizowanie kodu przerwania.

W przypadku obiektów przerwań, które obsługują przetwarzanie na poziomie pasywnym, blokady przerwań ram programistycznych są blokadami oczekiwania. Po uzyskaniu przez sterownik blokady oczekiwania przerwań, sterownik działa na poziomie IRQL = PASSIVE_LEVEL, dopóki nie zwolni blokady. Aby uzyskać więcej informacji na temat obsługi na poziomie pasywnym, zobacz Obsługa przerwań na poziomie pasywnym.