Compartir a través de


Ejemplos de sincronización

En los ejemplos siguientes se muestra lo que un minidriver debe hacer con respecto a la sincronización e incluye ejemplos de cuándo no se debe usar la sincronización:

  • Ejemplo uno: Minidriver con un ISR en funcionamiento

    Si la sincronización de clases de secuencia está activada, se llama a todos los puntos de entrada de minidriver en IRQL elevado, mediante KeSynchronizeExecution, lo que significa que el nivel IRQ del adaptador y todos los niveles irQ inferiores se enmascaran cuando el minidriver ejecuta su código. Por lo tanto, es imperativo que el minidriver solo realice una pequeña cantidad de trabajo en este modo.

    El minidriver no debe ejecutar código que normalmente tarda más de 10 a 20 microsegundos en IRQL elevado. Si usa la compilación de depuración de stream.sys, la clase de flujo registra la cantidad de tiempo invertido en IRQL elevado y afirma si el controlador está gastando demasiado tiempo allí. Si el minidriver simplemente necesita programar registros DMA de hardware para una solicitud, o simplemente necesita leer puertos en su ISR, normalmente es aceptable realizar todo su procesamiento en IRQL elevado.

    Si el minidriver necesita realizar el procesamiento que toma más de unos pocos microsegundos, como un minidriver que transfiere datos a través de PIO, el minidriver debe usar StreamClassCallAtNewPriority para programar una devolución de llamada DISPATCH_LEVEL. En la devolución de llamada, el minidriver puede tardar entre 1/2 y 1 milisegundo en realizar su procesamiento. Una cosa que hay que recordar cuando está en este modo es que la devolución de llamada DISPATCH_LEVEL no está sincronizada con el ISR.

    Esta falta de sincronización no es un problema si el hardware permanece estable cuando el minidriver accede a los recursos (por ejemplo, puertos o una cola) durante la devolución de llamada, así como en el ISR. Pero si la inestabilidad podría ser un problema, el minidriver debe usar StreamClassCallAtNewPriority para programar una devolución de llamada de alta prioridad donde la devolución de llamada DISPATCH_LEVEL toca los recursos que se comparten con los recursos usados por el ISR.

    Tenga en cuenta que una devolución de llamada de alta prioridad equivale a llamar a KeSynchronizeExecution. KeSynchronizeExecution requiere que el minidriver haga referencia a varios parámetros que StreamClassCallAtNewPriority no, pero en general los dos dan como resultado el mismo comportamiento.

    Si el minidriver solo necesita ocasionalmente ejecutar código que tarda más de 1/2 a 1 milisegundo, o ocasionalmente necesita llamar a servicios en PASSIVE_LEVEL (por ejemplo, en el momento de la inicialización), se puede usar el establecimiento de StreamClassCallAtNewPriority en PRIORIDAD BAJA para adquirir un subproceso de trabajo de PASSIVE_LEVEL. Tenga en cuenta que una devolución de llamada de prioridad baja no está sincronizada con nada y que el minidriver podría recibir nuevas solicitudes (suponiendo que el parámetro ReadyForNextRequest NotificationType está pendiente) o una llamada ISR al ejecutar una devolución de llamada de prioridad baja.

  • Ejemplo dos: Minidriver sin un ISR

    Si la sincronización de clases de secuencia está activada, se llama a los puntos de entrada del minidriver en DISPATCH_LEVEL. El minidriver puede realizar el procesamiento de hasta 1/2 a 1 milisegundos de duración sin necesidad de ajustar la prioridad. Si el minidriver solo necesita ocasionalmente ejecutar código que tarda más de 1/2 milisegundos, o ocasionalmente necesita llamar a los servicios en PASSIVE_LEVEL (por ejemplo, en el momento de la inicialización), se puede usar StreamClassCallAtNewPriority con prioridad LOW para adquirir un subproceso de trabajo de PASSIVE_LEVEL. Tenga en cuenta que una devolución de llamada de prioridad baja no está sincronizada con nada y el minidriver podría recibir nuevas solicitudes (suponiendo que el parámetro ReadyForNextRequest NotificationType está pendiente) al ejecutar una devolución de llamada de prioridad baja.

  • Cuando nose debe usar la sincronización de clases de secuencia

    A continuación se muestran ejemplos de situaciones en las que no se debe usar la sincronización de clases de flujo. Entre ellas se incluyen las siguientes:

    • Cuando los controladores con frecuencia (más del 20 % de las solicitudes que recibe el minidriver) necesitan realizar el procesamiento que tarda más de 1 milisegundos o necesitan llamar con frecuencia a servicios PASSIVE_LEVEL, como los servicios de Microsoft DirectDraw. Al usar la versión de depuración de stream.sys, la clase de secuencia validará ambos casos y se detendrá si se detectan con la sincronización activada.

    • Cuando el minidriver es un filtro sin hardware asociado. Este minidriver debe ejecutarse en PASSIVE_LEVEL, ya que no hay ningún hardware subyacente con el que sincronizarse y el minidriver normalmente realiza una gran cantidad de procesamiento. En este caso, es más fácil realizar su propia sincronización que desperdiciar la sobrecarga mediante la sincronización de clases de flujo. Si es necesario, use exclusiones mutuas para proteger las colas.

      Los errores en el código de sincronización a menudo pueden ser difíciles de encontrar y, en determinados entornos (como los sistemas operativos basados en NT que se ejecutan en sistemas multiprocesador), los errores pueden aparecer solo después de muchas horas de estrés. En función de la experiencia con los proveedores, estos no son los tipos de cosas que la mayoría de los proveedores tienen la capacidad o el deseo de depurar. Solo los escritores de controladores familiarizados con la escritura de controladores de dispositivos WDM totalmente asincrónicos deben intentar realizar su propia sincronización.

    • Cuando el minidriver es un controlador de tipo bus en bus (por ejemplo, un controlador periférico USB o 1394) que realmente no se preocupa por la sincronización del hardware real, sino que solo llama a las solicitudes a la siguiente capa en PASSIVE_LEVEL y recibe devoluciones de llamada normalmente en DISPATCH_LEVEL.