Introduzione ai blocchi di selezione

I blocchi di selezione sono meccanismi di sincronizzazione solo in modalità kernel definiti dal kernel, esportati come tipo opaco: KSPIN_LOCK. È possibile usare un blocco di selezione per proteggere i dati condivisi o le risorse dall'accesso simultaneo. Durante l'esecuzione in IRQL <= DISPATCH_LEVEL, un driver può usare KeAcquireInStackQueuedSpinLock e KeReleaseInStackQueuedSpinLock per acquisire e rilasciare il blocco spin come blocco spin in coda.

In alternativa, i chiamanti in esecuzione in IRQL >= DISPATCH_LEVEL possono chiamare KeAcquireSpinLockAtDpcLevel e KeReleaseSpinLockFromDpcLevel per migliorare le prestazioni dei driver.

Molti componenti usano blocchi di selezione, inclusi i driver. Qualsiasi tipo di driver può usare uno o più blocchi di rotazione esecutivi. Ad esempio, la maggior parte dei file system usa una coda di lavoro interlocked nell'estensione del dispositivo del driver del file system (FSD) per archiviare i runtime di integrazione elaborati sia dalle routine di callback del thread di lavoro del file system che dal fsd. Una coda di lavoro interlocked è protetta da un blocco spin esecutivo, che risolve la contesa tra il fsd cercando di inserire i runtime di integrazione nella coda e tutti i thread che tentano di rimuovere contemporaneamente i runtime di integrazione. Come un altro esempio, il driver del controller floppy di sistema usa due blocchi di rotazione esecutivi. Un blocco spin esecutivo protegge una coda di lavoro interlocked condivisa con il thread dedicato al dispositivo del driver; l'altro protegge un oggetto timer condiviso da tre routine driver.

I blocchi di selezione in coda offrono prestazioni migliori rispetto ai normali blocchi di rotazione per blocchi di contesa elevati nei computer multiprocessore. Per altre informazioni, vedere Blocchi spin in coda. I driver possono anche usare KeAcquireSpinLock e KeReleaseSpinLock per acquisire e rilasciare un blocco spin come blocco di rotazione ordinario.

Per sincronizzare l'accesso a strutture di dati semplici, i driver possono usare qualsiasi routine ExInterlockedXxx per garantire l'accesso atomico alla struttura dei dati. I driver che usano queste routine non devono acquisire o rilasciare il blocco di selezione in modo esplicito.

Ogni driver con ISR usa un blocco di spin di interrupt per proteggere tutti i dati o l'hardware condivisi tra le routine ISR e le routine SynchCritSection che vengono in genere chiamate dalle routine StartIo e DpcForIsr. Un blocco di selezione interrupt è associato al set di oggetti interrupt creati quando il driver chiama Io Connessione Interrupt, come descritto in Registrazione di un ISR.

Seguire queste linee guida per l'uso dei blocchi di selezione nei driver:

  • Fornire lo spazio di archiviazione per i dati o le risorse protette da un blocco spin e per il blocco spin corrispondente nella memoria dello spazio del sistema residente (pool non di paging, come illustrato nella figura Spazi di memoria virtuale e memoria fisica). Un driver deve fornire lo spazio di archiviazione per qualsiasi blocco di rotazione esecutivo usato. Tuttavia, un driver di dispositivo non deve fornire lo spazio di archiviazione per un blocco di spin di interrupt, a meno che non abbia un ISR multiveettore o abbia più isr, come descritto in Registrazione di un ISR.

  • Chiamare KeInitializeSpinLock per inizializzare ogni blocco di selezione per il quale il driver fornisce spazio di archiviazione prima di usarlo per sincronizzare l'accesso ai dati o alle risorse condivise protetti.

  • Chiamare ogni routine di supporto che usa un blocco di rotazione in corrispondenza di un IRQL appropriato, in genere in <= DISPATCH_LEVEL per i blocchi di rotazione esecutivi o in = <DIRQL per un blocco di rotazione di interrupt associato agli oggetti interrupt del driver.

  • Implementare routine per l'esecuzione il più rapidamente possibile mentre si tiene premuto un blocco di selezione. Nessuna routine deve contenere un blocco di rotazione per più di 25 microsecondi.

  • Non implementare mai routine che eseguono una delle operazioni seguenti tenendo premuto un blocco di selezione:

    • Causa eccezioni hardware o genera eccezioni software.

    • Tentare di accedere alla memoria di paging.

    • Effettuare una chiamata ricorsiva che provocherebbe un deadlock o che potrebbe causare un blocco di rotazione da mantenere per più di 25 microsecondi.

    • Se si tenta di acquisire un altro blocco di selezione, è possibile che si verifichi un deadlock.

    • Chiamare una routine esterna che viola una delle regole precedenti.