Information Technology Reference
In-Depth Information
classLock{
private:
SpinLockspinlock;
intvalue=FREE;
Queuewaiting;
public:
voidLock::Acquire(){
spinlock.acquire();
if(value!=FREE){
disableInterrupts();
//MustfinishwhatIstart
readyList->removeSelf(myTCB);
waiting.add(myTCB);
spinlock.release();
suspend(); //Likeyield(),butcurrent thread'sTCB
//isonwaitinglistorreadylist
enableInterrupts();
}
else{
value=BUSY;
spinlock.release();
}
}
voidLock::Release(){
spinlock.Acquire()
if(waiting.notEmtpy()){
otherTCB=waiting.removeOne();
readyList->add(otherTCB); //Readylistprotectedby
//itsownspinlock
}
else{
value=FREE;
}
spinlock.Release();
}
}
Figure5.12: Pseudo-code for a queuing lock that suspends threads that try
to acquire the lock when it isBusy.
loop until some other lock makes itFree. This approach will be inecient if
locks are held during long operations on shared data, but if locks are known
to only be held for short periods (i.e., less time than a context switch would
take), spinlocks make sense. So, spinlocks are frequently used in multiprocessor
kernels for shared objects whose methods all run fast.
Multiprocessor queuing locks
Often we need to support ciritical sections of variying length. For example, we
may want a general solution to locks that does not make assumptions about the
running time of methods that hold locks.
We cannot completely eliminate busy-waiting, but we can minimize it using
the same approach as we did for uniprocessor locks based on disabling interrupts.
Figure 5.12 shows an implementation of locks that uses a spinlock to guard
 
Search WWH ::




Custom Search