Configurazione e uso di code interlocked

I nuovi driver devono usare il framework di accodamento IRP indipendente dall'annullamento in preferenza per i metodi descritti in questa sezione.

I driver con thread o driver dedicati al dispositivo che usano thread di lavoro esecutivi, ad esempio la maggior parte delle unità fsd di sistema, sono i tipi più probabili di driver per gestire il proprio accodamento interno di runtime dei runtime di integrazione in una coda interlocked. Tutti i driver PnP, inclusi i driver WDM, devono anche accodarsi internamente determinati provider di integrazione durante la transizione dello stato di alimentazione e PnP.

In genere, questi driver configurano una coda interlock collegata doubly; ogni IRP contiene un membro di tipo LIST_ENTRY, che un driver può usare per collegare in modo doubly i provider di integrazione attualmente in possesso. Un driver non può accodare i runtime di integrazione per i tentativi se configura una coda interlock collegata singly.

Un driver deve configurare la coda interlocked all'inizializzazione del dispositivo. La figura seguente illustra una coda interlock collegata doubly, le routine di supporto che un driver deve chiamare per configurare una coda di questo tipo e un set di routine ExInterlocked Xxx può chiamare un driver per inserire i punti di integrazione in e rimuovere i punti di integrazione dalla coda.

diagramma che illustra l'uso di una coda interlocked.

Come illustrato nella figura seguente, un driver deve fornire l'archiviazione per la coda stessa e per configurare una coda interlock collegata doubly:

  • Blocco spin esecutivo, che il driver deve chiamare KeInitializeSpinLock per inizializzare. In genere, un driver inizializza il blocco di rotazione quando configura le estensioni del dispositivo per i relativi oggetti dispositivo nella routine AddDevice .

  • Intestazione dell'elenco per la coda, che il driver deve inizializzare chiamando InitializeListHead.

La maggior parte dei driver che usano code interlock collegate doubly forniscono l'archiviazione necessaria nell'estensione del dispositivo di un oggetto dispositivo creato dal driver. Il blocco della coda e dello spin esecutivo può invece trovarsi in un'estensione del controller (se il driver usa un oggetto controller) o in un pool non in pagine allocato dal driver.

Mentre il driver accetta le richieste di I/O, può inserire un IRP nella coda chiamando una delle routine di supporto seguenti se ListHead è di tipo LIST_ENTRY, come illustrato nella figura precedente:

ExInterlockedInsertTailList per posizionare L'IRP alla fine della coda

ExInterlockedInsertHeadList per posizionare l'IRP all'inizio della coda. I driver in genere chiamano questa routine solo quando devono ripetere una richiesta specifica.

Il driver deve passare puntatori ai puntatori ARP (ListEntry), nonché i puntatori ListHead e blocco di rotazione esecutivo (Lock) inizializzati in precedenza, a ognuna di queste routine ExInterlockedInsertXxxList . Solo i puntatori a ListHead e Lock sono necessari quando il driver rimuove dalla coda un IRP chiamando ExInterlockedRemoveHeadList. Per evitare deadlock, il driver non deve contenere un ExecutiveSpinLock che passa a qualsiasi routine ExInterlocked Xxx.

Poiché una coda interlocked è protetta dal blocco spin esecutivo, il driver può inserire irP nella coda collegata doubly e rimuoverli in modo sicuro da qualsiasi routine del driver in esecuzione con minore o uguale a IRQL = DISPATCH_LEVEL.

Una coda con un oggetto ListHead di tipo LIST_ENTRY, come illustrato nella figura precedente, è un elenco collegato doubly. Uno con un listHead di tipo SLIST_HEADER è un elenco sequenziato collegato. Un driver inizializza l'oggetto ListHead per una coda interlock collegata in sequenza chiamando ExInitializeSListHead.

Un driver che non ritenta mai le operazioni di I/O può usare ExInterlockedPushEntrySList ed ExInterlockedPopEntrySList per gestire l'accodamento dei runtime di integrazione internamente in una coda sequenziata collegata in sequenza. Qualsiasi driver che usa questo tipo di coda interlocked deve anche fornire spazio di archiviazione residente per un oggetto ListHead di tipo SLIST_HEADER e per executiveSpinLock, come illustrato nella figura precedente. Deve inizializzare il blocco di selezione e impostarne la coda prima di chiamare ExInterlockedPushEntrySList per inserire la voce iniziale nella relativa coda.

Per altre informazioni, vedere Gestione delle priorità hardware e dei blocchi di selezione. Per i requisiti IRQL per una routine di supporto specifica, vedere la pagina di riferimento della routine.