Sincronizzazione dell'accesso ai dati del dispositivo
In genere, le routine InterruptService o InterruptMessageService (ISR) di un driver devono condividere l'accesso ai dati del driver e alle risorse hardware con altre routine driver. Poiché gli ISR vengono eseguiti in un contesto di interrupt a un IRQL con privilegi elevati e poiché un sistema potrebbe avere più processori, è importante sincronizzare l'accesso a dati e risorse condivisi in modo che ogni routine possa avere accesso temporaneamente esclusivo a queste informazioni condivise, senza interruzioni.
Il sistema supporta questa sincronizzazione eseguendo l'ISR all'interno di una sezione critica di interrupt. Un interrupt ha un blocco di selezione assegnato, il blocco di rotazione di interrupt e IRQL, la sincronizzazione interrupt IRQL. Il sistema garantisce l'esecuzione di questo codice all'interno della sezione critica accesso esclusivo alle informazioni condivise, generando irQL del processore alla sincronizzazione interrupt IRQL e acquisendo il blocco di rotazione di interrupt prima di eseguire il codice. Il sistema entra sempre nella sezione critica dell'interrupt prima di eseguire il relativo ISR. Interruzioni diverse possono condividere la stessa sezione critica condividendo il blocco di spin di interruzione e la sincronizzazione IRQL.
I driver possono implementare codice eseguito nella sezione critica dell'interrupt fornendo una routine SynchCritSection . Quando il driver usa KeSynchronizeExecution per chiamare la routine SynchCritSection , il sistema immette automaticamente la sezione critica per l'interrupt specificato dal parametro Interrupt .
L'aumento del runtime di integrazione del processore alla sincronizzazione dell'interrupt IRQL impedisce l'interruzione del processore corrente, ad eccezione di un interrupt con un irQL di sincronizzazione superiore. L'acquisizione di un blocco di selezione impedisce ad altri processori di eseguire qualsiasi codice di sezione critico associato a tale blocco di selezione.
Il sistema assegna il blocco di spin di interruzione e il runtime di sincronizzazione IRQL per l'interrupt quando il driver chiama IoConnectInterruptEx. Nella maggior parte dei casi, il driver può consentire al sistema di determinare entrambi i valori:
Se il driver usa la versione CONNECT_LINE_BASED di IoConnectInterruptEx e specifica un blocco di rotazione NULL , il sistema allocherà un blocco spin per la riga di interruzione. Il sistema determina anche il valore per il runtime di integrazione di sincronizzazione (i driver possono facoltativamente specificare un valore superiore).
Se il driver usa la versione CONNECT_MESSAGE_BASED di IoConnectInterruptEx e specifica un blocco di selezione NULL , il sistema allocherà un blocco spin per ogni messaggio di interruzione. Il sistema determina anche il valore del runtime di integrazione di sincronizzazione per ogni messaggio (i driver possono facoltativamente specificare un valore più alto che sarà comune a tutti i messaggi).
Un driver deve allocare il proprio blocco di selezione solo quando si usa la versione CONNECT_FULLY_SPECIFIED di IoConnectInterruptEx e quando ha più vettori di interruzione che devono condividere la stessa sezione critica. Un driver può specificare il proprio irQL di selezione e sincronizzazione usando i membri SpinLock e SynchronizeIrql di IO_CONNECT_INTERRUPT_PARAMETERS. Per altre informazioni, vedere IO_CONNECT_INTERRUPT_PARAMETERS.
Per informazioni sulla scrittura e l'immissione di sezioni critiche, vedere Using Critical Sections.For information about writing and entering critical sections, see Using Critical Sections.