Condividi tramite


Uso di oggetti timer

La figura seguente illustra l'uso di un timer di notifica per configurare un intervallo di timeout per un'operazione e quindi attendere mentre altre routine driver elaborano una richiesta di I/O.

diagramma che illustra l'attesa di un oggetto timer.

Come illustrato nella figura precedente, un driver deve fornire l'archiviazione per l'oggetto timer, che deve essere inizializzato da una chiamata a KeInitializeTimer con un puntatore a questa risorsa di archiviazione. Un driver esegue in genere questa chiamata dalla routine AddDevice .

Nel contesto di un determinato thread, ad esempio un thread creato dal driver o un thread che richiede un'operazione di I/O sincrona, il driver può attendere il relativo oggetto timer, come illustrato nella figura precedente:

  1. Il thread chiama KeSetTimer con un puntatore all'oggetto timer e un determinato valore DueTime , espresso in unità di 100 nanosecondi. Un valore positivo per DueTime specifica un'ora assoluta in cui l'oggetto timer deve essere rimosso dalla coda timer del kernel e impostato sullo stato Signaled. Un valore negativo per DueTime specifica un intervallo relativo all'ora di sistema corrente.

    Si noti che il thread (o la routine driver in esecuzione in un thread di sistema) passa un puntatore NULL per l'oggetto DPC (illustrato in precedenza nella figura che illustra l'uso di oggetti timer e DPC per una routine CustomTimerDpc) quando chiama KeSetTimer se attende l'oggetto timer anziché accodare una routine CustomTimerDpc .

  2. Il thread chiama KeWaitForSingleObject con un puntatore all'oggetto timer, che inserisce il thread in uno stato di attesa mentre l'oggetto timer si trova nella coda timer del kernel.

  3. L'oggetto DueTime specificato scade.

  4. Il kernel dequeue l'oggetto timer, lo imposta sullo stato Segnalato e modifica lo stato del thread dall'attesa di pronto.

  5. Il kernel invia il thread per l'esecuzione non appena è disponibile un processore: ovvero nessun altro thread con una priorità maggiore è attualmente nello stato pronto e non sono presenti routine in modalità kernel da eseguire in un irQL superiore.

Le routine del driver eseguite in IRQL >= DISPATCH_LEVEL possono timeout delle richieste usando un oggetto timer con un oggetto DPC associato per accodare una routine CustomTimerDpc fornita dal driver. Solo le routine driver eseguite all'interno di un contesto di thread non arbiverso possono attendere un intervallo diverso da zero su un oggetto timer, come illustrato nella figura precedente.

Come ogni altro thread, un thread creato dal driver è rappresentato da un oggetto thread kernel, che è anche un oggetto dispatcher. Di conseguenza, un driver non deve avere il thread creato dal driver usa un oggetto timer per inserire volontariamente in uno stato di attesa per un determinato intervallo. Il thread può invece chiamare KeDelayExecutionThread con un intervallo fornito dal chiamante. Per altre informazioni su questa tecnica, vedere Polling di un dispositivo.

DriverEntry, Reinitialize e Scarica routine vengono eseguite anche in un contesto di thread di sistema, in modo che i driver possano chiamare KeWaitForSingleObject con un oggetto timer inizializzato driver o KeDelayExecutionThread durante l'inizializzazione o lo scarico. Un driver di dispositivo può chiamare KeStallExecutionProcessor per un intervallo molto breve (preferibilmente qualcosa di meno di 50 microsecondi) se deve attendere che il dispositivo aggiorni lo stato durante l'inizializzazione.

Tuttavia, i driver di livello superiore usano in genere un altro meccanismo di sincronizzazione nelle routine DriverEntry e Reinitialize anziché usare un oggetto timer. I driver di livello superiore devono essere sempre progettati per eseguire un livello superiore rispetto a qualsiasi driver di livello inferiore di un determinato tipo o tipo di dispositivo. Pertanto, un driver di livello superiore tende a diventare lento a caricare se attende su un oggetto timer o chiama KeDelayExecutionThread perché tale driver deve attendere un intervallo abbastanza lungo per supportare il dispositivo più lento possibile. Si noti anche che un intervallo "sicuro" ma minimo per tale attesa è molto difficile da determinare.

Analogamente, i driver PnP non devono attendere l'esecuzione di altre azioni, ma devono usare il meccanismo di notifica di PnP manager.