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


Синхронизация доступа к данным устройства

Как правило, подпрограммы InterruptService или InterruptMessageService (ISR) драйвера должны совместно использовать доступ к данным драйвера и аппаратным ресурсам с другими подпрограммами драйвера. Так как ISR выполняются в контексте прерывания с повышенными привилегиями IRQL, а система может иметь несколько процессоров, важно синхронизировать доступ к общим данным и ресурсам, чтобы каждая подпрограмма могла временно гарантировать монопольный доступ к этой общей информации без прерывания.

Система поддерживает эту синхронизацию, выполняя ISR в разделе критического прерывания. Прерывание имеет назначенную блокировку спина, блокировку прерывания и IRQL, irQL синхронизации прерываний IRQL. Система гарантирует выполнение этого кода в критическом разделе монопольного доступа к общей информации, поднимая IRQL процессора до irQL синхронизации прерываний IRQL и приобретая блокировку прерывания перед выполнением кода. Система всегда входит в критически важный раздел прерывания перед выполнением isR. Разные прерывания могут совместно использовать один и тот же критический раздел путем совместного использования блокировки прерывания спина и синхронизации IRQL.

Драйверы могут реализовать код, который выполняется в критическом разделе прерывания, предоставляя подпрограмму SynchCritSection . Когда драйвер использует KeSynchronizeExecution для вызова подпрограммы SynchCritSection , система автоматически вводит критический раздел для прерывания, указанного параметром Interrupt .

Вызов IRQL процессора в irQL синхронизации прерывания предотвращает прерывание работы текущего процессора, за исключением прерывания с более высокой синхронизацией IRQL. Получение блокировки спина не позволяет другим процессорам выполнять любой критически важный код раздела, связанный с этой блокировкой спина.

Система назначает прерывание блокировки спина и синхронизации IRQL для прерывания, когда драйвер вызывает IoConnectInterruptEx. В большинстве случаев драйвер может разрешить системе определять оба значения:

  • Если драйвер использует CONNECT_LINE_BASED версию IoConnectInterruptEx и задает блокировку со спином NULL , система выделит блокировку спина для строки прерывания. Система также определяет значение irQL синхронизации (драйверы могут дополнительно указать более высокое значение).

  • Если драйвер использует CONNECT_MESSAGE_BASED версию IoConnectInterruptEx и задает спиновую блокировку NULL , система выделяет спин-блокировку для каждого сообщения прерывания. Система также определяет значение IRQL синхронизации для каждого сообщения (при необходимости драйверы могут указать более высокое значение, которое будет общим для всех сообщений).

Драйвер должен выделять собственную спиновую блокировку только при использовании CONNECT_FULLY_SPECIFIED версии IoConnectInterruptEx и при наличии нескольких векторов прерываний, которые должны совместно использовать один и тот же критический раздел. Драйвер может указать собственную блокировку спина и синхронизацию IRQL с помощью элементов SpinLock и SynchronizeIrqlIO_CONNECT_INTERRUPT_PARAMETERS. Дополнительные сведения см. в разделе IO_CONNECT_INTERRUPT_PARAMETERS.

Сведения о написании и вводе критических разделов см. в разделе Использование критических разделов.