The next blog post of my exploration of kernel-mode synchronization mechanisms (I’m not going to bother with user-mode mechanisms), in this blog post, I’m going to talk about the Mutex object. Mutexes are a object which provide a form of mutual exclusion, they are very similar to Semaphores.
Mutexes only allow one thread which holds the mutex object, access to a certain protected resource.
|Source – Basics of Mutexes and Spinlocks|
Fast Mutexes (or Executive Mutexes) are built a dispatcher object called a Event object, a Event object can be within two states: Signaled or Non-Signaled, this thereby applies to a Fast Mutex. A Mutex comes Signaled, when it is not owned by a thread, and therefore can be a acquired. A Mutex is said to be Non-Signaled, when the object is owned by a thread, when the object is released, the Mutex object changes to Signaled, and the thread is released.
Fast Mutexes disable normal Kernel-Mode APCs when raising the IRQL Level of the processor to IRQL Level 1 or APC_LEVEL. Fast Mutexes can’t be acquired recursively, that is to say, the same thread can acquire the same Mutex multiple times, but the thread must release the Mutex the same number of times it acquired it, otherwise the system will run into a deadlock.
A reetrant mutex is recursive.
Guarded Mutexes are similar to Fast Mutexes, but use a different kind of dispatcher object, this object is called a Gate object. Any thread which holds a Guarded Mutex, runs inside a Guarded Region, which in turn disables all APC activity (Special and Normal).
When a Gate object, is set to Signaled, when the thread signals the gate; one waiting thread is then released.
More Information – Fast Mutexes and Guarded Mutexes
Unlike, Mutex objects which generally only allow one thread to have access to a resource, Semaphores can allow multiple threads at the same time to have access to that resource. A semaphore keeps a count of how many threads are accessing that resource, and how many threads are allowed to have access to a that resource.
The Semaphore can be thought of, as a gate, in that it controls the number of threads to a resource. A Semaphore can be Signaled or Non-Signaled, when Signaled the thread releases it’s access to the resource and the Semaphore count is incremented, meaning that a Semaphore object has become free to use and allow access to the protected resource.
When the Semaphore is obtained by another thread, the state changes from Signaled to Non-Signaled, and the Semaphore count is decremented. Once the count has become zero, no more threads are able to wait for the thread to become signaled.
More Information – Semaphore Objects
Deadlocks: One thread obtains a resource , and then another thread obtains a resource, although they are both waiting to acquire each others resources. One thread can continue and leave it’s wait state, until it’s obtained the other resource which is being held by the other thread.
Priority Inversion: A thread with a higher-priority is waiting for a lower-priority thread; this breaks the mechanism of thread priorities.
Resource Starvation: A process is never given the resources it requires to complete any tasks assigned to it, leading to the process freezing.