Information Technology Reference
In-Depth Information
classCond{
private:
SpinLockspinlock;
Queuewaiting;
public:
voidCond:Wait(Lock*lock){
spinlock.Acquire();
disableInterrupts();
//MustfinishwhatIstart
readyList->removeSelf(myTCB);
waiting.add(myTCB);
lock->Release();
spinlock.Release();
suspend();
//Likeyield(),butcurrentthread'sTCB
//maybeonthewaitinglistorthereadylist
enableInterrupts();
lock->Acquire();
}
voidCond::Signal(){
disableInterrupts();
if(waiting.notEmpty()){
moveoneTCBfromwaitingtoready;
}
enableInterrupts();
}
voidCond::Broadcast(){
disableInterrupts();
while(waiting.notEmpty()){
moveallTCBsfromwaitingtoready;
}
enableInterrupts();
}
}
Figure5.13: Pseudocode for condition variable implementation via atomic
read-modify-write instructions.
Exercises
7. Wikipedia provides an implementation of Peterson's algorithm to provide
mutual exclusion using loads and stores at
http://en.wikipedia.org/
wiki/Peterson's_algorithm
.
Unfortunately, this code is not guaranteed
to work with modern compilers or hardware. Update the code to include
memory barriers where necessary. (Of course you could add a memory
barrier before and after each instruction; your solution should instead add
memory barriers only where necessary for correctness.)
8. Linux provides a
sysfutex()
system call to assist in implementing hybrid
user-level/kernel-level locks and condition variables.
A call to
longsysfutex(void*addr1,FUTEXWAIT,intval1,NULL,
NULL,0
checks to see if the memory at address
addr1
has the same value
as
val1
. If so, the calling thread is suspended. If not, the calling thread
returns immediately with the error return value
EWOULDBLOCK
. In addition,