Information Technology Reference
In-Depth Information
/*
*Lockamutex(possiblyinterruptible),slowpath:
*/
staticinlineint__sched
__mutex_lock_common(structmutex*lock)
{
structtask_struct*task=current;
structmutex_waiterwaiter;
unsignedlongflags;
preempt_disable();
spin_lock_mutex(&lock->wait_lock,flags);
/*addwaitingtaskstotheendofthewaitqueue(FIFO):*/
list_add_tail(&waiter.list,&lock->wait_list);
waiter.task=task;
As shown in the excerpt above, the thread first disables interrupts, grabs
the lock's waitlock guard, and adds itself to the locks's waitlist .
Next in mutexlockcommon() is the main loop:
for(;;){
/*
*Letstrytotakethelockagain-thisisneededevenif
*wegethereforthefirsttime(shortlyafterfailingto
*acquirethelock),tomakesurethatwegetawakeuponce
*it'sunlocked.Lateron,ifwesleep,thisisthe
*operationthatgivesusthelock.Wexchgitto-1,so
*thatwhenwereleasethelock,weproperlywakeupthe
*otherwaiters:
*/
if(atomic_xchg(&lock->count,-1)==1)
break;
/*didntgetthelock,gotosleep:*/
spin_unlock_mutex(&lock->wait_lock,flags);
preempt_enable_no_resched();
schedule();
preempt_disable();
spin_lock_mutex(&lock->wait_lock,flags);
}
In this loop, the thread atomically swaps the value of the lock with -1 using an
atomic read-modify-write atomicxchg instruction. If the previous state was 1
(free), the lock is now owned by the calling thread, and it breaks out of the loop.
Otherwise, the thread clears the waitlock spinlock guard, moves itself off the
ready queue, reenables interrupts ( preemptenablenoresched() ), and sus-
pends its own execution to switch the processor to another thread ( schedule() ).
Later, when the thread runs again, it returns from schedule() , disables
interrupts, and reacquires the lock's guard.
Eventually, the thread breaks out of the loop, which means that it found a
moment when the lock was in the free state (the lock's count was 1), and at
that moment it set the lock to the \busy, possible waiters" state (by setting
count=-1 .) The thread now has the lock, and it cleans up before exiting the
acquire slow path as follows:
/*gotthelock-rejoice!*/
 
Search WWH ::




Custom Search