No Guarded Mutex in Win8?
As the MSDN article “Fast Mutexes and Guarded Mutexes” says,
Starting with Windows 8, guarded mutexes and fast mutexes are implemented identically. |
If you check WDK8 header file wdm.h, KGUARDED_MUTEX equals to FAST_MUTEX:
typedef struct _FAST_MUTEX { volatile LONG Count; PVOID Owner; ULONG Contention; KEVENT Event; ULONG OldIrql; } FAST_MUTEX, *PFAST_MUTEX, KGUARDED_MUTEX, *PKGUARDED_MUTEX; |
In WDK7.1 wdm.h, KGUARDED_MUTEX is defined as below:
typedef struct _KGUARDED_MUTEX { volatile LONG Count; PKTHREAD Owner; ULONG Contention; KGATE Gate; union { struct { SHORT KernelApcDisable; SHORT SpecialApcDisable; }; ULONG CombinedApcDisable; }; } KGUARDED_MUTEX, *PKGUARDED_MUTEX; |
Before Win8, People use guarded mutex, because comparing to fast mutex, guarded mutex is faster, more importantly, it will not raise IRQL to APC_LEVEL, which means the protected code can stay at PASSIVE_LEVEL in synchronization. A code path that is protected by fast mutex runs at IRQL = APC_LEVEL.
The problem is ‘OLD‘ Win7 KGUARDED_MUTEX was implemented based on guarded region, which disables all APCs (Normal Kernel APC and Special Kernel APC). This identical to raise current IRQL to APC_LEVEL. As such, any APIs that are illegal at APC_LEVEL are also illegal in protection of guarded mutex. Win8 made the conscious choice to unify the code implementation for fast mutex and guarded mutex. They are identical.
Here’s a blog calling out the fact that calling passive level APIs in guarded regions is bad: