When the semaphore's ability to count is not needed, a simplified version of the semaphore, called a mutex, is sometimes used.
Mutexes are good only for managing mutual exclusion to some shared resource or piece of code. They are easy and efficient to implement, which makes them especially useful in thread packages that are implemented entirely in user space.
A mutex is a variable that can be in one of two states: unlocked or locked. Consequently, only 1 bit is required to represent it, but in practice an integer often is used, with 0 meaning unlocked and all other values meaning locked.
Two procedures are used with mutexes. When a thread (or process) needs access to a critical region, it calls mutex-lock. If the mutex is currently unlocked (meaning that the critical region is available), the call succeeds and the calling thread is free to enter the critical region.
On the other hand, if the mutex is already locked, the calling thread is blocked until the thread in the critical region is finished and calls mutex-unlock. If multiple threads are blocked on the mutex, one of them is chosen at random and allowed to acquire the lock.
Mutex_lock:
TSL REGISTER., MUTEX copy mutex to register and set mutex to 1
CMP REGISTER, #0 was mutex zero?
JZE ok if it was zero, mutex was unlocked, so return
CALL thread_yield mutex is busy; schedule another thread
JMP mutex_lock try again
ok: RET return to caller; critical region entered
mutex_ unlock:
MOVE MUTEX, #0 store a 0 in mutex
RET return to caller