Поделиться через


Использование блокировок платформы

Иногда драйверы должны обеспечивать синхронизацию функций обратного вызова, связанных с запросами ввода-вывода, специфичных для конкретного драйвера, в дополнение к синхронизации, предоставляемой платформой, или в качестве замены для синхронизации, предоставляемой платформой. Драйверы могут использовать блокировки синхронизации обратного вызова, спин-блокировки, блокировки ожидания и блокировки прерываний для синхронизации кода драйвера.

Блокировки синхронизации обратных вызовов

Если вы настроили драйвер для использования возможности автоматической синхронизации платформы, платформа получает блокировку синхронизации перед вызовом функций обратного вызова событий, связанных с запросом ввода-вывода драйвера.

Эти блокировки синхронизации обратного вызова, связанные с объектами устройств платформы и объектами очередей, также могут быть получены драйверами. Чтобы получить блокировку синхронизации, драйвер вызывает WdfObjectAcquireLock. Чтобы освободить блокировку, драйвер вызывает WdfObjectReleaseLock.

Может потребоваться, чтобы драйвер использовал блокировки синхронизации обратных вызовов, если драйвер использует синхронизацию функций обратного вызова на уровне устройств или очередей платформы, связанных с запросами ввода-вывода, но должен синхронизировать код, выполняемый в IRQL = PASSIVE_LEVEL с функциями обратного вызова, которые выполняются в IRQL = DISPATCH_LEVEL. Это связано с тем, что драйверы могут использовать автоматическую синхронизацию только для функций обратного вызова, которые выполняются в том же IRQL.

Например, драйвер может использовать автоматическую синхронизацию для объекта рабочего элемента, только если уровень выполнения родительского объекта рабочего элемента — WdfExecutionLevelPassive (так как функция обратного вызова рабочего элемента всегда выполняется в IRQL= PASSIVE_LEVEL). Таким образом, если драйвер указывает WdfExecutionLevelDispatch в элементе ExecutionLevelструктуры WDF_OBJECT_ATTRIBUTES объекта устройства, драйвер не может задать элемент AutomaticSerialization структуры конфигурации дочернего объекта рабочего элемента. Вместо этого драйвер должен получить блокировку синхронизации обратного вызова для синхронизации функций обратного вызова EvtWorkItem с функциями обратного вызова родительского объекта устройства.

Блокировки ожидания платформы

Используйте блокировки ожидания платформы для синхронизации доступа к данным драйвера из кода, который выполняется в IRQL = PASSIVE_LEVEL. Прежде чем драйвер сможет использовать блокировку ожидания платформы, он должен вызвать WdfWaitLockCreate , чтобы создать объект wait-lock. Затем драйвер может вызвать WdfWaitLockAcquire , чтобы получить блокировку, и WdfWaitLockRelease , чтобы освободить ее.

Блокировки спина платформы

Используйте блокировки спина платформы для синхронизации доступа к данным драйвера из кода, который выполняется в IRQL <= DISPATCH_LEVEL. Когда поток драйвера получает блокировку спина, система устанавливает IRQL потока на DISPATCH_LEVEL. Когда поток снимает блокировку, система восстанавливает IRQL потока до предыдущего уровня.

Драйвер, который не использует автоматическую синхронизацию платформы, может использовать спин-блокировку для синхронизации доступа к контекстному пространству объекта устройства, если контекстное пространство доступно для записи и если несколько функций обратного вызова событий драйвера обращаются к пространству.

Прежде чем драйвер сможет использовать спин-блокировку платформы, он должен вызвать WdfSpinLockCreate , чтобы создать объект spin-lock. Затем драйвер может вызвать WdfSpinLockAcquire , чтобы получить блокировку, и WdfSpinLockRelease , чтобы освободить ее.

Пример использования спин-блокировок см. в разделе Синхронизация отмены отправленных запросов.

Блокировки прерываний платформы

Для объектов прерываний, поддерживающих обработку прерываний DIRQL, блокировки прерываний платформы являются спин-блокировками. После того как драйвер получит блокировку прерывания, драйвер выполняется в DIRQL устройства, пока не снимет блокировку. Дополнительные сведения об использовании блокировок прерываний см. в статье Синхронизация кода прерываний.

Для объектов прерываний, поддерживающих обработку пассивного уровня, блокировками прерываний платформы являются блокировки ожидания. После того как драйвер получит блокировку ожидания прерывания, драйвер выполняется в IRQL = PASSIVE_LEVEL, пока не снимет блокировку. Дополнительные сведения об обработке пассивного уровня см. в разделе Поддержка прерываний пассивного уровня.