Sincronización del acceso a los datos del dispositivo
Normalmente, las rutinas InterruptService o InterruptMessageService de un controlador deben compartir el acceso a los datos del controlador y a los recursos de hardware con otras rutinas de controlador. Dado que los ISR se ejecutan en un contexto de interrupción en un IRQL con privilegios elevados y, dado que un sistema puede tener varios procesadores, es importante sincronizar el acceso a los datos y recursos compartidos para que cada rutina pueda tener temporalmente acceso exclusivo a esta información compartida, sin interrupción.
El sistema admite esta sincronización ejecutando el ISR dentro de una sección crítica de interrupción. Una interrupción tiene un bloqueo de número asignado, el bloqueo de número de interrupción e IRQL, la sincronización de interrupciones IRQL. El sistema garantiza que este código se ejecute dentro de la sección crítica acceso exclusivo a la información compartida mediante la generación del IRQL del procesador a la sincronización de interrupciones IRQL y la adquisición del bloqueo de número de interrupción antes de ejecutar el código. El sistema siempre entra en la sección crítica de la interrupción antes de ejecutar su ISR. Las diferentes interrupciones pueden compartir la misma sección crítica compartiendo su bloqueo de número de interrupción e IRQL de sincronización.
Los controladores pueden implementar código que se ejecuta en la sección crítica de la interrupción proporcionando una rutina SynchCritSection . Cuando el controlador usa KeSynchronizeExecution para llamar a la rutina SynchCritSection , el sistema escribe automáticamente la sección crítica para la interrupción especificada por el parámetro Interrupt .
Elevar el IRQL del procesador a la irQL de sincronización de la interrupción impide que se interrumpa el procesador actual, excepto por una interrupción con una irQL de sincronización superior. La adquisición de un bloqueo de número impide que otros procesadores ejecuten cualquier código de sección crítico asociado a ese bloqueo de número.
El sistema asigna el bloqueo de número de interrupción y el IRQL de sincronización para la interrupción cuando el controlador llama a IoConnectInterruptEx. En la mayoría de los casos, el controlador puede permitir que el sistema determine ambos valores:
Si el controlador usa la versión CONNECT_LINE_BASED de IoConnectInterruptEx y especifica un bloqueo de número NULL , el sistema asignará un bloqueo de número para la línea de interrupción. El sistema también determina el valor de la IRQL de sincronización (los controladores pueden especificar opcionalmente un valor superior).
Si el controlador usa la versión CONNECT_MESSAGE_BASED de IoConnectInterruptEx y especifica un bloqueo de número NULL , el sistema asignará un bloqueo de número para cada mensaje de interrupción. El sistema también determina el valor del IRQL de sincronización para cada mensaje (los controladores pueden especificar opcionalmente un valor mayor que será común a todos los mensajes).
Un controlador debe asignar su propio bloqueo de número solo cuando se usa la versión de CONNECT_FULLY_SPECIFIED de IoConnectInterruptEx y cuando tiene varios vectores de interrupción que deben compartir la misma sección crítica. Un controlador puede especificar su propio bloqueo de número y sincronización IRQL mediante los miembros SpinLock y SynchronizeIrql de IO_CONNECT_INTERRUPT_PARAMETERS. Para obtener más información, consulte IO_CONNECT_INTERRUPT_PARAMETERS.
Para obtener información sobre cómo escribir y escribir secciones críticas, consulte Uso de secciones críticas.