Compartir a través de


Siempre preferente y siempre interrumpible

El objetivo del diseño preemptible e interrumpible del sistema operativo es maximizar el rendimiento del sistema. Cualquier subproceso puede ser reemplazado por un subproceso con una prioridad más alta y cualquier rutina de servicio de interrupción (ISR) de cualquier controlador se puede interrumpir mediante una rutina que se ejecuta en un nivel de solicitud de interrupción superior (IRQL).

El componente de kernel determina cuándo se ejecuta una secuencia de código, según uno de estos criterios de priorización:

  • Esquema de prioridad de tiempo de ejecución definido por el kernel para subprocesos.

    Cada subproceso del sistema tiene un atributo de prioridad asociado. En general, la mayoría de los subprocesos tienen atributos de prioridad variable : siempre son preemptibles y están programados para ejecutar round robin con todos los demás subprocesos que están actualmente en el mismo nivel de prioridad. Algunos subprocesos tienen atributos de prioridad en tiempo real: estos subprocesos críticos en tiempo se ejecutan hasta finalizar, a menos que sean interrumpidos por un subproceso con un atributo de prioridad en tiempo real mayor. La arquitectura de Microsoft Windows no proporciona un sistema en tiempo real inherentemente.

    Sea cual sea su atributo de prioridad, cualquier subproceso del sistema puede ser interrumpido cuando se produzcan interrupciones de hardware y determinados tipos de interrupciones de software.

  • Nivel de solicitud de interrupción definido por el kernel (IRQL) al que se asigna un vector de interrupción determinado en una plataforma determinada.

    El kernel prioriza las interrupciones de hardware y software para que algunos códigos en modo kernel, incluidos la mayoría de los controladores, se ejecuten en IRQLs más altos, lo que hace que tengan una prioridad de programación más alta que otros hilos del sistema. El IRQL determinado en el que se ejecuta un fragmento de código de controlador en modo kernel viene determinado por la prioridad de hardware de su dispositivo subyacente.

    El código en modo kernel siempre es interrumpible: una interrupción con un valor IRQL mayor puede producirse en cualquier momento, lo que provoca otra parte del código en modo kernel que tiene un IRQL asignado por el sistema superior que se ejecutará inmediatamente en ese procesador. Sin embargo, cuando un fragmento de código se ejecuta en un IRQL determinado, el kernel enmascara todos los vectores de interrupción con un valor IRQL menor o igual en el procesador.

El nivel IRQL más bajo se denomina PASSIVE_LEVEL. En este nivel, no se enmascara ningún vector de interrupción. Por lo general, los subprocesos se ejecutan en IRQL=PASSIVE_LEVEL. Los siguientes niveles irQL superiores son para interrupciones de software. Estos niveles incluyen APC_LEVEL, DISPATCH_LEVEL o, para la depuración del kernel, WAKE_LEVEL. Las interrupciones del dispositivo aún tienen valores IRQL más altos. El kernel reserva los valores IRQL más altos para las interrupciones críticas del sistema, como las del reloj del sistema o los errores de bus.

Algunas rutinas de soporte del sistema se ejecutan en IRQL=PASSIVE_LEVEL, ya sea porque se implementan como código paginable o acceden a datos paginables, o porque algunos componentes en modo kernel configuran sus propios subprocesos.

Del mismo modo, algunas rutinas de controlador estándar normalmente se ejecutan en IRQL=PASSIVE_LEVEL. Sin embargo, varias rutinas de controlador estándar se ejecutan en IRQL=DISPATCH_LEVEL o, para un controlador de nivel inferior, en IRQL del dispositivo (también denominado DIRQL). Para obtener más información sobre las IRQL, consulte Administración de prioridades de hardware.

Todas las rutinas de un controlador son interrumpibles. Esto incluye cualquier rutina que se ejecute en un IRQL mayor que PASSIVE_LEVEL. Cualquier rutina que se ejecuta en un IRQL determinado conserva el control del procesador solo si no se produce ninguna interrupción para un IRQL superior mientras se ejecuta esa rutina.

A diferencia de los controladores de algunos sistemas operativos de equipos personales más antiguos, un ISR del controlador de Microsoft Windows nunca es una rutina grande y compleja que realiza la mayoría del procesamiento de E/S del controlador. Esto se debe a que la rutina de servicio de interrupción (ISR) de cualquier controlador se puede interrumpir mediante otra rutina (por ejemplo, mediante el ISR de otro controlador) que se ejecuta en un IRQL superior. Por lo tanto, el ISR del driver no conserva necesariamente el control de una CPU, sin interrupciones, desde el principio de su ruta de acceso de ejecución hasta el final.

En los controladores de Windows, un ISR normalmente guarda información de estado de hardware, pone en cola una llamada a procedimiento diferido (DPC), y después sale rápidamente. Más adelante, el sistema desencola el DPC del controlador para que el controlador pueda completar las operaciones de E/S a un nivel IRQL más bajo (DISPATCH_LEVEL). Para un buen rendimiento general del sistema, todas las rutinas que se ejecutan en IRQLs altos deben ceder rápidamente el control de la CPU.

En Windows, todos los hilos tienen un contexto de hilo. Este contexto consta de información que identifica el proceso que posee el subproceso, además de otras características, como los derechos de acceso del subproceso.

En general, solo se llama a un controlador de nivel superior en el contexto del subproceso que solicita la operación de E/S actual del controlador. Un controlador de nivel intermedio o de nivel inferior nunca puede suponer que se está ejecutando en el contexto del subproceso que solicitó su operación de E/S actual.

Por lo tanto, las rutinas del controlador normalmente se ejecutan en un contexto arbitrario de subproceso, el contexto de cualquier subproceso actual cuando se llama a una rutina de controlador estándar. Por motivos de rendimiento (para evitar conmutadores de contexto), muy pocos controladores configuran sus propios subprocesos.