Compartir a través de


Usar una rutina CustomTimerDpc

Para deshabilitar un objeto de temporizador establecido previamente, un controlador llama a KeCancelTimer. Esta rutina quita el objeto de temporizador de la cola del temporizador del sistema. Por lo general, el objeto de temporizador no se establece en el estado señalado y la rutina CustomTimerDpc no se pone en cola para su ejecución. Sin embargo, si el temporizador está a punto de expirar cuando se llama a KeCancelTimer , la expiración puede producirse antes de que KeCancelTimer tenga la oportunidad de acceder a la cola de tiempo, en cuyo caso se producirá la señalización y la puesta en cola de DPC.

La recuperación de KeSetTimer o KeSetTimerEx, con punteros Timer y Dpc especificados anteriormente, antes de que expire el intervalo especificado anteriormente, tiene los siguientes efectos:

  • El kernel quita el objeto de temporizador de la cola del temporizador, sin establecer el objeto en el estado señalado ni poner en cola la rutina CustomTimerDpc .

  • El kernel vuelve a insertar el objeto de temporizador en la cola del temporizador, con el nuevo valor DueTime .

El uso del mismo objeto de temporizador para diferentes propósitos puede causar condiciones de carrera o errores graves del conductor. Por ejemplo, supongamos que un controlador especifica un único objeto de temporizador para configurar una llamada a una rutina CustomTimerDpc y para configurar esperas en un subproceso dedicado al controlador. Cada vez que el subproceso dedicado al controlador llama a KeSetTimer, KeSetTimerEx o KeCancelTimer para el objeto de temporizador común, el subproceso cancelaría las llamadas a la rutina CustomTimerDpc , si el objeto del temporizador ya estaba en cola para una llamada a CustomTimerDpc .

Si un controlador tiene rutinas CustomTimerDpc y también espera objetos de temporizador en un contexto de subproceso nobitrario, debe:

  • Nunca use un objeto de temporizador sensible al contexto del subproceso en un contexto de subproceso nobitrario o viceversa.

  • Asigne un objeto de temporizador independiente para cada rutina CustomTimerDpc . Cada conjunto de subprocesos de controlador o rutinas de controlador a los que se llama en un contexto de subproceso nobitrario debe tener su propio conjunto de objetos de temporizador "esperables".

Si usa una rutina CustomTimerDpc , elija cuidadosamente el intervalo en el que el controlador pasa llamadas a KeSetTimer o KeSetTimerEx. Además, considere todos los posibles efectos de una llamada a KeCancelTimer con el mismo objeto de temporizador de cualquier rutina de controlador que realice esta llamada, especialmente en plataformas SMP.

Tenga en cuenta el siguiente hecho sobre las rutinas CustomTimerDpc :

Solo se puede poner en cola una instancia de un objeto DPC que representa una rutina de DPC determinada para su ejecución en cualquier momento dado.

Si una segunda rutina de controlador llama a KeSetTimer o KeSetTimerEx para ejecutar la misma rutina CustomTimerDpc antes del intervalo especificado por el primer llamador, la rutina CustomTimerDpc solo se ejecuta después de que expire el intervalo especificado por el segundo llamador. En estas circunstancias, CustomTimerDpc no realiza ninguna de las tareas para las que la primera rutina se denomina KeSetTimer o KeSetTimerEx.

Para los controladores que tienen rutinas CustomTimerDpc y usan temporizadores periódicos:

Un controlador no puede desasignar un temporizador periódico de una rutina DPC. Los controladores solo pueden desasignar temporizadores noperiódicos de una rutina DPC.

Tenga en cuenta las siguientes directrices de diseño para los controladores que tienen rutinas CustomDpc y CustomTimerDpc :

Para evitar condiciones de carrera, nunca pase el mismo puntero Dpc a KeSetTimer o KeSetTimerEx y KeInsertQueueDpc.

En otras palabras, supongamos que la rutina StartIo de un controlador llama a KeSetTimer o KeSetTimerEx para poner en cola una rutina CustomTimerDpc y el ISR del controlador llama a KeInsertQueueDpc simultáneamente desde otro procesador con el mismo puntero Dpc . Esa rutina DPC se ejecutará cuando IRQL en un procesador esté por debajo de DISPATCH_LEVEL o el intervalo del temporizador expire, lo que ocurra primero. Lo que ocurra en primer lugar, algunos trabajos esenciales para startIo o ISR simplemente se quitarán por la rutina DPC.

Además, un DPC usado por dos rutinas de controlador estándar con una funcionalidad muy diferente tendría características de rendimiento más deficientes que las rutinas CustomTimerDpc y CustomDpc independientes. El DPC tendría que determinar qué operaciones llevar a cabo, dependiendo de las condiciones que provocaron que la rutina StartIo o isR la poneran en cola. Las pruebas de estas condiciones en DPC usarían ciclos de CPU adicionales.