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