Condividi tramite


Introduzione agli oggetti dispatcher del kernel

Il kernel definisce un set di tipi di oggetto denominati oggetti dispatcher kernel o semplicemente oggetti dispatcher. Gli oggetti Dispatcher includono oggetti timer, oggetti evento, oggetti semafori, oggetti mutex e oggetti thread.

Drivers can use dispatcher objects as synchronization mechanisms within a nonarbitrary thread context while executing at IRQL equal to PASSIVE_LEVEL.

Dispatcher Object States

Every kernel-defined dispatcher object type has a state that is either set to Signaled or set to Not-Signaled.

Un gruppo di thread può sincronizzare le operazioni se uno o più thread chiamano KeWaitForSingleObject, KeWaitForMutexObject o KeWaitForMultipleObjects. These functions take dispatcher object pointers as input and wait until another routine or thread sets one or more dispatcher objects to the Signaled state.

Quando un thread chiama KeWaitForSingleObject per attendere un oggetto dispatcher (o KeWaitForMutexObject per un mutex ), il thread viene inserito in uno stato di attesa finché l'oggetto dispatcher non viene impostato sullo stato Signaled. Un thread può chiamare KeWaitForMultipleObjects per attendere che uno qualsiasi o tutti gli oggetti di un set di dispatcher siano impostati su Signaled.

Ogni volta che un oggetto dispatcher viene impostato sullo stato Signaled, il kernel modifica lo stato di qualsiasi thread in attesa che tale oggetto sia pronto. I timer di sincronizzazione e gli eventi di sincronizzazione sono eccezioni a questa regola. Quando viene segnalato un evento di sincronizzazione o un timer, solo un thread in attesa viene impostato sullo stato pronto. Per altre informazioni, vedere Oggetti timer e controller di dominio eoggetti evento. Un thread nello stato pronto verrà pianificato per l'esecuzione in base alla priorità del thread di runtime corrente e alla disponibilità corrente dei processori per qualsiasi thread con tale priorità.

When Can Drivers Wait for Dispatcher Objects?

In generale, i driver possono attendere che gli oggetti dispatcher vengano impostati solo se almeno una delle circostanze seguenti è vera:

  • The driver is executing in a nonarbitrary thread context.

    Ovvero, è possibile identificare il thread che entrerà in uno stato di attesa. In practice, the only driver routines that execute in a nonarbitrary thread context are the DriverEntry, AddDevice, Reinitialize, and Unload routines of any driver, plus the dispatch routines of highest-level drivers. Tutte queste routine vengono chiamate direttamente dal sistema.

  • Il driver esegue una richiesta di I/O completamente sincrona.

    That is, no driver queues any operations while handling the I/O request, and no driver returns until the driver below it has finished handling the request.

Inoltre, un driver non può entrare in uno stato di attesa se è in esecuzione a un livello IRQL pari o superiore a DISPATCH_LEVEL.

In base a queste limitazioni, è necessario usare le regole seguenti:

  • Le routine DriverEntry, AddDevice, Reinitialize e Unload di qualsiasi driver possono attendere gli oggetti dispatcher.

  • The dispatch routines of a highest-level driver can wait for dispatcher objects.

  • The dispatch routines of lower-level drivers can wait for dispatch objects, if the I/O operation is synchronous, such as create, flush, shutdown, and close operations, some device I/O control operations, and some PnP and power operations.

  • The dispatch routines of lower-level drivers cannot wait for a dispatcher object for the completion of asynchronous I/O operations.

  • A driver routine that is executing at or above IRQL DISPATCH_LEVEL must not wait for a dispatcher object to be set to the Signaled state.

  • Un driver non deve tentare di attendere che un oggetto dispatcher venga impostato sullo stato Segnalato per il completamento di un'operazione di trasferimento da o verso un dispositivo di paging.

  • Driver dispatch routines servicing read/write requests generally cannot wait for a dispatcher object to be set to the Signaled state.

  • Una routine dispatch per una richiesta di controllo di I/O del dispositivo può attendere che un oggetto dispatcher venga impostato sullo stato Segnalato solo se il tipo di trasferimento per il codice di controllo I/O è METHOD_BUFFERED.

  • SCSI miniport drivers should not use kernel dispatcher objects. SCSI miniport drivers should call only SCSI Port Driver Support Routines.

Ogni altra routine del driver standard viene eseguita nel contesto di un thread arbitrario: quello di qualunque thread attivo quando la routine del driver viene chiamata per elaborare un'operazione in coda o per gestire un'interruzione del dispositivo. Moreover, most standard driver routines are run at a raised IRQL, either at DISPATCH_LEVEL, or for device drivers, at DIRQL.

Se necessario, un driver può creare un thread dedicato al dispositivo, che può attendere le altre routine del driver (ad eccezione di una routine ISR o SynchCritSection ) per impostare un oggetto dispatcher sullo stato Segnalato e reimpostare lo stato Not-Signaled.

Come linea guida generale, se si prevede che il nuovo driver di dispositivo debba spesso bloccarsi per più di 50 microsecondi mentre attende modifiche dello stato del dispositivo durante le operazioni di I/O, prendere in considerazione l'implementazione di un driver con un thread dedicato al dispositivo. If the device driver is also a highest-level driver, consider using system worker threads and implementing one or more worker-thread callback routines. See PsCreateSystemThread and Managing Interlocked Queues with a Driver-Created Thread.