Exclusiones mutuas rápidas y exclusiones mutuas protegidas

A partir de Windows 2000, los controladores pueden usar exclusiones mutuas rápidas si requieren una forma de exclusión mutua de baja sobrecarga para el código que se ejecuta en IRQL <= APC_LEVEL. Una exclusión mutua rápida puede proteger una ruta de acceso de código que solo debe especificar un subproceso cada vez. Para escribir la ruta de acceso de código protegida, el subproceso adquiere la exclusión mutua. Si otro subproceso ya ha adquirido la exclusión mutua, la ejecución del subproceso actual se suspende hasta que se libere la exclusión mutua. Para salir de la ruta de acceso de código protegida, el subproceso libera la exclusión mutua.

A partir de Windows Server 2003, los controladores también pueden usar exclusiones mutuas protegidas. Las exclusiones mutuas protegidas son reemplazos desplegables para exclusiones mutuas rápidas, pero proporcionan un mejor rendimiento. Al igual que una exclusión mutua rápida, una exclusión mutua protegida puede proteger una ruta de acceso de código que solo debe especificar un subproceso cada vez. Sin embargo, el código que usa exclusiones mutuas protegidas se ejecuta más rápidamente que el código que usa exclusiones mutuas rápidas.

En las versiones de Windows anteriores a Windows 8, las exclusiones mutuas protegidas se implementan de forma diferente a las exclusiones mutuas rápidas. Una ruta de acceso de código protegida por una exclusión mutua rápida se ejecuta en IRQL = APC_LEVEL. Una ruta de acceso de código protegida por una exclusión mutua protegida se ejecuta en IRQL <= APC_LEVEL pero con todas las API deshabilitadas. En estas versiones anteriores de Windows, la adquisición de una exclusión mutua protegida es una operación más rápida que la adquisición de una exclusión mutua rápida. Sin embargo, estos dos tipos de exclusión mutua se comportan de forma idéntica y están sujetos a las mismas restricciones. En concreto, las rutinas de kernel que no son válidas para llamar a en IRQL = APC_LEVEL no deben llamarse desde una ruta de acceso de código protegida por una exclusión mutua rápida o una exclusión mutua protegida.

A partir de Windows 8, las exclusiones mutuas protegidas se implementan como exclusiones mutuas rápidas. En una ruta de acceso de código protegida por una exclusión mutua protegida o una exclusión mutua rápida, el Comprobador de controladores trata las llamadas a rutinas de kernel como ocurre en IRQL = APC_LEVEL. Como en versiones anteriores de Windows, las llamadas que no son válidas en APC_LEVEL son ilegales en una ruta de acceso de código que está protegida por una exclusión mutua protegida o una exclusión mutua rápida.

Exclusiones mutuas rápidas

Una exclusión mutua rápida se representa mediante una estructura FAST_MUTEX . El controlador asigna su propio almacenamiento para una estructura de FAST_MUTEX y, a continuación, llama a la rutina ExInitializeFastMutex para inicializar la estructura.

Un subproceso adquiere una exclusión mutua rápida realizando una de las siguientes acciones:

  • Llamar a la rutina ExAcquireFastMutex . Si otro subproceso ya ha adquirido la exclusión mutua, la ejecución del subproceso que realiza la llamada se suspende hasta que la exclusión mutua esté disponible.

  • Llamar a la rutina ExTryToAcquireFastMutex para intentar adquirir la exclusión mutua rápida sin suspender el subproceso actual. La rutina devuelve inmediatamente, independientemente de si se ha adquirido la exclusión mutua. ExTryToAcquireFastMutex devuelve TRUE si adquirió correctamente la exclusión mutua del autor de la llamada; de lo contrario, devuelve FALSE.

Un subproceso llama a ExReleaseFastMutex para liberar una exclusión mutua rápida adquirida por ExAcquireFastMutex o ExTryToAcquireFastMutex.

Una ruta de acceso de código protegida por una exclusión mutua rápida se ejecuta en IRQL = APC_LEVEL. ExAcquireFastMutex y ExTryToAcquireFastMutex generan el IRQL actual para APC_LEVEL y ExReleaseFastMutex restaura el IRQL original. Por lo tanto, todas las API están deshabilitadas mientras el subproceso contiene una exclusión mutua rápida.

Si se garantiza que una ruta de acceso de código siempre se ejecute en APC_LEVEL, el controlador puede llamar a ExAcquireFastMutexUnsafe y ExReleaseFastMutexUnsafe para adquirir y liberar una exclusión mutua rápida. Estas rutinas no cambian el IRQL actual y solo se pueden usar de forma segura cuando el IRQL actual está APC_LEVEL.

Las exclusiones mutuas rápidas no se pueden adquirir de forma recursiva. Si un subproceso que ya contiene una exclusión mutua rápida intenta adquirirlo, ese subproceso se interbloqueará. Las exclusiones mutuas rápidas solo se pueden usar en el código que se ejecuta en IRQL <= APC_LEVEL.

Exclusiones mutuas protegidas

Las exclusiones mutuas protegidas, que están disponibles a partir de Windows Server 2003, realizan la misma función que las exclusiones mutuas rápidas, pero con un mayor rendimiento.

A partir de Windows 8, las exclusiones mutuas protegidas y las exclusiones mutuas rápidas se implementan de forma idéntica.

En las versiones de Windows anteriores a Windows 8, las exclusiones mutuas protegidas se implementan de forma diferente a las exclusiones mutuas rápidas. La adquisición de una exclusión mutua rápida eleva el IRQL actual a APC_LEVEL, mientras que la adquisición de una exclusión mutua protegida entra en una región protegida, que es una operación más rápida. Para obtener más información sobre las regiones protegidas, consulte Regiones críticas y Regiones protegidas.

Una exclusión mutua protegida se representa mediante una estructura de KGUARDED_MUTEX . El controlador asigna su propio almacenamiento para una estructura de KGUARDED_MUTEX y, a continuación, llama a la rutina KeInitializeGuardedMutex para inicializar la estructura.

Un subproceso adquiere una exclusión mutua protegida realizando una de las siguientes acciones:

  • Llamar a KeAcquireGuardedMutex. Si otro subproceso ya ha adquirido la exclusión mutua, la ejecución del subproceso que realiza la llamada se suspende hasta que la exclusión mutua esté disponible.

  • Llamar a KeTryToAcquireGuardedMutex para intentar adquirir la exclusión mutua protegida sin suspender el subproceso actual. La rutina devuelve inmediatamente, independientemente de si se ha adquirido la exclusión mutua. KeTryToAcquireGuardedMutex devuelve TRUE si adquirió correctamente la exclusión mutua para el autor de la llamada; de lo contrario, devuelve FALSE.

Un subproceso llama a KeReleaseGuardedMutex para liberar una exclusión mutua protegida adquirida por KeAcquireGuardedMutex o KeTryToAcquireGuardedMutex.

Un subproceso que contiene una exclusión mutua protegida se ejecuta implícitamente dentro de una región protegida. KeAcquireGuardedMutex y KeTryToAcquireGuardedMutex entran en la región protegida, mientras que KeReleaseGuardedMutex lo cierra. Todas las API están deshabilitadas mientras el subproceso contiene una exclusión mutua protegida.

Si se garantiza que una ruta de acceso de código se ejecute con todas las API deshabilitadas, el controlador puede usar KeAcquireGuardedMutexUnsafe y KeReleaseGuardedMutexUnsafe para adquirir y liberar la exclusión mutua protegida. Estas rutinas no entran ni salen de una región protegida y solo se pueden usar dentro de una región protegida ya existente o en IRQL = APC_LEVEL.

Las exclusiones mutuas protegidas no se pueden adquirir de forma recursiva. Si un subproceso que ya contiene una exclusión mutua protegida intenta adquirirla, ese subproceso interbloqueo. Las exclusiones mutuas protegidas solo se pueden usar en el código que se ejecuta en IRQL <= APC_LEVEL.