Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A partir do Windows 2000, os drivers podem usar mutexes rápidos se exigirem uma forma de exclusão mútua de baixa sobrecarga para código executado em IRQL <= APC_LEVEL. Um mutex rápido pode proteger um caminho de código que deve ser inserido por apenas um thread de cada vez. Para inserir o caminho de código protegido, o thread adquire o mutex. Se outro thread já tiver adquirido o mutex, a execução do thread atual será suspensa até que o mutex seja liberado. Para sair do caminho de código protegido, o thread libera o mutex.
A partir do Windows Server 2003, os drivers também podem usar mutexes protegidos. Os mutexes protegidos são substitutos imediatos para mutexes rápidos, mas fornecem um melhor desempenho. Como um mutex rápido, um mutex protegido pode proteger um caminho de código que deve ser acessado por apenas um thread de cada vez. No entanto, o código que usa mutexes protegidos é executado mais rapidamente do que o código que usa mutexes rápidos.
Em versões do Windows anteriores ao Windows 8, os mutexes protegidos são implementados de forma diferente dos mutexes rápidos. Um caminho de código protegido por um mutex rápido é executado em IRQL = APC_LEVEL. Um caminho de código protegido por um mutex protegido é executado em IRQL <= APC_LEVEL mas com todos os APCs desativados. Nessas versões anteriores do Windows, a aquisição de um mutex protegido é uma operação mais rápida do que a aquisição de um mutex rápido. No entanto, estes dois tipos de mutex comportam-se de forma idêntica e estão sujeitos às mesmas restrições. Em particular, as rotinas do kernel que são ilegais para chamar IRQL = APC_LEVEL não devem ser chamadas a partir de um caminho de código protegido por um mutex rápido ou um mutex protegido.
A partir do Windows 8, mutexes protegidos são implementados como mutexes rápidos. Em um caminho de código protegido por um mutex guardado ou um mutex rápido, o Driver Verifier trata as chamadas para rotinas do kernel como ocorrendo em IRQL = APC_LEVEL. Como em versões anteriores do Windows, chamadas que são ilegais em APC_LEVEL são ilegais num caminho de código protegido por um mutex guardado ou um mutex rápido.
Mutexes rápidos
Um mutex rápido é representado por uma estrutura FAST_MUTEX . O driver aloca seu próprio armazenamento para uma estrutura FAST_MUTEX e, em seguida, chama a rotina ExInitializeFastMutex para inicializar a estrutura.
Um thread adquire um mutex rápido seguindo um destes procedimentos:
Invocando a rotina ExAcquireFastMutex . Se o mutex já tiver sido adquirido por outro thread, a execução do thread de chamada será suspensa até que o mutex fique disponível.
Chamando a rotina ExTryToAcquireFastMutex para tentar adquirir o mutex rápido sem suspender o thread atual. A rotina retorna imediatamente, independentemente de o mutex ter sido adquirido. ExTryToAcquireFastMutex retorna TRUE se adquiriu com sucesso o mutex para o chamador; caso contrário, ele retorna FALSE.
Um thread chama ExReleaseFastMutex para liberar um mutex rápido que foi adquirido pelo ExAcquireFastMutex ou ExTryToAcquireFastMutex.
Um caminho de código protegido por um mutex rápido é executado em IRQL = APC_LEVEL. ExAcquireFastMutex e ExTryToAcquireFastMutex elevam o IRQL atual para APC_LEVEL, e ExReleaseFastMutex restaura o IRQL original. Assim, todos os APCs são desativados enquanto o thread mantém um mutex rápido.
Se for garantido que um caminho de código sempre será executado em APC_LEVEL, o driver pode, em vez disso, chamar ExAcquireFastMutexUnsafe e ExReleaseFastMutexUnsafe para adquirir e liberar um mutex rápido. Essas rotinas não alteram o IRQL atual e podem ser usadas com segurança somente quando o IRQL atual estiver APC_LEVEL.
Os mutexes rápidos não podem ser adquiridos recursivamente. Se uma thread que já está mantendo um mutex rápido tentar adquiri-lo, essa thread ficará bloqueada. Os mutexes rápidos só podem ser usados em código executado em IRQL <= APC_LEVEL.
Mutexes protegidos
Os mutexes protegidos, que estão disponíveis a partir do Windows Server 2003, executam a mesma função que os mutexes rápidos, mas com desempenho superior.
A partir do Windows 8, mutexes protegidos e mutexes rápidos são implementados de forma idêntica.
Nas versões do Windows anteriores ao Windows 8, os mutexes protegidos são implementados de forma diferente dos mutexes rápidos. A aquisição de um mutex rápido eleva o IRQL atual para APC_LEVEL, enquanto a aquisição de um mutex protegido entra numa região protegida, sendo uma operação mais rápida. Para obter mais informações sobre regiões protegidas, consulte Regiões críticas e regiões protegidas.
Um mutex protegido é representado por uma estrutura KGUARDED_MUTEX. O driver aloca seu próprio armazenamento para uma estrutura KGUARDED_MUTEX e, em seguida, chama a rotina KeInitializeGuardedMutex para inicializar a estrutura.
Um thread adquire um mutex protegido seguindo um destes procedimentos:
Chamando KeAcquireGuardedMutex. Se o mutex já tiver sido adquirido por outro thread, a execução do thread de chamada será suspensa até que o mutex fique disponível.
Chamando KeTryToAcquireGuardedMutex para tentar adquirir o mutex protegido sem suspender o thread atual. A rotina retorna imediatamente, independentemente de o mutex ter sido adquirido. KeTryToAcquireGuardedMutex retorna TRUE se adquiriu com sucesso o mutex para o chamador; caso contrário, ele retorna FALSE.
Um thread chama KeReleaseGuardedMutex para liberar um mutex protegido que foi adquirido por KeAcquireGuardedMutex ou KeTryToAcquireGuardedMutex.
Um fio que segura um mutex protegido corre implicitamente dentro de uma região protegida. KeAcquireGuardedMutex e KeTryToAcquireGuardedMutex entram na região protegida, enquanto KeReleaseGuardedMutex sai dela. Todos os APCs são desativados enquanto o thread mantém um mutex protegido.
Se for garantido que um caminho de código será executado com todos os APCs desativados, o driver poderá usar KeAcquireGuardedMutexUnsafe e KeReleaseGuardedMutexUnsafe para adquirir e liberar o mutex protegido. Essas rotinas não entram ou saem de uma região vigiada e podem ser usadas apenas dentro de uma região vigiada já existente ou em IRQL = APC_LEVEL.
Os mutexes protegidos não podem ser obtidos recursivamente. Se um thread que já está segurando um mutex protegido tentar adquiri-lo, esse thread será bloqueado. Os mutexes protegidos só podem ser usados em código executado em IRQL <= APC_LEVEL.