Information Technology Reference
In-Depth Information
waitlist is empty. Finally, if count is negative, the lock is locked and there
may be threads on the waitlist .
Note that to coordinate the fast and slow paths, the implementation uses
atomic operations whenever it needs to manipulate count . Then, as long as a
lock stays in the first two states, lock() and unlock() stay on their fast paths.
Acquiring the lock. To acquire a lock, a thread calls mutexlock() , which
is defined in kernel/mutex.c :
voidmutex_lock(structmutex*lock)
{
__mutex_fastpath_lock(&lock->count,__mutex_lock_slowpath);
}
On a 32-bit x86 machine, mutexfastpathlock() is defined in arch/x86/include/asm/mutex32.h :
/**
*Changethecountfrom1toavaluelowerthan1,andcall<fn>ifit
*wasn't1originally.ThisfunctionMUSTleavethevaluelowerthan1
*evenwhenthe"1"assertionwasn'ttrue.
*/
#define__mutex_fastpath_lock(count,fail_fn)
\
do{
\
unsignedintdummy;
\
asmvolatile(LOCK_PREFIX" decl(%%eax)\n"
\
" jns1f\n"
\
" call"#fail_fn"\n"
\
"1:\n"
\
:"=a"(dummy)
\
:"a"(count)
\
:"memory","ecx","edx");
\
}while(0)
The syntax of this inline assembly is a bit baroque, but the function itself is
simple. Near the end, the notation :"a"(count) says that before running this
assembly code, the x86 eax register should be initialized to hold the parameter
count ; notice from above that count holds the address of the mutex's atomict
count field. Thus, the first x86 assembly instruction LOCKPREFIXdecl(%%eax)
is an atomic read-modify-write instruction that reads the old value of count
from memory, decrements it, and stores the new value back to memory; the
LOCKPREFIX directive tells the assembler to use a version of the decrement
instruction that executes atomically.
The second instruction jns1f (\jump if not signed") implements the fast
path. If the new value of count is zero, then this conditional jump instruc-
tion jumps to the end of the assembly code snippet (to the 1: label), and
mutexfastpathlock() returns. In this case, the lock is acquired in just two
instructions!
On the other hand, if the new value of count is negative, the jns instruction
falls through, and the call#failfn instruction calls the mutexlockslowpath()
function.
The slowpath function is implemented by mutexlockcommon() , as de-
scribed in the following excerpts from kernel/mutex.c .
 
Search WWH ::




Custom Search