Good Morning AskPerf! We’re continuing on with our mini-series on Synchronization Mechanisms today with a look at Mutexes. A mutex is a synchronization object. Mutexes ensure mutually exclusive (hence the term) access. In other words, while one thread has the mutex, all other threads are prevented from using it. Essentially any lock that grants mutually exclusive access is a mutex. There are different types of mutexes – and determining which one will be used is based on a number of factors, including:
- At what IRQL can the mutex be acquired and released?
- Does acquiring the mutex raise the current IRQL?
- Must the mutex be released on the same thread that acquired it?
- Can the mutex be acquired by a thread more than once without releasing it (i.e. recursively)?
- What happens to a mutex if the thread that is holding it is terminated?
As with our last two posts, we’re not going to delve too deeply into programming concepts. However, here are the different types of Windows mutex as listed on MSDN:
|Type of Mutex||IRQL Considerations||Recursion / Thread Details|
|Interrupt spin lock||Acquisition raises IRQL to DIRQ and returns previous IRQL to caller||Not recursive / Release on same thread as acquire|
|Spin lock||Acquisition raises IRQL to DISPATCH_LEVEL and returns previous IRQL to caller||Not recursive / Release on same thread as acquire|
|Queued spin lock||Acquisition raises IRQL to DISPATCH_LEVEL and stores previous IRQL in lock owner handle||Not recursive / Release on same thread as acquire|
|Fast mutex||Acquisition raises IRQL to APC_LEVEL and stores previous IRQL in lock||Not recursive / Release on same thread as acquire|
|Kernel mutex||Enters critical region upon acquisition and leaves critical region upon release||Recursive / Release on same thread as acquire|
|Synchronization event (kernel dispatcher object)||Acquisition does not change IRQL. Wait at IRQL <= APC_LEVEL and signal at IRQL <= DISPATCH_LEVEL||Not recursive / Release on the same thread or on a different thread|
|Unsafe fast mutex||Acquisition does not change IRQL. Acquire and release at IRQL < = APC_LEVEL||Not recursive / Release on same thread as acquire|
OK, let’s switch gears slightly and discuss the three types of spin lock mentioned above. A spin lock is exactly what it sounds like. When a thread owns a spin lock, all the other threads waiting to acquire the lock “spin” until the lock is available. The threads don’t block – so they aren’t suspended or paged out – they retain control of the CPU. That prevents execution of other code at a same (or lower) IRQL. For more on IRQL, see our earlier post. Spin locks are allocated from nonpaged memory or nonpaged pool that is allocated by the caller.
As indicated above, there are three different types of spin lock:
- Interrupt spin lock: An interrupt spin lock protects shared data at DIRQL (Device Interrupt Request Level). The interrupt spin lock protects data accessed by device driver routines. Some types of devices can generate multiple interrupts at different levels. When this occurs, the driver creates a spin lock to protect shared data at the highest DIRQL at which the interrupt may arrive.
- Spin lock: A spin lock (or ordinary spin lock) works at DISPATCH_LEVEL. A driver creates an ordinary spin lock by allocating a structure in nonpaged memory. Code that runs at IRQL < DISPATCH_LEVEL acquires and releases the lock by calling two routines (KeAcquireSpinLock and KeReleaseSpinLock). These routines raise the IRQL prior to acquiring the lock and lower the IRQL when the lock is released.
- Queued spin lock: A queued spin lock is a variation on the ordinary spin lock. This variation is more efficient than ordinary spin locks. When multiple threads request the same queued spin lock, the waiting threads are queued up in the order of the request. Queued spin locks also test and set a variable local to the current CPU, so they generate less bus traffic.
OK, that’s all for this post. The resources below provide some additional information on mutexes and spin locks. In our next post, we’ll talk about Semaphore Objects. Until next time …
|Share this post :|