Are some implementations better than others for specific applications? Is there anything to earn by rolling out your own?
Locks have two operations: acquire allows a thread to take ownership of a lock. If a thread tries to acquire a lock currently owned by another thread, it blocks until the other thread releases the lock. At that point, it will contend with any other threads that are trying to acquire the lock.
Mutex lock will only be released by the thread who locked it. So this ensures that once a thread has locked a piece of code then no other thread can execute the same region until it is unlocked by the thread who locked it.
The idea behind mutexes is to only allow one thread access to a section of memory at any one time. If one thread locks the mutex, any other lock attempts will block until the first one unlocks.
Check out the description of the Test-and-set machine instruction on Wikipedia, which alludes to how atomic operations are achieved at the machine level. I can imagine most language-level mutex implementations rely on machine-level support such as Test-and-set.
Building on Adamski's test-and-set
suggestion, you should also look at the concept of "fast user-space mutexes" or futexes.
Futexes have the desirable property that they do not require a kernel system call in the common cases of locking or unlocking an uncontended mutex. In these cases, the user-mode code successfully uses an atomic compare and swap (CAS) operation to lock or unlock the mutex.
If CAS fails, the mutex is contended and a kernel system call -- sys_futex
under Linux -- must be used either to wait for the mutex (in the lock case) or to wake other threads (in the unlock case).
If you're serious about implementing this yourself, make sure you also read Ulrich Drepper's paper.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With