At the most basic, every hardware out there has some sort of instruction or sequence of instructions that does "test and set": "As an atomic action, test if this variable has value x, and if so, set it to y. Let me know if I am successful".
So at it's heart, we have:
mutex_var = 0
pthread_mutex_lock(&mutex_var):
while True:
if successful in atomically changing mutex_var from 0 to 1:
break
pthread_mutex_unock(&mutex_var):
mutex_var = 0
Now this code has two basic problems:
- Anyone can unlock the mutex, even if they don't own it
- This is wasteful of CPU. A thread waiting for the lock is in an infinite loop: "Can I have it?" "Can I have it?" "Can I have it?"
Actual implementations do a bit more. The mutex contains more information about who currently owns the mutex, if it is locked, so that only that thread can unlock it.
So the actual code is more like:
pthread_mutex_lock():
while True:
if successful in atomically changing mutex_var from 0 to 1:
break
go to sleep waiting on this mutex
pthread_mutex_unlock():
verify that this thread owns the mutex
set mutex_var back to 0
wake up all threads waiting on this mutex